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, 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() ## Set args 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 commit(self): self._assertCorrectThread() if not self._parent.is_active: raise TransactionError("This transaction is inactive") Registry.getConfig().txnGuard.txn = self._actual_parent self._do_commit() self.is_active = False
def rollback(self): self._assertCorrectThread() if not self._parent.is_active: return Registry.getConfig().txnGuard.txn = self._actual_parent self._do_rollback() self.is_active = False
def setUp(self): yield initDB(self) self.user = yield User(first_name="First", last_name="Last", age=10).save() self.avatar = yield Avatar(name="an avatar name", user_id=self.user.id).save() self.picture = yield Picture(name="a pic", size=10, user_id=self.user.id).save() self.dbconfig = Registry.getConfig()
def _refresh(self, forced=False): if self.DEBUG: self.logger.info( 'Penguin ASync-Refresh-ing : Penguin - {}, Forced - {}'.format( self.penguin['nickname'], forced)) if self.penguin['connectionLost']: returnValue(0) if self.firstTimeCall: yield self._setupCache() self.firstTimeCall = False returnValue(1) # coins update self.penguin.penguin.coins = (yield Registry.getConfig(). \ execute("SELECT SUM(transaction) FROM coins where penguin_id = %s" % self.penguin['id']))[0][0] if self.penguin['coins'] is None: yield Coin(penguin_id=self.penguin['id'], transaction=100, comment="Player went bankrupt. " "Giving them +100").save() self.penguin.penguin.coins = 100 self.penguin.penguin.coins = int(self.penguin['coins']) self.penguin.send('gtc', self.penguin['coins']) for item in self.REFRESH_ITEMS: if not hasattr(self.penguin.dbpenguin, item): continue relation = getattr(self.penguin.dbpenguin, item) items_o = set(self.cache[item]) items_ = yield relation.get() items_updated = set(items_) items_added = items_updated - items_o items_removed = items_o - items_updated reactor.callFromThread(self.cacheHandlers[item], items_added, items_removed, items_o) reactor.callFromThread(self.cacheHandlers['igloos']) GeneralEvent( 'Refresh-Cache', self) # Refresh cache data for things other than those in here if forced: reactor.callFromThread( self.RefreshManagerLoop.stop ) if self.RefreshManagerLoop.running else None reactor.callFromThread(self.RefreshManagerLoop.start, self.REFRESH_INTERVAL, False) if \ not self.penguin['connectionLost'] else None
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 _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 deleteAll(klass, where=None, transaction=None): """ Delete all instances of C{klass} 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, transaction)
def transaction(func=None, nested=False, thread_check=True): """Starts a new transaction. A Transaction object returned by this function can be used as a context manager, which will atomatically be commited or rolledback if an exception is raised. Transactions must only be used in db threads. This behaviour can be overriden by setting the 'thread_check' to False, allowing transactions to be started in arbitrary threads which is useful to e.g simplify testcases. If this function is used as decorator, the decorated function will be executed in a db thread and gets the Transaction passed as first argument. Decorated functions are allowed to return Deferreds. E.g: @transaction def someFunc(txn, param1): # Runs in a db thread d = someFunc(1) # will be calledback (in mainthread) when someFunc returns You have to make sure, that you use blockingCallFromThread() or use synchronization if you need to interact with code which runs in the mainthread. Also care has to be taken when waiting for Deferreds. You must assure that the callbacks will be invoked from the db thread. Per default transactions can be nested: Commiting such a "nested" transaction will simply do nothing, but a rollback on it will rollback the outermost transaction. This allow creation of functions which will either create a new transaction or will participate in an already ongoing tranaction which is handy for library code. SAVEPOINT transactions can be used by either setting the 'nested' flag to true or by calling the 'nested_transaction' function. """ if nested and Registry.DBPOOL.dbapi.__name__ == "sqlite3": # needs some modification on our side, see: # http://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#serializable-isolation-savepoints-transactional-ddl raise NotImplementedError("sqlite currently not supported") if func is None: conn_pool = Registry.DBPOOL cfg = Registry.getConfig() if cfg.txnGuard.txn is None: conn = conn_pool.connectionFactory(conn_pool) return _RootTransaction(conn_pool, conn, thread_check=thread_check) elif nested: return _SavepointTransaction(cfg.txnGuard.txn, thread_check=thread_check) else: return _Transaction(cfg.txnGuard.txn, thread_check=thread_check) else: return _transaction_dec( func, functools.partial(transaction, nested=nested, thread_check=thread_check))
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 connect(cls, connection, *args, **kwargs): "This is how we instantiate a DatastoreSQL object with connection" obj = cls(connection, *args, **kwargs) Registry.DBPOOL = adbapi.ConnectionPool( 'pyodbc', obj.config['connection'], autocommit=True, cp_reconnect=True ) obj.raw_db = Registry.DBPOOL # Accessible if we need *really* low-level access to DB. obj.db = Registry.getConfig() return obj
def transaction(func=None, nested=False, thread_check=True): """Starts a new transaction. A Transaction object returned by this function can be used as a context manager, which will atomatically be commited or rolledback if an exception is raised. Transactions must only be used in db threads. This behaviour can be overriden by setting the 'thread_check' to False, allowing transactions to be started in arbitrary threads which is useful to e.g simplify testcases. If this function is used as decorator, the decorated function will be executed in a db thread and gets the Transaction passed as first argument. Decorated functions are allowed to return Deferreds. E.g: @transaction def someFunc(txn, param1): # Runs in a db thread d = someFunc(1) # will be calledback (in mainthread) when someFunc returns You have to make sure, that you use blockingCallFromThread() or use synchronization if you need to interact with code which runs in the mainthread. Also care has to be taken when waiting for Deferreds. You must assure that the callbacks will be invoked from the db thread. Per default transactions can be nested: Commiting such a "nested" transaction will simply do nothing, but a rollback on it will rollback the outermost transaction. This allow creation of functions which will either create a new transaction or will participate in an already ongoing tranaction which is handy for library code. SAVEPOINT transactions can be used by either setting the 'nested' flag to true or by calling the 'nested_transaction' function. """ if nested and Registry.DBPOOL.dbapi.__name__ == "sqlite3": # needs some modification on our side, see: # http://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#serializable-isolation-savepoints-transactional-ddl raise NotImplementedError("sqlite currently not supported") if func is None: conn_pool = Registry.DBPOOL cfg = Registry.getConfig() if cfg.txnGuard.txn is None: conn = conn_pool.connectionFactory(conn_pool) return _RootTransaction(conn_pool, conn, thread_check=thread_check) elif nested: return _SavepointTransaction(cfg.txnGuard.txn, thread_check=thread_check) else: return _Transaction(cfg.txnGuard.txn, thread_check=thread_check) else: return _transaction_dec(func, functools.partial(transaction, nested=nested, thread_check=thread_check))
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.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, parent, thread_check=True): # Transactions must be started in db thread unless explicitely permitted if thread_check and threading.current_thread() not in Registry.DBPOOL.threadpool.threads: raise TransactionError("Transaction must only be started in a db pool thread") if parent is None: self._root = self else: self._root = parent._root self._actual_parent = parent self.is_active = True self._threadId = threadable.getThreadID() self._savepoint_seq = 0 if not self._parent.is_active: raise TransactionError("Parent transaction is inactive") Registry.getConfig().txnGuard.txn = self
def __init__(self, parent, thread_check=True): # Transactions must be started in db thread unless explicitely permitted if thread_check and threading.current_thread( ) not in Registry.DBPOOL.threadpool.threads: raise TransactionError( "Transaction must only be started in a db pool thread") if parent is None: self._root = self else: self._root = parent._root self._actual_parent = parent self.is_active = True self._threadId = threadable.getThreadID() self._savepoint_seq = 0 if not self._parent.is_active: raise TransactionError("Parent transaction is inactive") Registry.getConfig().txnGuard.txn = self
def resetAllPwmStatus(): return Registry.getConfig().delete("pwmstatus")
def resetAllRelStatus(): return Registry.getConfig().delete("relstatus")
def _setupCache(self): self.penguin.penguin.recentStamps = [] database_penguin = self.penguin.dbpenguin self.cache.avatar = yield database_penguin.avatar.get() if self.cache.avatar is None: self.cache.avatar = yield Avatar( penguin_id=self.penguin['id']).save() yield self.cache.avatar.refresh() self.cache.inventories = yield database_penguin.inventories.get() self.cache.assets = yield database_penguin.assets.get() self.cache.friends = yield database_penguin.friends.get() self.cache.requests = [] friends_data = [] for friend in self.cache.friends: friendObj = (yield Penguin.find(where=['swid = ?', friend.friend], limit=1)) if friendObj is None: continue friend.friend_id = friendObj.id friend.onlinePresence = {'online_status': False} data = [ int(friendObj.id), friendObj.nickname, friendObj.swid, friend.bff ] friends_data.append('|'.join(map(str, data))) self.penguin.send('fl', (yield database_penguin.requests.count()), *friends_data) self.cache.ignores = yield database_penguin.ignores.get() self.cache.careItems = yield database_penguin.careItems.get() self.cache.stamps = yield database_penguin.stamps.get() self.cache.mails = yield database_penguin.mails.get() self.cache.bans = yield database_penguin.bans.get() self.cache.puffles = yield database_penguin.puffles.get() self.cache.stampCovers = yield database_penguin.stampCovers.get() self.cache.igloos = deque() igloos = yield database_penguin.igloos.get(limit=6) for igloo in igloos: iglooCache = PenguinObject() iglooCache.igloo = igloo iglooCache.iglooFurnitures = yield igloo.iglooFurnitures.get( limit=99) iglooCache.iglooLikes = yield igloo.iglooLikes.get() self.cache.igloos.append(iglooCache) self.cache.memberships = yield database_penguin.memberships.get() self.cacheHandlers.inventories = self.handleInventory self.cacheHandlers.assets = self.handleAssets self.cacheHandlers.friends = self.handleFriends self.cacheHandlers.requests = self.handleRequests self.cacheHandlers.ignores = self.handleIgnores self.cacheHandlers.careItems = self.handleCareItems self.cacheHandlers.stamps = self.handleStamps self.cacheHandlers.mails = self.handleMails self.cacheHandlers.bans = self.handleBans self.cacheHandlers.puffles = self.handlePuffles self.cacheHandlers.stampCovers = self.handleStampCovers self.cacheHandlers.igloos = self.handleIgloos self.penguin.penguin.coins = (yield Registry.getConfig().\ execute("SELECT COALESCE(SUM(transaction), 0) FROM coins where penguin_id = %s" % self.penguin['id']))[0][0] self.penguin.penguin.igloo = yield self.initPenguinIglooRoom( self.penguin['id']) if self.penguin['igloo']._id not in self.getIgloos(): igloo = yield database_penguin.igloos.get( where=['id = ?', self.penguin['igloo']._id], limit=1) iglooCache = PenguinObject() iglooCache.igloo = igloo iglooCache.iglooFurnitures = yield igloo.iglooFurnitures.get( limit=99) iglooCache.iglooLikes = yield igloo.iglooLikes.get() self.cache.igloos.append(iglooCache) self.penguin.penguin.currentIgloo = self.getIgloos()[ self.penguin.dbpenguin.igloo].igloo self.setupCJMats() membership = yield database_penguin.memberships.get( orderby='expires desc', limit=1) if membership is None: #no membership records, give a free 7 day trial trialExpiry = time.time() + 7 * 24 * 60 * 60 membership = yield \ Membership(penguin_id=self.penguin['id'], expires=Registry.getDBAPIClass("TimestampFromTicks")(trialExpiry), comments='Redeemed 7-day auto free trial membership. - Timeline Server').save() self.penguin.penguin.member = MembershipHandler( membership, self.penguin) self.cache.avatar = yield database_penguin.avatar.get() if self.cache.avatar is None: self.cache.avatar = yield Avatar( penguin_id=self.penguin['id']).save() GeneralEvent('Setup-Cache', self) self.CacheInitializedDefer.callback(True)
def resetDynMediaSources(): return Registry.getConfig().delete('video', where=["dynamic=1"])
def get_likes_count(self): likes = yield Registry.getConfig().execute("SELECT COALESCE(SUM(likes), 0) FROM igloo_likes where " "igloo_id = %s" % (self.id)) returnValue(likes[0][0])
def resetAllInpStatus(): return Registry.getConfig().delete("inpstatus")
def __init__(self, driver, **kwargs): conf = {'cp_reconnect': True, 'charset': 'utf8'} conf.update(kwargs) Registry.DBPOOL = adbapi.ConnectionPool(driver, **conf) self.dbconfig = Registry.getConfig()
def cleanFlags(): Registry.getConfig().delete("flags", where=["expire<="+str(time.time())])
def resetDynPwms(): return Registry.getConfig().delete("pwm", where=["dynamic=1"])
def resetDynAnalogs(): return Registry.getConfig().delete("analog", where=["dynamic=1"])
def resetDynActions(): return Registry.getConfig().delete("actions", where=["dynamic=1"])
def cleanOldStatus(ts): Registry.getConfig().delete("anastatus", where=["lastupdate<"+str(ts)]) Registry.getConfig().delete("inpstatus", where=["lastupdate<"+str(ts)]) Registry.getConfig().delete("relstatus", where=["lastupdate<"+str(ts)]) Registry.getConfig().delete("pwmstatus", where=["lastupdate<"+str(ts)])
def __init__(self, driver, **kwargs): conf = { 'cp_reconnect': True, 'charset': 'utf8' } conf.update(kwargs) Registry.DBPOOL = adbapi.ConnectionPool(driver, **conf) self.dbconfig = Registry.getConfig()
def resetDynInputs(): return Registry.getConfig().delete("input", where=["dynamic=1"])
def resetAllAnaStatus(): return Registry.getConfig().delete("anastatus")
def resetBoards(): return Registry.getConfig().delete("dmboards")
def cleanUndetected(): Registry.getConfig().delete("analog", where=["detected=0 AND dynamic>0"]) Registry.getConfig().delete("relay", where=["detected=0 AND dynamic>0"]) Registry.getConfig().delete("input", where=["detected=0 AND dynamic>0"]) Registry.getConfig().delete("actions", where=["detected=0 AND dynamic>0"]) Registry.getConfig().delete("output", where=["detected=0 AND dynamic>0"]) Registry.getConfig().delete("pwm", where=["detected=0 AND dynamic>0"])
def resetDynRelays(): log.debug('RESET DYN RELAYS') return Registry.getConfig().delete("relay", where=["dynamic=1"])