def select_after_insert_where(self, dbobj): if dbobj.__primary_key__ is None: raise PrimaryKeyNotKnown() primary_key_attributes = tuple(dbobj.__primary_key__.attributes()) if len(primary_key_attributes) == 1: primary_key_attribute = primary_key_attributes[0] else: primary_key_attribute = None if isinstance(primary_key_attribute, datatypes.serial): # Serial columns are treated specially if primary_key_attribute.sequence_name is None: if dbobj.__relation__.schema is not None: # If the relation's name is quoted and contains illegal # characters for a sequence name, this wil result in an # illegal identifyer. In that case please specify # the sequence name by hand. relation = "%s.%s" % ( dbobj.__relation__.schema, dbobj.__relation__.name.name, ) else: relation = dbobj.__relation__.name sequence_name = "%s_%s_seq" % ( relation, primary_key_attribute.column, ) else: sequence_name = primary_key_attribute.sequence_name where = sql.where( sql.expression(primary_key_attribute.column, " = ", "currval('%s')" % (sequence_name, ))) elif isinstance(primary_key_attribute, common_serial): where = sql.where( sql.expression("id = ", "currval('%s_id_seq')" % dbobj.__relation__)) elif dbobj.__primary_key__.isset(): # If we know the primary key value, we use it to identify # the new row. where = dbobj.__primary_key__.where() else: raise PrimaryKeyNotKnown() return where
def insert(self, dbobj, dont_select=False): """ Firebird does not provide a mechanism that let's me query the id of the last row I inserted. This has to be done *before* the INSERT. """ for property in dbobj.__dbproperties__(): if isinstance(property, common_serial): sequence_name = "GEN_PK_%s" % dbobj.__relation__ elif isinstance(property, datatypes.serial): sequence_name = property.sequence else: continue query = sql.select(sql.expression("GEN_ID(", sequence_name, ", 1) AS new_id"), "RDB$DATABASE") cursor = self.execute(query) tpl = cursor.fetchone() new_id = tpl[0] property.__set_from_result__(self, dbobj, new_id) orm2.datasource.datasource_base.insert(self, dbobj, dont_select)
def __init_dbclass__(self, dbclass, attribute_name): self.inside_datatype.__init_dbclass__(dbclass, attribute_name) exp = self.expression.parts[:] exp.insert(0, "(") exp.append(") AS ") exp.append(self.column) # Perform template substitution info = { "$relation": str(dbclass.__relation__), "$table": str(dbclass.__relation__), "$attribute": attribute_name } for key, value in info.items(): n = [] for a in exp: if type(a) == StringType: parts = a.split(key) parts.reverse() s = [] while parts: s.append(parts.pop()) if parts: s.append(value) n.append(join(s, "")) else: n.append(a) exp = n self.column = sql.expression(*exp)
def select_after_insert_where(self, dbobj): if dbobj.__primary_key__ is None: raise PrimaryKeyNotKnown() primary_key_attributes = tuple(dbobj.__primary_key__.attributes()) if len(primary_key_attributes) == 1: primary_key_attribute = primary_key_attributes[0] else: primary_key_attribute = None if isinstance(primary_key_attribute, datatypes.serial): # Serial columns are treated specially if primary_key_attribute.sequence_name is None: if dbobj.__relation__.schema is not None: # If the relation's name is quoted and contains illegal # characters for a sequence name, this wil result in an # illegal identifyer. In that case please specify # the sequence name by hand. relation = "%s.%s" % ( dbobj.__relation__.schema, dbobj.__relation__.name.name, ) else: relation = dbobj.__relation__.name sequence_name = "%s_%s_seq" % ( relation, primary_key_attribute.column, ) else: sequence_name = primary_key_attribute.sequence_name where = sql.where(sql.expression( primary_key_attribute.column, " = ", "currval('%s')" % (sequence_name, ) )) elif isinstance(primary_key_attribute, common_serial): where = sql.where(sql.expression( "id = ", "currval('%s_id_seq')" % dbobj.__relation__ )) elif dbobj.__primary_key__.isset(): # If we know the primary key value, we use it to identify # the new row. where = dbobj.__primary_key__.where() else: raise PrimaryKeyNotKnown() return where
def count_all(self): """ Do the same thing as count() above, but remove all clauses but the where clause. """ count_select = copy.deepcopy(self.select) count_select.columns = sql.expression("COUNT(*)") count_select.clauses = \ filter(lambda clause: isinstance(clause, sql.where), count_select.clauses) return int(self.ds.query_one(count_select))
def __init__(self, inside_datatype, expression, has_default=False, default=None): wrapper.__init__(self, inside_datatype) if type(expression) == StringType: expression = sql.expression(expression) if not isinstance(expression, sql.expression): msg = ( "You must initialize an expression datatype width an " "sql.expression instance, or a string, " "not %s") % repr(expression) raise TypeError(msg) self.expression = expression self.has_default = has_default self.default = default
def count(self): """ This is a helper function that will perform a query as SELECT COUNT(*) ... appropriate to determine the number of rows in this result. This will include all clauses of the original select. This can't be called __len__(), because then it is used by list() and yields a superflous SELECT query. """ count_select = copy.deepcopy(self.select) count_select.clauses = \ filter(lambda clause: isinstance(clause, sql.where) \ or isinstance(clause, sql.limit) \ or isinstance(clause, sql.offset), count_select.clauses) count_select.columns = sql.expression("COUNT(*)") return int(self.ds.query_one(count_select))
def __init__(self, inside_datatype, expression, has_default=False, default=None): wrapper.__init__(self, inside_datatype) if type(expression) == StringType: expression = sql.expression(expression) if not isinstance(expression, sql.expression): msg = ("You must initialize an expression datatype width an " "sql.expression instance, or a string, " "not %s") % repr(expression) raise TypeError(msg) self.expression = expression self.has_default = has_default self.default = default