Beispiel #1
0
 def test_entity_decoration(self):
     # Default label based on name.
     user = db.execute(db.User.t.create(name='foo'))
     assert label.label(user) == 'foo'
     # Custom label.
     realm = db.execute(db.Realm.t.create(name='bar'))
     avatar = db.execute(db.Avatar.t.create(
         name='baz', user=user, realm=realm))
     assert label.label(avatar) == u'baz (foo in bar)'
Beispiel #2
0
 def test_transaction_method_decoration(self):
     # Extents for entity classes that are not customized only have
     # a transaction method for the canonical Create transaction.
     t = db.Realm.t
     assert sorted(t) == ['create']
     assert label.label(t.create) == 'New'
     # Entity instances for entity classes that are not customized
     # only have transaction methods for canonical Delete and
     # Update transactions.
     realm = db.execute(t.create(name='foo'))
     t = realm.t
     L = sorted(t)
     assert L == ['clone', 'delete', 'update']
     assert label.label(t.delete) == 'Delete'
     assert label.label(t.update) == 'Edit'
     assert label.label(
         db.Realm.EntityClass.t.delete_selected) == 'Delete Selected'
     # Transaction methods that aren't labeled are automatically
     # labeled.  Test for labels of custom extent transaction
     # methods.
     t = db.Batch_Job.t
     assert 'multiple_keys_create' in list(t)
     assert label.label(t.multiple_keys_create) == 'Multiple Keys Create'
     # Test for labels of custom entity transaction methods.
     t = db.Account[1].t
     assert 'suspend' in list(t)
     assert 'transfer' in list(t)
     assert label.label(t.suspend) == 'Suspend'
     assert label.label(t.transfer) == 'Transfer Funds From This Account'
     # Test for labels of database-level transaction functions.
     t = db.t
     assert list(t) == ['subtransactions']
     assert label.label(t.subtransactions) == 'Subtransactions'
Beispiel #3
0
def get_default_tx_dialog(parent, db, tx,
                          get_value_handlers, set_field_handlers):
    extent_name = tx.s.extent_name
    if extent_name is None:
        title = u'%s' % label(tx)
        text = u'%s' % label(tx)
    else:
        extent_label = label(db.extent(extent_name))
        title = u'%s :: %s' % (label(tx), extent_label)
        text = u'%s :: %s' % (label(tx), extent_label)
    field_map = tx.s.field_map()
    fields = field_map.values()
    dialog = get_dialog(title, parent, text, db, tx, fields,
                        get_value_handlers, set_field_handlers)
    return dialog
Beispiel #4
0
 def test_database_decoration(self):
     # This label is assigned automatically.
     assert label.label(db) == u'Schevo Database'
     # It can be easily overridden.
     label.relabel(db, 'Custom Label')
     assert label.label(db) == u'Custom Label'
     # When reopening the database, the label persists.
     self.reopen()
     assert label.label(db) == u'Custom Label'
     # Cannot change the label during a transaction.
     def fn(db):
         label.relabel(db, u'Custom Label 2')
     tx = transaction.CallableWrapper(fn)
     raises(error.DatabaseExecutingTransaction,
            db.execute, tx)
Beispiel #5
0
 def _get_columns_for_field_spec(self, field_spec):
     columns = []
     if '_oid' not in self._hidden:
         column = grid.Column(self, '_oid', 'OID', data_type=int)
         columns.append(column)
     if '_rev' not in self._hidden:
         column = grid.Column(self, '_rev', 'Rev', data_type=int)
         columns.append(column)
     for field_name, FieldClass in field_spec.iteritems():
         if field_name in self._hidden:
             # Don't create a column for this field.
             continue
         if self._related and field_name == self._related.field_name:
             # Don't create a column for the related field.
             continue
         if not FieldClass.expensive and not FieldClass.hidden:
             data_type = FieldClass.data_type
             title = label(FieldClass)
             if issubclass(FieldClass, field.Entity):
                 column = EntityColumn(self, field_name, title, data_type)
             elif issubclass(FieldClass, field.Image):
                 column = grid.Column(self, field_name, title, data_type,
                                      type='pixbuf')
             else:
                 column = FieldColumn(self, field_name, title, data_type)
             columns.append(column)
     return columns
Beispiel #6
0
 def __init__(self, db, field):
     gtk.EventBox.__init__(self)
     self.set_visible_window(False)
     self.db = db
     self.field = field
     if os.name == 'nt' and not field.directory_only:
         if field.file_only:
             stock_id = gtk.STOCK_FILE
         self._hbox = hbox = gtk.HBox()
         hbox.show()
         self._entry = entry = gtk.Entry()
         entry.show()
         entry.props.editable = False
         entry.props.can_focus = False
         entry.props.has_focus = False
         self._button = button = gtk.Button()
         button.show()
         image = gtk.Image()
         image.show()
         image.set_from_stock(stock_id, gtk.ICON_SIZE_MENU)
         button.add(image)
         hbox.pack_start(entry)
         hbox.pack_start(button, expand=False)
         button.connect('clicked', self._on_clicked)
         self.add(hbox)
     else:
         title = 'Choose %r file' % label(self.field)
         self._filechooser = chooser = gtk.FileChooserButton(title)
         if self.field.directory_only:
             chooser.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
         chooser.show()
         chooser.connect('selection-changed', self._on_changed)
         self.add(chooser)
Beispiel #7
0
 def update_title(self):
     """Add or remove the database label from the end of the title."""
     separator = u' :: '
     text = self.get_title()
     # Get only the text in front of the separator.
     text = text.split(separator, 1)[0]
     if self._db:
         text = text + separator + label(self._db)
     self.set_title(text)
Beispiel #8
0
 def main(self, arg0, args):
     print
     print
     parser = _parser()
     options, args = parser.parse_args(list(args))
     if len(args) != 1:
         parser.error('Please specify URL.')
     url = args[0]
     # Open the database.
     print 'Opening database...'
     db = schevo.database.open(url)
     print
     print 'Label:', label(db)
     print 'Version:', db.version
     print 'Format:', db.format
     print
     print 'Checking for needed repairs...'
     print
     repairs = schevo.repair.repairs_needed(db, url)
     db.close()
     if len(repairs) == 0:
         print 'No repairs needed.'
         return
     print 'Repairs needed:'
     for repair in repairs:
         print '-', repair.description
         if repair.is_needed_certainty == False:
             print (
                 '    (Could not detect if needed; '
                 'assuming so for safety.)'
                 )
     print
     if not options.repair:
         print 'Use -r or --repair option to perform repairs.'
         return
     print 'Repairing database...'
     for repair in repairs:
         repair.perform()
         print 'Done:', repair.description
     print
     print 'Re-checking for needed repairs...'
     print
     db = schevo.database.open(url)
     repairs_with_certainty = [
         r for r in schevo.repair.repairs_needed(db, url)
         if r.is_needed_certainty == True
         ]
     db.close()
     if len(repairs_with_certainty) > 0:
         print 'WARNING! Repairs needed despite actions taken above:'
         for repair in repairs:
             print '-', repair.description
         print
         return 1
     else:
         print 'No repairs needed.'
Beispiel #9
0
 def main(self, arg0, args):
     print
     print
     parser = _parser()
     options, args = parser.parse_args(list(args))
     if len(args) != 1:
         parser.error("Please specify DBFILE.")
     db_filename = args[0]
     # Open the database.
     if not os.path.isfile(db_filename):
         parser.error("DBFILE must be an existing database.")
     print "Opening database..."
     db = schevo.database.open(
         filename=db_filename, backend_name=options.backend_name, backend_args=options.backend_args
     )
     print
     print "Label:", label(db)
     print "Version:", db.version
     print "Format:", db.format
     print
     print "Checking for needed repairs..."
     print
     repairs = schevo.repair.repairs_needed(db, db_filename)
     db.close()
     if len(repairs) == 0:
         print "No repairs needed."
         return
     print "Repairs needed:"
     for repair in repairs:
         print "-", repair.description
         if repair.is_needed_certainty == False:
             print ("    (Could not detect if needed; " "assuming so for safety.)")
     print
     if not options.repair:
         print "Use -r or --repair option to perform repairs."
         return
     print "Repairing database..."
     for repair in repairs:
         repair.perform()
         print "Done:", repair.description
     print
     print "Re-checking for needed repairs..."
     print
     db = schevo.database.open(db_filename)
     repairs_with_certainty = [
         r for r in schevo.repair.repairs_needed(db, db_filename) if r.is_needed_certainty == True
     ]
     db.close()
     if len(repairs_with_certainty) > 0:
         print "WARNING! Repairs needed despite actions taken above:"
         for repair in repairs:
             print "-", repair.description
         print
         return 1
     else:
         print "No repairs needed."
Beispiel #10
0
 def test_many_pluralization(self):
     assert label(db.Goauld) == u"Goa\u2032uld"
     assert plural(db.Goauld) == u"Goa\u2032ulds"
     ex = db.execute
     something = ex(db.Something.t.create())
     goauld1 = ex(db.Goauld.t.create(something=something))
     goauld2 = ex(db.Goauld.t.create(something=something))
     goaulds = something.m.goaulds()
     assert len(goaulds) == 2
     assert goauld1 in goaulds
     assert goauld2 in goaulds
Beispiel #11
0
 def test_extent_decoration(self):
     # These labels were assigned automatically.
     assert label.label(db.Avatar) == 'Avatar'
     assert label.label(db.Batch_Job) == 'Batch Job'
     assert label.label(db.Realm) == 'Realm'
     assert label.label(db.User) == 'User'
     assert label.label(db.Person) == 'Person'
     assert label.plural(db.Avatar) == 'Avatars'
     assert label.plural(db.Batch_Job) == 'Batch Jobs'
     assert label.plural(db.Realm) == 'Realms'
     assert label.plural(db.User) == 'Users'
     # These labels were assigned manually.
     assert label.plural(db.Person) == 'People'
     # The docstring for an extent is set to the docstring for the
     # entity.
     assert db.Person.__doc__ == 'Bank account owner.'
     # An extent may optionally be hidden from typical user
     # interfaces.
     assert db.AlphaAlpha.hidden
     assert not db.AlphaBravo.hidden
Beispiel #12
0
 def __init__(self, ResultClass, results):
     columns = []
     sorted = True
     for field_name, FieldClass in ResultClass._field_spec.iteritems():
         if not FieldClass.expensive:
             title = label(FieldClass)
             column = Column(field_name, title, data_type=str,
                             sorted=sorted)
             columns.append(column)
             sorted = False
     ObjectList.__init__(self, columns, results)
Beispiel #13
0
 def __init__(self, db, extent, method_name):
     gtk.VBox.__init__(self)
     self._db = db
     self._extent = extent
     method = extent.q[method_name]
     query = self._query = method()
     # Criteria form.
     expander_label = gtk.HBox()
     image_label = icon.small_image(self, db, 'q.%s' % method_name)
     text_label = gtk.Label(label(method))
     expander_label.pack_start(image_label, expand=False, padding=6)
     expander_label.pack_start(text_label, expand=False)
     image_label = icon.small_image(self, extent)
     text_label = gtk.Label(u'<b>%s</b>' % label(extent))
     text_label.props.use_markup = True
     expander_label.pack_start(image_label, expand=False, padding=6)
     expander_label.pack_start(text_label, expand=False)
     expander = gtk.Expander()
     expander.props.label_widget = expander_label
     self.pack_start(expander, expand=False)
     vbox = gtk.VBox()
     expander.add(vbox)
     criteria = self._criteria = query_widget(db, query)
     vbox.pack_start(criteria, expand=False)
     # Update button.
     box = gtk.HBox()
     vbox.pack_start(box, expand=False)
     refresh = gtk.Button(stock=gtk.STOCK_REFRESH)
     refresh.connect('clicked', self.on_refresh_clicked)
     box.pack_end(refresh, expand=False)
     # Results table.
     scroller = gtk.ScrolledWindow()
     scroller.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
     self.pack_start(scroller, expand=True)
     results = self._results = Results(db, query)
     scroller.add_with_viewport(results)
     self.show_all()
     criteria.update_ui()
     results.rerun()
Beispiel #14
0
def get_method_action(db, instance, namespace_id, method_name, related=None):
    """Return action for method name."""
    namespace = getattr(instance, namespace_id)
    method = namespace[method_name]
    method_label = label(method)
    action = Action()
    action.db = db
    action.instance = instance
    # Default label.
    action.label = u'%s...' % method_label
    if namespace_id == 't' and method_name in DEFAULT_T_METHODS:
        # Determine if there are any custom methods whose labels start
        # with the same string.
        t = action.instance.t
        other_found = False
        for other_name in t:
            if other_name not in DEFAULT_T_METHODS:
                other_label = label(t[other_name])
                if other_label.startswith(method_label):
                    other_found = True
        if other_found:
            # Custom labels, since there are custom methods that share
            # prefixes.
            if isinstance(instance, Entity):
                action.label = u'%s %s...' % (
                    method_label, label(instance.s.extent))
            elif isinstance(instance, Extent):
                action.label = u'%s %s...' % (method_label, label(instance))
            elif isinstance(instance, View):
                action.label = u'%s %s...' % (
                    method_label, label(instance.s.entity.s.extent))
    action.method = method
    action.name = method_name
    action.related = related
    if namespace_id == 'q':
        action.type = 'query'
    elif namespace_id == 't':
        action.type = 'transaction'
    return action
Beispiel #15
0
 def __unicode__(self):
     FieldClass = self.FieldClass
     field = FieldClass(self, self.field_name)
     operator = self.operator
     on = self.on
     if isinstance(on, base.Extent):
         on_label = plural(on)
     else:
         on_label = unicode(on)
     s = u'%s where %s %s' % (
         on_label,
         label(field),
         label(self.operator),
         )
     if operator is not o_any:
         value = self.value
         if isinstance(value, Query):
             s += u' %s' % value
         else:
             field.set(value)
             s += u' %s' % field
     return s
Beispiel #16
0
 def test_clone_simple(self):
     # Create a user that we will then clone.
     tx = db.User.t.create(name='User 1', age=123)
     user1 = db.execute(tx)
     # Make sure the label for the 'clone' transaction method is
     # correct.
     assert label(user1.t.clone) == 'Clone'
     # Create a 'clone' transaction based on the user.
     tx = user1.t.clone()
     # Make sure the label for the actual transaction is correct.
     assert label(tx) == 'Clone'
     # The values of the cloned transaction should match the entity
     # being cloned.
     assert tx.name == user1.name
     assert tx.age == user1.age
     # Executing the transaction without modification will result
     # in a key collision, since a user with the name 'User 1'
     # already exists.
     try:
         db.execute(tx)
     except error.KeyCollision, e:
         assert e.extent_name == 'User'
         assert e.key_spec == ('name',)
         assert e.field_values == (u'User 1',)
Beispiel #17
0
 def __init__(self, query):
     model = gtk.ListStore(gobject.TYPE_STRING)
     gtk.ComboBox.__init__(self, model)
     cell = gtk.CellRendererText()
     self.pack_start(cell, True)
     self.add_attribute(cell, 'text', 0)
     # Add operators.
     operators = self._operators = query.valid_operators
     current_operator = query.operator
     index = -1
     for operator in operators:
         index += 1
         self.append_text(label(operator))
         if operator is current_operator:
             self.set_active(index)
Beispiel #18
0
 def __init__(self, allowed_extents):
     gtk.VButtonBox.__init__(self)
     group = None
     self.selected_extent = None
     for extent in allowed_extents:
         button = gtk.RadioButton(group, label(extent), use_underline=False)
         if group is None:
             # First in the list, so make it the group and the
             # selected extent.
             group = button
             self.selected_extent = extent
             button.props.active = True
         button.connect('toggled', self.on_radio_button__toggled, extent)
         button.show()
         self.add(button)
Beispiel #19
0
def print_entity_information(db, entity):
    if db.format != 2:
        raise RuntimeError('Unsupported DB format')
    print '=' * 70
    print 'Entity information for %r' % entity
    print 'Label: %r' % label(entity)
    extent = entity.s.extent
    print 'Extent: %r (id %r)' % (
        extent.name,
        db._extent_name_id[extent.name],
        )
    print 'Fields:'
    extent_map = db._extent_map(extent.name)
    field_id_name = extent_map['field_id_name']
    entity_map = db._entity_map(extent.name, entity.s.oid)
    for field_id, stored_value in sorted(entity_map['fields'].iteritems()):
        print '    %r (name %r): %r' % (
            field_id,
            field_id_name[field_id],
            stored_value,
            )
    print 'Related Entities:'
    related_entities = sorted(entity_map['related_entities'].iteritems())
    for field_id, related_entity_set in related_entities:
        print '    %r (name %r): %r' % (
            field_id,
            field_id_name[field_id],
            related_entity_set,
            )
    print 'Link Count: %r' % entity_map['link_count']
    print 'Links:'
    links = sorted(entity_map['links'].iteritems())
    for (ref_extent_id, ref_field_id), links_tree in links:
        ref_extent_name = db._extent_id_name.get(ref_extent_id, '<Not Found>')
        if ref_extent_id in db._extent_id_name:
            ref_extent_map = db._extent_map(ref_extent_name)
            ref_field_name = ref_extent_map['field_id_name'][ref_field_id]
        else:
            ref_field_name = '<Unknown>'
        oids = ' '.join(str(oid) for oid in sorted(links_tree))
        print '    From extent %r (name %r) field %r (name %r): %r' % (
            ref_extent_id,
            ref_extent_name,
            ref_field_id,
            ref_field_name,
            oids,
            )
Beispiel #20
0
def get_default_view_dialog(parent, db, entity, action,
                            get_value_handlers, set_field_handlers):
    extent_text = label(entity.s.extent)
    title = u'View :: %s' % (extent_text, )
    text = u'View :: %s :: %s' % (extent_text, entity)
    def include(field):
        if action.include_expensive:
            return True
        elif field.expensive:
            return False
        else:
            return True
    f_map = entity.s.field_map(include)
    fields = f_map.values()
    dialog = get_dialog(title, parent, text, db, entity, fields,
                        get_value_handlers, set_field_handlers)
    return dialog
Beispiel #21
0
 def __unicode__(self):
     extent = self._on
     criteria = self._criteria
     if criteria:
         field_spec = self._on.field_spec
         criteria = [
             # (field label, value label)
             (label(field_spec[name]), unicode(self.f[name]))
             for name in criteria
             ]
         criteria = ', '.join(
             '%s == %s' % (field_label, value_label)
             for field_label, value_label
             in criteria
             )
         return u'%s where (%s)' % (plural(extent), criteria)
     else:
         return u'all %s' % plural(extent)
Beispiel #22
0
 def __init__(self, db, query):
     gtk.HBox.__init__(self)
     self._db = db
     self._query = query
     FieldClass = query.FieldClass
     # Field for value-based operators.
     field = self._field = FieldClass(query, query.field_name, query.value)
     # Label for the query's field.
     field_label = widget.FieldLabel(label(field))
     self.pack_start(field_label, expand=False)
     # Menu list for operator selection.
     opcombo = OperatorComboBox(query)
     self.pack_start(opcombo, expand=False)
     opcombo.connect('changed', self.on_opcombo_changed)
     # Field widget.
     controller = self._controller = gtk_field.Controller(db, field)
     field_widget = self._field_widget = controller.widget
     self.pack_start(field_widget, expand=True)
     field_widget.props.visible = query.operator not in FIELDLESS_OPERATORS
Beispiel #23
0
 def rerun(self):
     """Re-run the query and update results."""
     db = self._db
     # Destroy existing results.
     class_expander = self._class_expander
     while class_expander:
         class_, expander = class_expander.pop()
         expander.destroy()
     # Re-run query.
     results = self._query()
     class_results = {}
     for result in results:
         L = class_results.setdefault(result.__class__, [])
         L.append(result)
     # Create expanders and listviews.
     if not class_results:
         no_results = gtk.Label('No results found.')
         self.pack_start(no_results, expand=False)
         class_expander.append((None, no_results))
     for class_, results in class_results.iteritems():
         extent = class_._extent
         expander_label = gtk.HBox()
         # Label for extent.
         extent_image = icon.small_image(self, extent)
         count = len(results)
         if count != 1:
             extent_label = gtk.Label(
                 u'%i %s found:' % (count, plural(extent)))
         else:
             extent_label = gtk.Label(
                 u'%i %s found:' % (count, label(extent)))
         expander_label.pack_start(extent_image, expand=False, padding=6)
         expander_label.pack_start(extent_label, expand=False, padding=6)
         expander = gtk.Expander()
         expander.props.label_widget = expander_label
         expander.props.expanded = True
         self.pack_start(expander, expand=True)
         listview = ResultsListView(class_, results)
         expander.add(listview)
         class_expander.append((class_, expander))
     self.show_all()
Beispiel #24
0
 def test_field_decoration(self):
     # Fields on transactions have labels.
     tx = db.Avatar.t.create()
     # These labels were assigned automatically.
     assert label.label(tx.f.realm) == 'Realm'
     assert label.label(tx.f.user) == 'User'
     assert label.label(tx.f.name) == 'Name'
     # Batch_Job.priority has a custom label.
     tx = db.Batch_Job.t.create()
     assert label.label(tx.f.priority) == 'Pri.'
     # Resulting entity instances' fields have labels.
     tx.name = 'foo'
     tx.priority = 1
     batch_job = db.execute(tx)
     assert label.label(batch_job.f.name) == 'Name'
     assert label.label(batch_job.f.priority) == 'Pri.'
Beispiel #25
0
 def setup_transactions(cls, class_name, class_dict, t_spec):
     """Create standard transaction classes."""
     # Fields in a transaction class defined in the schema appear
     # below the fields that come from the entity field spec.
     for name in dir(cls):
         # Skip namespace names so we do not access them.
         if len(name) == 1 or name == 'sys':
             continue
         OldClass = getattr(cls, name)
         if not isinstance(OldClass, type):
             continue
         if not issubclass(OldClass, (transaction.Create,
                                      transaction.Delete,
                                      transaction.Update)):
             continue
         NewClass = type(name, (OldClass,), {})
         NewClass._EntityClass = cls
         NewClass._extent_name = class_name
         NewClass._fget_fields = cls._fget_fields
         field_spec = NewClass._field_spec = t_spec.copy()
         field_spec.update(OldClass._field_spec, reorder=True)
         field_spec.reorder_all()
         # Perform any class-level initialization.
         if hasattr(NewClass, '_init_class'):
             NewClass._init_class()
         setattr(cls, name, NewClass)
     # Special case for DeleteSelected.  It needs to be subclassed
     # so that its ._db is set properly, but it does not need the
     # field copying performed above.
     if (isinstance(cls._DeleteSelected, type)
         and issubclass(cls._DeleteSelected, transaction.DeleteSelected)
         ):
         NewClass = type(name, (cls._DeleteSelected,), {})
         NewClass._EntityClass = cls
         NewClass._extent_name = class_name
         if hasattr(NewClass, '_init_class'):
             NewClass._init_class()
         relabel(NewClass, label(cls._DeleteSelected))
         cls._DeleteSelected = NewClass
Beispiel #26
0
 def test_transaction_decoration(self):
     # Canonical transactions have default labels.
     tx = db.Realm.t.create(name='foo')
     assert label.label(tx) == 'New'
     realm = db.execute(tx)
     assert label.label(realm.t.delete()) == 'Delete'
     assert label.label(realm.t.update()) == 'Edit'
     assert label.label(
         db.Realm.EntityClass.t.delete_selected([])) == 'Delete Selected'
     # Custom transactions have default labels generated from their
     # class name.
     tx = db.User.t.create_foo_and_bar()
     assert label.label(tx) == 'Create Foo And Bar'
     # Transaction instances can have custom labels assigned upon
     # creation by transaction methods, among other means.
     tx = db.Account[1].t.transfer()
     text = 'Transfer Funds From Fred Flintstone :: Personal'
     assert label.label(tx) == text
Beispiel #27
0
 def test_q_labels(self):
     assert label(db.DeltaAlpha.q.by_example) == u'By Example'
     assert label(db.DeltaAlpha.q.exact) == u'Exact Matches'
Beispiel #28
0
 def test_builtin_decoration(self):
     assert label.label('some string') == 'some string'
Beispiel #29
0
 def test_UNASSIGNED(self):
     assert label(UNASSIGNED) == '<UNASSIGNED>'
     assert len(UNASSIGNED) == 0
     assert str(UNASSIGNED) == ''
     assert raises(TypeError, UNASSIGNED)
Beispiel #30
0
 def test_view_labels(self):
     assert label(db.EchoAlpha[1].v.default) == u'View'
     assert label(db.EchoCharlie[1].v.custom) == u'Custom View'
     assert label(db.EchoAlpha[1].v.default()) == u'View'
     assert label(db.EchoCharlie[1].v.custom()) == u'Custom View'