def set_fields(tbl, ndnt): ''' Generate the code for initializing an object of type tbl.''' lines = [] line = "@staticmethod" lines.append(cg.indent(ndnt, line)) line = "def set_fields(" + tbl.py_singular + ", fields):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "'''Get a new " + tbl.py_singular + " populated from fields.'''" lines.append(cg.indent(ndnt, line)) line = tbl.py_singular + ".__init__(" lines.append(cg.indent(ndnt, line)) ndnt += 1 flines = [] for column in tbl.columns: line = column.py_name + "=fields['" line += column.name + "']," flines.append(cg.indent(ndnt, line)) last = flines.pop() last = last[:-1] last += ")" flines.append(last) lines += flines ndnt -= 1 lines.append("") return lines
def instance(tbl, ndnt): ''' Generate the code for returning the instance of an object of type table. ''' lines = [] cls_prefix = tbl.cap_words_plural + "Table." line = "instance = None" lines.append(cg.indent(ndnt, line)) line = "@staticmethod" lines.append(cg.indent(ndnt, line)) line = "def get_instance():" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Instantiates (if it hasn't already) a singleton " line += cls_prefix lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "and returns it." lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "'''" lines.append(cg.indent(ndnt, line)) line = "if " + cls_prefix + "instance == None:" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = cls_prefix + "instance = " + tbl.cap_words_plural + "Table()" lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "return " + cls_prefix + "instance" lines.append(cg.indent(ndnt, line)) ndnt -= 1 lines.append("") return lines
def std_set_method(var_name, ndnt): ''' Generates a basic attribute setter method.''' lines = [] line = "def set_" + var_name + "(self, " + var_name + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Setter method for " + var_name + ".'''" lines.append(cg.indent(ndnt, line)) line = "self._" + var_name + " = " + var_name lines.append(cg.indent(ndnt, line)) ndnt -= 1 return lines
def std_property(var_name, ndnt): ''' Generates a basic attribute property.''' lines = [] line = var_name + " = property(get_" + var_name line += ", set_" + var_name + ")" lines.append(cg.indent(ndnt, line)) lines.append('') return lines
def varbinary_set_field(ndnt, py_name): ''' Generates the lines of a set function of varbinary field py_name. ''' lines = [] line = "if isinstance(" + py_name + ", bytes):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "self._" + py_name + " = " + py_name lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "elif isinstance(" + py_name + ", bytearray):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "self._" + py_name + " = bytes(" + py_name + ")" lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "elif " + py_name + " != None:" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "out = 'type(' + str(type(" + py_name + ")) + ') not recognized'" lines.append(cg.indent(ndnt, line)) line = "raise TypeError(out)" lines.append(cg.indent(ndnt, line)) return lines
def bool_set_field(ndnt, py_name): ''' Generates the lines of a set function of boolean field py_name. ''' lines = [] line = "if " + py_name + " == 1 or " + py_name + " == True:" lines.append(cg.indent(ndnt, line)) line = "self._" + py_name + " = True" lines.append(cg.indent(ndnt + 1, line)) line = "elif " + py_name + " == 0 or " + py_name + " == False:" lines.append(cg.indent(ndnt, line)) line = "self._" + py_name + " = False" lines.append(cg.indent(ndnt + 1, line)) line = "elif " + py_name + " != None:" lines.append(cg.indent(ndnt, line)) line = "msg = 'bool, 0, or 1 required in " + py_name + "\\n'" lines.append(cg.indent(ndnt + 1, line)) line = "msg += 'received: ' + str(" + py_name + ")" lines.append(cg.indent(ndnt + 1, line)) line = "raise TypeError(msg)" lines.append(cg.indent(ndnt + 1, line)) return lines
def get_fields(tbl, ndnt): ''' Generate the code for returning the fields of an object of type table. ''' lines = [] line = "@staticmethod" lines.append(cg.indent(ndnt, line)) line = "def get_fields(" + tbl.py_singular + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "'''Get a dictionary of fields populated from " \ + tbl.py_singular + "'''" lines.append(cg.indent(ndnt, line)) lines.append(cg.indent(ndnt, 'fields = {}')) for column in tbl.columns: # LOG.debug("column: " + str(column)) line = 'fields["' + column.name + '"] = ' line += tbl.py_singular + '.' + column.py_name lines.append(cg.indent(ndnt, line)) line = 'return fields' lines.append(cg.indent(ndnt, line)) lines.append("") return lines
def generate_table(self, tbl): """ Generate the table code for the table tbl. """ tbl.columns.sort(key=lambda x: x.ordinal_position) # misc.log_list(tbl.columns) lines = [] ndnt = 0 line = "''' " + tbl.schema.module_name + "." line += tbl.py_plural + "_table." + tbl.cap_words_plural line += "Table implements the" lines.append(line) line = " Flyweight pattern which handles caching." lines.append(line) line = "'''" lines.append(line) lines += self.code_gen.header_lines[:] # Imports line = "from " + cg.MODELS_PKG + "." line += tbl.schema.module_name + "." line += tbl.py_singular + " import " + tbl.cap_words_singular lines.append(line) if tbl.supertype_name != None and tbl.supertype != None: line = "from " + cg.MODELS_PKG + "." line += tbl.supertype.schema.py_name line += " import " + tbl.supertype.py_plural + "_table" lines.append(line) else: line = "from " + cg.FRAMEWORK_BASE + ".dal import table" lines.append(line) lines.append("") # Class def line = "class " + tbl.cap_words_plural + "Table(" if tbl.supertype_name != None and tbl.supertype != None: line += tbl.supertype.py_plural + "_table" line += "." line += tbl.supertype.cap_words_plural + "Table" else: line += "table.Table" line += "):" lines.append(line) ndnt += 1 line = "''' " + tbl.cap_words_plural + "Table holds exactly one copy of " line += "each row queried from the" lines.append(cg.indent(ndnt, line)) line = " " + tbl.name + " table.'''" lines.append(cg.indent(ndnt, line)) lines.append("") fqtn = "[" + tbl.schema_name + "].[" + tbl.name + "]" line = 'table_name = "' + fqtn + '"' lines.append(cg.indent(ndnt, line)) line = TableGenerator.add_columns(tbl) lines.append(cg.indent(ndnt, line)) if tbl.supertype_name != None and tbl.supertype != None: line = 'super_key = [' super_key = tbl.supertype.primary_key for ukc in super_key.unique_key_columns: line += '"' line += ukc.column.name line += '", ' line = line[:-2] line += "]" lines.append(cg.indent(ndnt, line)) line = "_attributes = [" for column in tbl.columns: line += "'" line += column.py_name line += "', " line = line[:-2] line += "]" lines.append(cg.indent(ndnt, line)) line = "_template_class = " + tbl.cap_words_singular lines.append(cg.indent(ndnt, line)) unique_keys = table_logic.unique_keys_minus_super(tbl) unique_key_logic.sort(unique_keys) # misc.log_list(logging.DEBUG, unique_keys) line = "_template_keys = [" if len(unique_keys) > 0: if len(unique_keys) > 1: lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "" for key in unique_keys: line += "(" for key_column in key.unique_key_columns: line += "'" + key_column.column.py_name + "', " line = line[:-1] + ")," lines.append(cg.indent(ndnt, line)) line = "" line = lines.pop() line = line[:-1] + "]" lines.append(line) if len(unique_keys) > 1: ndnt -= 1 else: line += "]" lines.append(cg.indent(ndnt, line)) lines.append("") lines += TableGenerator.instance(tbl, ndnt) lines += TableGenerator.get_fields(tbl, ndnt) lines += TableGenerator.set_fields(tbl, ndnt) line = "def __init__(self):" lines.append(cg.indent(ndnt, line)) ndnt += 1 fw_name = tbl.cap_words_plural + "Table" line = "super(" + fw_name + ", self).__init__()" lines.append(cg.indent(ndnt, line)) line = "self.attributes = " + fw_name + "._attributes" lines.append(cg.indent(ndnt, line)) line = "self.template_class = " + fw_name + "._template_class" lines.append(cg.indent(ndnt, line)) line = "self.template_keys = " + fw_name + "._template_keys" lines.append(cg.indent(ndnt, line)) by_key = None if len(unique_keys) > 0: # dictionaries for key in unique_keys: line = "self._by_" + key.postfix + " = {}" lines.append(cg.indent(ndnt, line)) line = "self.key_dict[(" for key_column in key.unique_key_columns: line += "'" + key_column.column.py_name + "', " line = line[:-1] + ")] = self." line += "get_by_" + key.postfix lines.append(cg.indent(ndnt, line)) by_key = unique_keys[0] if tbl.supertype_name != None and tbl.supertype != None: if tbl.primary_key_name != None: tbl.primary_key.postfix \ = unique_key_logic.cat_column_names(tbl.primary_key) by_key = tbl.primary_key if by_key != None: line = "self.by_key = self._by_" + by_key.postfix else: line = "self.by_key = {}" lines.append(cg.indent(ndnt, line)) ndnt -= 1 lines.append("") # add_dict_entry tbl.py_singular = tbl.py_singular line = "def add_dict_entry(self, " + tbl.py_singular + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Add an entry to the table and all indexes.'''" lines.append(cg.indent(ndnt, line)) if tbl.supertype_name != None and tbl.supertype != None: line = "super(" + tbl.cap_words_plural line += "Table, self).add_dict_entry(" line += tbl.py_singular + ")" lines.append(cg.indent(ndnt, line)) line = "# LOG.debug('adding: ' + str(" + tbl.py_singular + "))" lines.append(cg.indent(ndnt, line)) if len(unique_keys) > 0: for key in unique_keys: if len(key.unique_key_columns) == 1: column = key.unique_key_columns[0].column line = "self._by_" + key.postfix line += "[" + tbl.py_singular + "." line += column.py_name + "] = " + tbl.py_singular lines.append(cg.indent(ndnt, line)) else: line = TableGenerator.get_idx_line(key) lines.append(cg.indent(ndnt, line)) line = "self._by_" + key.postfix line += "[idx] = " + tbl.py_singular lines.append(cg.indent(ndnt, line)) else: line = "pass" lines.append(cg.indent(ndnt, line)) ndnt -= 1 lines.append("") # del_dict_entry line = "def del_dict_entry(self, " + tbl.py_singular + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Delete an entry from the table and all indexes.'''" lines.append(cg.indent(ndnt, line)) if tbl.supertype_name != None and tbl.supertype != None: line = "super(" + tbl.cap_words_plural line += "Table, self).del_dict_entry(" + tbl.py_singular + ")" lines.append(cg.indent(ndnt, line)) line = "# LOG.debug('deleting: ' + str(" + tbl.py_singular + "))" lines.append(cg.indent(ndnt, line)) if len(unique_keys) > 0: for key in unique_keys: if len(key.unique_key_columns) == 1: column = key.unique_key_columns[0].column line = "del self._by_" + key.postfix line += "[" + tbl.py_singular + "." line += column.py_name + "]" lines.append(cg.indent(ndnt, line)) else: line = TableGenerator.get_idx_line(key) lines.append(cg.indent(ndnt, line)) line = "del self._by_" + key.postfix + "[idx]" lines.append(cg.indent(ndnt, line)) else: line = "pass" lines.append(cg.indent(ndnt, line)) ndnt -= 1 lines.append("") # LOG.debug('unique_keys: ' + str(unique_keys)) if len(unique_keys) > 0: # get_by for key in unique_keys: # LOG.debug('key: ' + str(key)) key.params = TableGenerator.get_params(key) line = "def get_by_" + key.postfix line += "(self, " + key.params + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Lookup up a record with the unique key" line += " defined by" lines.append(cg.indent(ndnt, line)) line = " " + key.params + "." lines.append(cg.indent(ndnt, line)) line = "'''" lines.append(cg.indent(ndnt, line)) line = "rtn = None" lines.append(cg.indent(ndnt, line)) if len(key.unique_key_columns) == 1: idx = key.params else: idx = "idx" line = "idx = " + key.params lines.append(cg.indent(ndnt, line)) line = "if " + idx + " in self._by_" + key.postfix + ":" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "# LOG.debug(str(" + idx + ") + ' found')" lines.append(cg.indent(ndnt, line)) line = "rtn = self._by_" + key.postfix line += "[" + idx + "]" lines.append(cg.indent(ndnt, line)) ndnt -= 1 lines.append(cg.indent(ndnt, "else:")) ndnt += 1 line = "# LOG.debug(str(" + idx + ") + ' loading...')" lines.append(cg.indent(ndnt, line)) line = "rtn = self.load_one(" if len(key.unique_key_columns) > 1: lines.append(cg.indent(ndnt, line)) line = "" ndnt += 1 for key_col in key.unique_key_columns: column = key_col.column line += column.py_name + "=" line += column.py_name + "," lines.append(cg.indent(ndnt, line)) line = "" if len(key.unique_key_columns) > 1: ndnt -= 1 line = lines.pop() line = line[:-1] + ")" lines.append(line) ndnt -= 1 line = "return rtn" lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "by_" + key.postfix line += " = property(get_by_" + key.postfix + ")" lines.append(cg.indent(ndnt, line)) lines.append("") ndnt -= 1 lines.append("") return lines
def generate_template(self, tbl): ''' Generate the template, which consists of some very basic code like getters and setters. ''' # LOG.debug("tbl: " + str(tbl)) tbl.columns.sort(key=lambda x: x.ordinal_position) # misc.log_list(tbl.columns) columns = table_logic.columns_minus_super(tbl) # misc.log_list(columns) foreign_keys = table_logic.foreign_keys_minus_super(tbl) foreign_keys.sort(key=lambda x: x.one_name) # misc.log_list(foreign_keys) # Set referencing foreign keys ref_keys = [] # LOG.debug('tbl: ' + str(tbl)) for key in tbl.unique_keys: # Remove supertype keys for ref_key in key.foreign_keys: # LOG.debug('ref_key: ' + str(ref_key)) if ref_key.table.supertype_name != None: # LOG.debug('supertype_name: ' # + ref_key.table.supertype_name) if ref_key.table.supertype != None: if ref_key.table.supertype. \ primary_key_name != tbl.primary_key_name: ref_keys.append(ref_key) else: LOG.debug('removed: ' + str(ref_key)) else: LOG.warning("supertype == None (" + ref_key.table.supertype_name + ")") else: ref_keys.append(ref_key) ref_keys.sort(key=lambda x: x.many_name) lines = [] ndnt = 0 line = "''' " + tbl.schema.module_name + "." line += tbl.py_singular + " can be thought of as a bean " line += "or a template. It" lines.append(line) line = " has only attributes with getters and setters." lines.append(line) line = "'''" lines.append(line) lines += self.code_gen.header_lines[:] # Imports importing = False if tbl.supertype_name != None and tbl.supertype != None: line = "from " + cg.MODELS_PKG + "." line += tbl.supertype.schema.py_name line += " import " + tbl.supertype.py_singular lines.append(line) importing = True for column in columns: if column.sql_type == None: continue if importing: lines.append("") # Class def line = "class " + tbl.cap_words_singular + "(" if tbl.supertype_name != None and tbl.supertype != None: line += tbl.supertype.py_singular line += "." line += tbl.supertype.cap_words_singular else: line += "object" line += "):" lines.append(line) ndnt += 1 line = "'''" + tbl.cap_words_singular + " class generated from " line += tbl.name + " table.'''" lines.append(cg.indent(ndnt, line)) # __init__ line = 'def __init__(self, ' # build init params params = [] # Add inheritance to constuctor args if tbl.supertype_name != None and tbl.supertype != None: tbl.supertype.columns.sort(key=lambda x: x.ordinal_position) for column in tbl.supertype.columns: col = copy.copy(column) params.append(col) # Our args override for column in columns: matches = [x for x in params if x.py_name == column.py_name] for dup in matches: dup.py_name = "super_" + dup.py_name params.append(column) for column in params: append = column.py_name + "=None, " line += append line = line[:-2] line += "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 # Call super class constructors if tbl.supertype_name != None and tbl.supertype != None: line = "super(" + tbl.cap_words_singular + ", self).__init__(" for column in tbl.supertype.columns: name = column.py_name matches = [x for x in columns if x.py_name == column.py_name] for dup in matches: name = "super_" + dup.py_name line += name + ", " line = line[:-2] line += ")" lines.append(cg.indent(ndnt, line)) # Set variables # misc.log_list(columns) for column in columns: # LOG.debug('column: ' + str(column)) if column.sql_type == None: continue if column.sql_type.python_type_name == 'bool' \ or column.sql_type.python_type_name == 'varbinary': line = 'self._' + column.py_name + " = None" lines.append(cg.indent(ndnt, line)) line = 'self.' + column.py_name + " = " + column.py_name lines.append(cg.indent(ndnt, line)) else: line = 'self.' + column.py_name + " = " + column.py_name lines.append(cg.indent(ndnt, line)) # Foreign keys for f_key in foreign_keys: line = "self._" + f_key.one_name + " = None" lines.append(cg.indent(ndnt, line)) # Referenced by for ref_key in ref_keys: line = "self._" + ref_key.many_name + " = None" lines.append(cg.indent(ndnt, line)) lines.append('') ndnt -= 1 # __str__ line = 'def __str__(self):' lines.append(cg.indent(ndnt, line)) ndnt += 1 if tbl.supertype_name != None and tbl.supertype != None: line = "out = super(" + tbl.cap_words_singular line += ", self).__str__() + ' == '" lines.append(cg.indent(ndnt, line)) line = "out += '" + tbl.cap_words_singular + "(" else: line = "out = '" + tbl.cap_words_singular + "(" if len(columns) > 0: line += "'" lines.append(cg.indent(ndnt, line)) for column in columns: line = "if self." + column.py_name + " != None:" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "out += '" + column.py_name + ":' + str(self." line += column.py_name + ") + ','" lines.append(cg.indent(ndnt, line)) ndnt -= 1 ndnt += 1 lines.pop() line = line[:-6] lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "if out[-1:] == ',':" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "out = out[:-1]" lines.append(cg.indent(ndnt, line)) ndnt -= 1 line = "out += ')'" lines.append(cg.indent(ndnt, line)) else: line += ")'" lines.append(cg.indent(ndnt, line)) line = "return out" lines.append(cg.indent(ndnt, line)) ndnt -= 1 lines.append('') for column in columns: if column.sql_type == None: continue if column.sql_type.python_type_name == 'bool': # get method lines += std_get_method(column.py_name, ndnt) # set method line = "def set_" + column.py_name + "(self, " line += column.py_name + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Setter method for " + column.py_name line += ".'''" lines.append(cg.indent(ndnt, line)) lines += bool_set_field(ndnt, column.py_name) ndnt -= 1 # property lines += std_property(column.py_name, ndnt) elif column.sql_type.python_type_name == 'varbinary': # get method lines += std_get_method(column.py_name, ndnt) # set method line = "def set_" + column.py_name + "(self, " line += column.py_name + "):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Setter method for " + column.py_name line += ".'''" lines.append(cg.indent(ndnt, line)) lines += varbinary_set_field(ndnt, column.py_name) ndnt -= 1 # property lines += std_property(column.py_name, ndnt) for f_key in foreign_keys: if f_key.ref_uk_obj != None: f_key.foreign_key_columns.sort(key=lambda x: \ x.fk_column_obj.ordinal_position) # get method line = "def get_" + f_key.one_name + "(self):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Getter method for " + f_key.one_name + ".'''" lines.append(cg.indent(ndnt, line)) line = "if " for fkc in f_key.foreign_key_columns: line += "self." line += fkc.fk_column_obj.py_name line += " != None and " line += "self._" + f_key.one_name + " == None:" lines.append(cg.indent(ndnt, line)) ndnt += 1 table = f_key.ref_uk_obj.table.py_plural + "_table" table_class = f_key.ref_uk_obj.table.cap_words_plural \ + "Table" schm = f_key.ref_uk_obj.schema.module_name line = "from " + cg.MODELS_PKG + "." line += schm + " import " + table lines.append(cg.indent(ndnt, line)) line = "self._" + f_key.one_name + " = " + table \ + "." + table_class + ".get_instance() \\" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = ".get_one(" for fkc in f_key.foreign_key_columns: # LOG.debug('fkc: ' + str(fkc)) line += fkc.uk_column_obj.py_name line += "=self." line += fkc.fk_column_obj.py_name line += ", " line = line[:-2] line += ')' lines.append(cg.indent(ndnt, line)) ndnt -= 2 line = "return self._" + f_key.one_name lines.append(cg.indent(ndnt, line)) ndnt -= 1 # setter, property lines += std_set_method(f_key.one_name, ndnt) lines += std_property(f_key.one_name, ndnt) else: LOG.warning('Referenced unique key not detected for ' + str(f_key) + '. skipping.') for ref_key in ref_keys: ref_key.foreign_key_columns.sort(key=lambda x: \ x.fk_column_obj.ordinal_position) var_name = ref_key.many_name # get method line = "def get_" + var_name + "(self):" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = "''' Getter method for " + var_name + ".'''" lines.append(cg.indent(ndnt, line)) line = "if " for fkc in ref_key.foreign_key_columns: line += "self." + fkc.uk_column_obj.py_name line += " != None and " line += "self._" + var_name + " == None:" lines.append(cg.indent(ndnt, line)) ndnt += 1 table = ref_key.table.py_plural + "_table" table_class = ref_key.table.cap_words_plural \ + "Table" schm = ref_key.schema.module_name line = "from " + cg.MODELS_PKG + "." line += schm + " import " + table lines.append(cg.indent(ndnt, line)) line = "self._" + var_name + " = " + table \ + "." + table_class + ".get_instance() \\" lines.append(cg.indent(ndnt, line)) ndnt += 1 line = ".get(" for fkc in ref_key.foreign_key_columns: # LOG.debug('fkc: ' + str(fkc)) line += fkc.fk_column_obj.py_name line += "=self." + fkc.uk_column_obj.py_name + ", " line = line[:-2] line += ')' lines.append(cg.indent(ndnt, line)) ndnt -= 2 line = "return self._" + var_name lines.append(cg.indent(ndnt, line)) ndnt -= 1 # setter, property lines += std_set_method(var_name, ndnt) lines += std_property(var_name, ndnt) ndnt -= 1 lines.append("") return lines