def __init__(self, inst, propname, givenargs): """ Constructor. @param inst: The L{DBObject} instance. @param propname: The property name in the L{DBObject} instance that results in this class being created. @param givenargs: Any arguments given (through the use of a C{dict} in the class variable in L{DBObject} rather than a string to describe the relationship). The given args can include, for all relationships, a C{class_name}. Depending on the relationship, C{association_foreign_key} and C{foreign_key} might also be used. """ self.infl = Inflector() self.inst = inst self.dbconfig = Registry.getConfig() self.args = { 'class_name': propname, 'association_foreign_key': self.infl.foreignKey(self.infl.singularize(propname)), 'foreign_key': self.infl.foreignKey(self.inst.__class__.__name__), 'polymorphic': False } self.args.update(givenargs) otherklassname = self.infl.classify(self.args['class_name']) if not self.args['polymorphic']: self.otherklass = Registry.getClass(otherklassname) self.othername = self.args['association_foreign_key'] self.thisclass = self.inst.__class__ self.thisname = self.args['foreign_key']
def find(klass, id=None, where=None, group=None, limit=None, orderby=None): """ Find instances of a given class. @param id: The integer of the C{klass} to find. For instance, C{Klass.find(1)} will return an instance of Klass from the row with an id of 1 (unless it isn't found, in which case C{None} is returned). @param where: A C{list} whose first element is the string version of the condition with question marks in place of any parameters. Further elements of the C{list} should be the values of any parameters specified. For instance, C{['first_name = ? AND age > ?', 'Bob', 21]}. @param group: A C{str} describing the grouping, like C{group='first_name'}. @param limit: An C{int} specifying the limit of the results. If this is 1, then the return value will be either an instance of C{klass} or C{None}. @param orderby: A C{str} describing the ordering, like C{orderby='first_name DESC'}. @return: A C{Deferred} which returns the following to a callback: If id is specified (or C{limit} is 1) then a single instance of C{klass} will be returned if one is found that fits the criteria, C{None} otherwise. If id is not specified and C{limit} is not 1, then a C{list} will be returned with all matching results. """ config = Registry.getConfig() d = config.select(klass.tablename(), id, where, group, limit, orderby) return d.addCallback(createInstances, klass)
def _init_(self): """ Check to make sure the database exists. Will create if missing, will also update schema if any changes are required. """ self._ModDescription = "Manages the local database" self._ModAuthor = "Mitch Schwenk @ Yombo" self._ModUrl = "https://yombo.net" self.db_model = {} #store generated database model here. # Connect to the DB Registry.DBPOOL = adbapi.ConnectionPool('sqlite3', "usr/etc/yombo.db", check_same_thread=False, cp_min=1, cp_max=1) self.dbconfig = Registry.getConfig() self.schema_version = 0 try: results = yield Schema_Version.find(where=['table_name = ?', 'core']) self.schema_version = results[0].version except: logger.info("Creating new database file.") start_schema_version = self.schema_version for z in range(self.schema_version+1, LATEST_SCHEMA_VERSION+1): script = __import__("yombo.utils.db."+str(z), globals(), locals(), ['upgrade'], 0) results = yield script.upgrade(Registry) self.dbconfig.update("schema_version", {'table_name': 'core', 'version':z}) results = yield Schema_Version.all() yield self._load_db_model()
def _transaction(txn, args, kwargs): config = Registry.getConfig() config.txn = txn # get the result of the functions *synchronously*, since this is in a transaction try: result = threads.blockingCallFromThread(reactor, interaction, txn, *args, **kwargs) config.txn = None return result except Exception, e: config.txn = None raise TransactionError(str(e))
def _transaction(txn, args, kwargs): config = Registry.getConfig() config.txn = txn # get the result of the functions *synchronously*, since this is in a transaction try: result = threads.blockingCallFromThread(reactor, interaction, txn, *args, **kwargs) config.txn = None return result except Exception as e: config.txn = None raise TransactionError(str(e))
def count(klass, where=None): """ Count instances of a given class. @param where: An optional C{list} whose first element is the string version of the condition with question marks in place of any parameters. Further elements of the C{list} should be the values of any parameters specified. For instance, C{['first_name = ? AND age > ?', 'Bob', 21]}. @return: A C{Deferred} which returns the total number of db records to a callback. """ config = Registry.getConfig() return config.count(klass.tablename(), where=where)
def deleteAll(klass, where=None): """ Delete all instances of C{klass} in the database without instantiating the records first or invoking callbacks (L{beforeDelete} is not called). This will run a single SQL DELETE statement in the database. @param where: Conditionally delete instances. This parameter is of the same form found in L{find}. @return: A C{Deferred}. """ config = Registry.getConfig() tablename = klass.tablename() return config.delete(tablename, where)
def executeOperation(self, query, *args, **kwargs): """ Simply makes same C{twisted.enterprise.dbapi.ConnectionPool.runOperation} call, but with call to L{log} function. """ # self.log(query, args, kwargs) Registry.debug(f"q: {query}\n") Registry.debug(f"args: {args}\n") Registry.debug(f"kwargs: {kwargs}\n") return Registry.DBPOOL.runOperation(query, *args, **kwargs)
def executeTxn(self, txn, query, *args, **kwargs): """ Execute given query within the given transaction. Also, makes call to L{log} function. """ Registry.debug(f"q: {query}\n") Registry.debug(f"args: {args}\n") Registry.debug(f"kwargs: {kwargs}\n") # print(f"q: {query}\n") # print(f"args: {args}\n") # print(f"kwargs: {kwargs}\n") return txn.execute(query, *args, **kwargs)
def __init__(self, **kwargs): """ Constructor. DO NOT OVERWRITE. Use the L{DBObject.afterInit} method. @param kwargs: An optional dictionary containing the properties that should be initially set for this object. @see: L{DBObject.afterInit} """ self._rowid = None self.id = None self._deleted = False self.errors = Errors() self.updateAttrs(kwargs) self._config = Registry.getConfig() if self.__class__.RELATIONSHIP_CACHE is None: self.__class__.initRelationshipCache()
def _init_(self, **kwargs): """ Check to make sure the database exists. Will create if missing, will also update schema if any changes are required. """ self.working_dir = settings.arguments["working_dir"] self.db_bulk_queue = {} self.db_bulk_queue_id_cols = {} self.save_bulk_queue_loop = None self.cleanup_database_loop = None self.cleanup_database_running = False self.db_model = {} # store generated database model here. self.remote_tables = [ 'categories', 'commands', 'devices', 'device_command_inputs', 'device_commands', 'device_types', 'device_type_commands', 'gateways', 'input_types', 'locations', 'modules', 'module_commits', 'module_device_types', 'nodes', 'users', 'variable_groups', 'variable_fields', 'variable_data' ] # Connect to the DB def show_connected(connection): connection.execute("PRAGMA foreign_keys = ON") Registry.DBPOOL = adbapi.ConnectionPool( "sqlite3", f"{self.working_dir}/etc/yombo.sqlite3", check_same_thread=False, cp_min=1, cp_max=1, cp_openfun=show_connected) self.dbconfig = Registry.getConfig() # self._Events.new("localdb", "connected", (start_schema_version, current_schema_version)) yield self._load_db_model() # print(self.db_model) Registry.DBPOOL.runOperation("PRAGMA synchronous=2;") # used to cache datatables lookups for the webinterface viewers self.event_counts = self._Cache.ttl(ttl=15, tags="events") self.storage_counts = self._Cache.ttl(ttl=15, tags="storage") self.webinterface_counts = self._Cache.ttl(ttl=15, tags="webinterface_logs")
def __init__(self, **kwargs): """ Constructor. DO NOT OVERWRITE. Use the L{DBObject.afterInit} method. @param kwargs: An optional dictionary containing the properties that should be initially set for this object. @see: L{DBObject.afterInit} """ if self.ID_FIELD in kwargs: self._rowid = kwargs[self.ID_FIELD] else: self._rowid = None # self.id = None self._deleted = False self.errors = Errors() self.updateAttrs(kwargs) self._config = Registry.getConfig() if self.__class__.RELATIONSHIP_CACHE is None: self.__class__.initRelationshipCache()
""" Determine if this object is the same as another (only taking the type of the other class and it's C{id} into account). @param other: The other object to compare this one to. @return: A boolean. """ eqclass = self.__class__.__name__ == other.__class__.__name__ eqid = hasattr(other, '_rowid') and self._rowid == other._rowid return eqclass and eqid def __neq__(self, other): """ Determine if this object is not the same as another (only taking the type of the other class and it's C{id} into account). @param other: The other object to compare this one to. @return: A boolean. """ return not self == other def __hash__(self): return hash('%s.%d' % (type(self).__name__, self._rowid)) __repr__ = __str__ Registry.register(DBObject)
@param other: The other object to compare this one to. @return: A boolean. """ eqclass = self.__class__.__name__ == other.__class__.__name__ eqid = hasattr(other, '_rowid') and self._rowid == other._rowid return eqclass and eqid def __neq__(self, other): """ Determine if this object is not the same as another (only taking the type of the other class and it's C{id} into account). @param other: The other object to compare this one to. @return: A boolean. """ return not self == other def __hash__(self): return hash('%s.%d' % (type(self).__name__, self.id)) __repr__ = __str__ Registry.register(DBObject)
class WebinterfaceLogs(DBObject): TABLENAME = "webinterface_logs" #### Views #### class ModuleRoutingView(DBObject): TABLENAME = "module_routing_view" Registry.SCHEMAS["PRAGMA_table_info"] = [ "cid", "name", "type", "notnull", "dft_value", "pk" ] Registry.register(Device, DeviceState, VariableData, DeviceType, Command) Registry.register(Modules, ModuleInstalled, ModuleDeviceType) Registry.register(VariableGroups, VariableData) Registry.register(Category) Registry.register(DeviceTypeCommand) Registry.register(Events) Registry.register(EventTypes) #Registry.setDebug(True) TEMP_MODULE_CLASSES = inspect.getmembers(sys.modules[__name__]) MODULE_CLASSES = {} for item in TEMP_MODULE_CLASSES: if isinstance(item, tuple) and len(item) == 2: if inspect.isclass(item[1]): if issubclass(item[1], DBObject): MODULE_CLASSES[item[0]] = item[1]
# class Variable(DBObject): # TABLENAME='variables' # BELONGSTO = ['devices', 'modules'] class Sessions(DBObject): TABLENAME='webinterface_sessions' #### Views #### class ModuleRoutingView(DBObject): TABLENAME='module_routing_view' #Registry.register(Config) Registry.SCHEMAS['PRAGMA_table_info'] = ['cid', 'name', 'type', 'notnull', 'dft_value', 'pk'] Registry.register(Device, DeviceStatus, VariableData, DeviceType, Command) Registry.register(Modules, ModuleInstalled) Registry.register(VariableGroups, VariableData) Registry.register(Category) Registry.register(DeviceTypeCommand) TEMP_MODULE_CLASSES = inspect.getmembers(sys.modules[__name__]) MODULE_CLASSES = {} for item in TEMP_MODULE_CLASSES: if isinstance(item, tuple) and len(item) == 2 : if inspect.isclass(item[1]): if issubclass(item[1], DBObject): MODULE_CLASSES[item[0]] = item[1] del TEMP_MODULE_CLASSES
def get_polymorphic(row): kid = getattr(row, "%s_id" % self.args['class_name']) kname = getattr(row, "%s_type" % self.args['class_name']) return Registry.getClass(kname).find(kid)