def __init__(self, options, **kw): # options must be a regular list of strings, iterable is ok assert hasattr(options, "__iter__") and len(options) > 1 self.options = options # keep provided options kw.update({"options": options}) # set size, if not manually done... self.size = max(map(len, options)) # cross-check own size with provided and so on if kw.get("size") is not None and self.size <= kw.get("size"): raise DatabaseError( "provided size ({}<{}) is less than biggest " + "provided option: {}". \ format(kw.get("size"), self.size, ", ".join(options))) # default value -> first item of options, if no 'default' is set if "default" in kw: assert kw["default"] in options self.default = kw["default"] else: self.default = options[0] kw["default"] = self.default # call parent's ctor super(OptionField, self).__init__(**kw)
def __init__(self, **kw): # check, if kw contains solely legal keywords wrong = [ k for k in kw if not k in (self.accepted_keywords + self.general_keywords) ] if len(wrong) > 0: raise DatabaseError("Keyword(s): {} not supported by this Field: {}". \ format(", ".join(wrong), self.__class__.__name__)) # setting FieldObjects as member names for k, v in kw.items(): setattr(self, k, v) # apply the various general flags/values for k in self.general_keywords: val = kw.get(k) if k in kw else getattr(self.__class__, k) setattr(self, k, val) # keeps the explicit value of this field (and it's object, if applicable) self._value = self.default if not "default" in kw else kw["default"] self._value_obj = None # parent record class self.parent = None # keep the passed keyword-dict from instanciation self.passed_kw = kw
def __init__(cls, name, bases, dct): # exclude the base class from this behaviour if object in bases: return cls.table = name.lower() # move all "*Fields" to self.fields cls.base_fields = {} # queue based descent in hierachy to find all necassary fields of # arbitrary depth workqueue = [(cls, "", att) for att in cls.__dict__.keys()] from fields import AbstractField, BaseFieldGroup while len(workqueue) > 0: curcls, prefix, att = workqueue.pop(0) # check for minimal field name length (> 2) if len(att) < 2: raise DatabaseError("For __reasons unknown__ field " + \ "names must have at least 2 chars") # identify and setup fields inside this cls if not issubclass(curcls.__class__, (AbstractField, BaseFieldGroup)): field = getattr(curcls, att) else: field = curcls # description TODO ;D if issubclass(field.__class__, AbstractField): cls.setup_field(prefix + att, field) elif issubclass(field.__class__, BaseFieldGroup): cls.setup_field(prefix + att, field) for sub_field_key, sub_field in field.grp_fields.items(): if issubclass(sub_field.__class__, BaseFieldGroup): workqueue.append( (sub_field, prefix + att + "__", sub_field_key)) elif issubclass(sub_field.__class__, AbstractField): cls.setup_field(prefix + att + "__" + sub_field_key, sub_field) # init database instance for this class cls.database = SQLiteDatabase() cls.database.contribute(cls) # populate cls.objects cls.objects = DataManager(cls)
def __call__(cls, *vargs, **kw): # check, if kw contains solely legal keywords wrong = [k for k in kw if not k in cls.keywords] if len(wrong) > 0: raise DatabaseError("Keyword(s): {} unsupported by this Field: {}".\ format(", ".join(wrong), cls.__class__.__name__)) # create object instance out_inst = type.__call__(cls, *vargs, **kw) # fill in key->val from 'kw' into 'out_inst', as attributes for key, val in cls.keywords.items(): if key in kw: setattr(out_inst, key, kw[key]) return out_inst
def __init__(cls, name, bases, dct): # exclude the base class from this behaviour if not name == "BaseRecord": cls.table = name.lower() # move all "*Fields" to self.fields and init atts to None cls.base_fields = {} for att in cls.__dict__.keys()[:]: # check for minimal field name length (> 2) if len(att) < 2: raise DatabaseError( "For __reasons unknown__ field names must have at least 2 chars" ) # identify and setup fields inside this record field = getattr(cls, att) from fields import AbstractField if issubclass(field.__class__, AbstractField): cls.setup_field(att, field) # this does not behave as expected inside sqlite3 # - rowid named col needs AUTOINC, which sux (performance) # - so omit this and use built-in rowid, # which works nicely except for the unintuitive interface (select rowid, * ...) # # if there is no explicit column named: 'rowid', create one as primary_key!!! #if "rowid" not in cls.base_fields: # from fields import IDField # cls.setup_field("rowid", # IDField(name="rowid", unique=True, primary_key=True)) # init database instance for this class cls.database = Database() cls.database.contribute(cls) # populate cls.objects cls.objects = DataManager(cls)
def __init__(self, **kw): # copy class base_fields to instanc:e self.fields = {} for name, field in self.__class__.base_fields.items(): self.fields[name] = field.clone() # if there is some keyword-argument, that is not handled by the record, throw exception for key in kw: if key == "rowid": continue if not key in self.fields: raise DatabaseError( "The field/keyword: '{}' was not found in the record". format(key)) # set this obj as parent for all fields for name, field in self.fields.items(): field.parent = self from fields import ManyToOneRelation, OneToManyRelation, \ OneToOneRelation, ManyToManyRelation # process each defined field self.rowid = None self.found_primary_key = False for k, v in kw.items(): field = self.fields.get(k) # keep field using the primary_key flag and ensure its uniqueness if field is not None and field.primary_key: if not self.found_primary_key: self.found_primary_key = (k, v) else: raise DatabaseError("Found multiple 'primary_key' flagged fields. Inserting: {} Found: {}". \ format(k, str(self.found_primary_key))) # relation-field -> 1:N elif issubclass(field.__class__, OneToManyRelation): field.set(v) # relation-field -> N:1 elif issubclass(field.__class__, ManyToOneRelation): #rid = v if isinstance(v, int) else v.rowid #field.set(field.related_record.objects.get(rowid=rid)) field.set(v) # relation-field -> 1:1 elif issubclass(field.__class__, OneToOneRelation): #rid = v if isinstance(v, int) else v.rowid #field.set(field.related_record.objects.get(rowid=rid)) field.set(v) # relation-field -> N:M elif issubclass(field.__class__, ManyToManyRelation): raise DatabaseError("NOT IMPLEMENTED: ManyToManyRelation") # unique-identifier field # (overwritten by user-defined Field, if inside this branch) elif k == "rowid": if field is not None: field.set(v) self.rowid = v # regular, all other fields else: field.set(v)
def __init__(self, **kw): # copy class base_fields to instance self.fields = {} from fields import ManyToOneRelation, OneToOneRelation, \ ManyToManyRelation, BaseFieldGroup for name, field in self.__class__.base_fields.items(): self.fields[name] = field.clone() self.fields[name].name = name # check for a non-existing passwd keyword for key in kw: if key == "rowid": continue if not key in self.fields: raise DatabaseError("The field/keyword: '{}' was not found " + \ "in the record".format(key)) # set this obj as parent for all fields for name, field in self.fields.items(): field.parent = self # 'dirty'-flag ... 'True' -> needs to be saved self.dirty = True # keyword assignment add_kw = {} for name in kw.keys(): field = self.fields.get(name) if isinstance(field, BaseFieldGroup): for k in field.key2field.keys(): add_kw[name + "__" + k] = getattr(kw.get(name), k) kw.update(add_kw) # process each defined field self.rowid = None self.found_primary_key = False for k, v in kw.items(): field = self.fields.get(k) # keep field using the primary_key flag and ensure its uniqueness if field is not None \ and hasattr(field, "primary_key") \ and field.primary_key: if not self.found_primary_key: self.found_primary_key = (k, v) else: raise DatabaseError("Found multiple 'primary_key' " + \ "flagged fields. Inserting: {} Found: {}". \ format(k, str(self.found_primary_key))) # handle index col elif k == "rowid": if field is not None: field.set(v) self.rowid = v # regular, all other fields else: field.set(v) for k, v in self.fields.items(): if isinstance(v, BaseFieldGroup): v.update_cls()