Commits

jayven committed 49c40f2

support multiple consoles

  • Participants
  • Parent commits 692ec59

Comments (0)

Files changed (1)

 
 class DebugConsole(osv.osv_memory):
     
-    # global one, the only one currently
-    _debug_console = None
-
-    def _create_console(self, cr, uid):
-        l = {'uid': uid, 'dbname': cr.dbname,}
-        # cr will be closed, so create one
-        db, pool = pooler.get_db_and_pool(cr.dbname)
-        l['cr'] = db.cursor()
-        l['pool'] = pool
-        DebugConsole._debug_console = BGConsole(l, max_line=35)
-        return DebugConsole._debug_console
-
-    def _ensure_console(self, cr, uid):
-        if DebugConsole._debug_console is None:
-            self._create_console(cr, uid)
-        return DebugConsole._debug_console
-
-    def _clear_exc(self, cr, uid, id_, context):
-        rec = self.browse(cr, uid, id_, context=context)
+    def _clear_exc(self, cr, uid, id, context):
+        rec = self.browse(cr, uid, id, context=context)
         tb_ids = [tb.id for tb in rec.last_traceback]
         self.write(cr, uid, [rec.id,], {'last_type': '', 'last_value': ''},
                 context=context)
         # XXX does hotdebug.tb.locals are unlinked as well?
         self.pool.get('hotdebug.tb').unlink(cr, uid, tb_ids, context=context)
     
-    def _set_exc(self, cr, uid, id_, context):
-        console = self._ensure_console(cr, uid)
+    def _set_exc(self, cr, uid, id, context):
+        console = self.get_console(cr, uid, id, context)
         if not console.got_exception:
             return
 
         # first clear the previous exc
-        self._clear_exc(cr, uid, id_, context=context)
+        self._clear_exc(cr, uid, id, context)
 
         # should be set by InteractiveInterpreter.showtraceback at code.py
         last_type = getattr(sys, 'last_type', None)
         last_value = getattr(sys, 'last_value', None)
         last_traceback = getattr(sys, 'last_traceback', None)
         assert last_type and last_value and last_traceback
-        self.write(cr, uid, [id_,], {'last_type': str(last_type),
+        self.write(cr, uid, [id,], {'last_type': str(last_type),
             'last_value': str(last_value)}, context=context)
 
         # now add tracebacks
             line, lines = get_file_part(filename, lineno,
                     lines_around,
                     f.f_globals)
-            tb_id = tb_obj.create(cr, uid, {'console': id_,
+            tb_id = tb_obj.create(cr, uid, {'console': id,
                 'filename': filename,
                 'where': where,
                 'lineno': lineno,
             context = {}
         res = super(DebugConsole, self).default_get(cr, uid, fields,
                 context=context)
-        res['output'] = self._ensure_console(cr, uid).output
-        res['last_type'] = ''
-        res['last_value'] = ''
+        bgconsole_obj = self.pool.get('hotdebug.console.bgconsole')
+        bgconsole_id = bgconsole_obj.create(cr, uid, {}, context=context)
+        output = bgconsole_obj.get_console(cr, uid, bgconsole_id,
+                context).output
+        res['bgconsole'] = bgconsole_id
+        res['output'] = output
         return res
 
     def _cmd_get(self, cr, uid, ids, field_name, arg, context=None):
         if context is None:
             context = {}
 
-        console = self._ensure_console(cr, uid)
-        console.push_cmd(field_val)
-        if console.dead:
-            raise osv.except_osv('Info!',
-                    "The console has exited, try restart")
+        ids = norm_select(ids)
+        for id in ids:
+            console = self.get_console(cr, uid, id, context)
+            console.push_cmd(field_val)
+            if console.dead:
+                raise osv.except_osv('Info!',
+                        "The console has exited, try restart")
 
-        ids = norm_select(ids)
-        self.write(cr, uid, ids, {'output': console.output})
-        for id_ in ids:
-            self._set_exc(cr, uid, id_, context)
+            self.write(cr, uid, [id], {'output': console.output})
+            self._set_exc(cr, uid, id, context)
+
         return True
 
     def restart_console(self, cr, uid, ids, context=None):
         if context is None:
             context = {}
 
+        bgconsole_obj = self.pool.get('hotdebug.console.bgconsole')
         ids = norm_select(ids)
-        for id_ in ids:
-            self._clear_exc(cr, uid, id_, context)
-        console = self._create_console(cr, uid)
-        self.write(cr, uid, ids, {'output': console.output})
+        for rec in self.browse(cr, uid, ids, context=context):
+            # clear exception
+            self._clear_exc(cr, uid, rec.id, context)
+            # create new console and set
+            old_id = rec.bgconsole.id
+            new_id = bgconsole_obj.create(cr, uid, {}, context=context)
+            output = bgconsole_obj.get_console(cr, uid, new_id, context).output
+            self.write(cr, uid, [id], {'bgconsole': new_id, 'output': output},
+                    context=context)
+            # unlink the old one
+            bgconsole_obj.unlink(cr, uid, [old_id], context=context)
         return True
 
+    def get_console(self, cr, uid, id, context):
+        bgconsole_obj = self.pool.get('hotdebug.console.bgconsole')
+        bgconsole_id = self.browse(cr, uid, id, context=context).bgconsole.id
+        return bgconsole_obj.get_console(cr, uid, bgconsole_id, context)
 
     _name = 'hotdebug.console'
     _columns = {
+        'bgconsole': fields.many2one('hotdebug.console.bgconsole',
+            'BGConsole Object'),
         'output': fields.text('Output', readonly=True),
         'cmd': fields.function(_cmd_get, fnct_inv=_cmd_set, type='text',
             method=True,
         'help': fields.text('Help', readonly=True),
     }
     _defaults = {
+        'output': '',
+        'last_type': '',
+        'last_value': '',
         'help': help_text,
     }
 
 DebugConsole()
 
 
+class BGConsoleObj(osv.osv_memory):
+    _name = 'hotdebug.console.bgconsole'
+    _columns = {
+        'py_id': fields.integer('BGConsole Object id'),
+    }
+    # py_id->obj
+    _consoles = {}
+
+    def default_get(self, cr, uid, fields, context=None):
+        ret = super(BGConsoleObj, self).default_get(cr, uid, fields,
+                context=context)
+
+        # create the console object
+        loc = {'uid': uid, 'dbname': cr.dbname}
+        # cr will be closed, so create one
+        db, pool = pooler.get_db_and_pool(cr.dbname)
+        loc['cr'] = db.cursor()
+        loc['pool'] = pool
+        console = BGConsole(loc, max_line=35)
+
+        # store
+        ret['py_id'] = id(console)
+        self._consoles[id(console)] = console
+        return ret
+
+    # override unlink to dettach consoles
+    def unlink(self, cr, uid, ids, context=None):
+        for rec in self.browse(cr, uid, ids, context=context):
+            self._consoles.pop(rec.py_id, None)
+        return super(BGConsoleObj, self).unlink(cr, uid, ids, context=context)
+
+    def get_console(self, cr, uid, id, context):
+        rec = self.browse(cr, uid, id, context=context)
+        return self._consoles[rec.py_id]
+
+BGConsoleObj()
+
+
 class Traceback(osv.osv_memory):
 
     def _name_get(self, cr, uid, ids, field_name, arg, context=None):