예제 #1
0
    def fetch_fields(self, table_name, schema):
        cursor = self.connection.cursor()

        field_list = list()
        fields = cursor.execute("""
        select 
            COLUMN_NAME as name, 
            t.name as dom,
            ORDINAL_POSITION as position, 
            sc.is_identity as edit,
            sc.is_hidden as show_in_grid,
            sc.is_computed as autocalculated,
            sc.is_nullable as required,
            col.DATA_TYPE,
            sc.scale,
            sc.precision,
            sc.max_length
        from INFORMATION_SCHEMA.TABLES as tbl
        left join INFORMATION_SCHEMA.COLUMNS as col
        on col.TABLE_NAME = tbl.TABLE_NAME
        left join sys.columns as sc
        on sc.object_id = object_id(tbl.table_schema + '.' + tbl.table_name) and sc.NAME = col.COLUMN_NAME
        left join sys.types as t
        on col.DATA_TYPE = t.name
        where tbl.TABLE_NAME = ?;""", (table_name,)).fetchall()

        # НЕ РАБОТАЕТ (SQL type - 150 not supported yet)
        # prop.value as descript,
        # left join sys.extended_properties prop
        # on prop.major_id = sc.object_id and prop.minor_id = sc.column_id and prop.NAME = 'MS_Description'

        domain_list = list()
        for fld in fields:
            field = Dbc.Field()
            field.name = fld[0]
            field.domain = fld[1]
            field.position = str(fld[2])
            field.edit = fld[3]
            field.show_in_grid = fld[4]
            field.autocalculated = fld[5]
            field.required = fld[6]
            field.input = not(field.autocalculated or field.edit)
            domain = Dbc.Domain()
            domain.char_length = str(fld[10])
            domain.precision = str(fld[9])
            domain.scale = str(fld[8])
            domain.type = TYPES[fld[7]]
            domain_list.append(domain)

            field.domain = domain
            field_list.append(field)
        # schema.domains += domain_list
        return field_list
예제 #2
0
    def fetch_indices(self, table_id):
        cursor = self.connection.cursor()

        indices_list = list()
        indices_attributes = cursor.execute(
            """\
        select id, name, local, kind\
        from dbd$indices\
        where dbd$indices.table_id = ?""", (table_id, )).fetchall()
        for attr_tuple in indices_attributes:
            index = Dbc.Index()
            if attr_tuple[3] == "fulltext":
                index.fulltext, index.uniqueness = True, False
            elif attr_tuple[3] == "uniqueness":
                index.fulltext, index.uniqueness = False, True
            else:
                index.fulltext, index.uniqueness = False, False
            index.name, index.local = attr_tuple[1:-1]
            index.field = cursor.execute(
                """\
            select name from dbd$fields \
            where dbd$fields.id = (\
            select field_id from dbd$index_details\
            where dbd$index_details.index_id = ?)""",
                (attr_tuple[0], )).fetchone()[0]
            indices_list.append(index)

        return indices_list
예제 #3
0
    def fetch_indices(self, schema_name, table_name):
        cursor = self.connection.cursor()

        indices_list = list()
        indices = cursor.execute("""
        select 
            ind.name as index_name, 
            ind.is_unique, 
            fti.object_id as is_fulltext, 
            c.name as field_name
        from sys.indexes as ind
        left join sys.fulltext_indexes as fti
        on ind.object_id = fti.object_id
        join sys.index_columns as ic
        on ind.object_id = ic.object_id and ind.index_id = ic.index_id
        join sys.columns as c
        on ind.object_id = c.object_id and ic.column_id = c.column_id
        where ind.object_id = OBJECT_ID(?);""",
                                 ("{schema_name}.{table_name}".format(schema_name=schema_name,
                                                                      table_name=table_name),)).fetchall()
        for ind in indices:
            index = Dbc.Index()
            index.name = ind[0]
            index.uniqueness = ind[1]
            index.fulltext = bool(ind[2])
            index.field = ind[3]
            indices_list.append(index)

        return indices_list
예제 #4
0
    def fetch_tables(self, schema):
        cursor = self.connection.cursor()

        tables_list = list()
        tables = cursor.execute("""
        select 
            t.name, 
            OBJECTPROPERTY(t.object_id, 'HasInsertTrigger') as addition, 
            OBJECTPROPERTY(t.object_id, 'HasUpdateTrigger') as edition, 
            t.temporal_type
        from sys.tables as t
        join sys.schemas as s
        on t.schema_id = s.schema_id
        where s.name = ?;""", (schema.name,)).fetchall()
        for tbl in tables:
            table = Dbc.Table()
            table.name = tbl[0]
            table.add = bool(tbl[1])
            table.edit = bool(tbl[2])
            table.temporal_mode = bool(tbl[3])
            table.indices = self.fetch_indices(schema.name, table.name)
            table.constraints = self.fetch_constraints(schema.name, table.name)
            table.fields = self.fetch_fields(table.name, schema)
            tables_list.append(table)

        return tables_list
예제 #5
0
    def get_indices(table):
        """
        :param      table: Dbc.Table() to find indices in.

        :return:    indices_list: list of indices in table.

        Parse table to find indices in.
        """
        if table.nodeName != "table":
            raise WrongNodeException("table", table.nodeName)

        indices_list = list()
        for index in table.getElementsByTagName("index"):
            idx = Dbc.Index()
            for an, av in index.attributes.items():
                if an.lower() == "name":
                    idx.name = av
                elif an.lower() == "field":
                    idx.field = av
                elif an.lower() == "props":
                    for prop in av.split(", "):
                        if prop == "fulltext":
                            idx.fulltext = True
                        elif prop == "uniqueness":
                            idx.uniqueness = True
                        elif prop == "local":
                            idx.local = True
                        else:
                            raise WrongPropertyException(["fulltext", "uniqueness", "local"], prop)
                else:
                    raise WrongAttributeException(["field", "name", "props"], an)
            indices_list.append(idx)

        return indices_list
예제 #6
0
    def fetch_schema(self):
        schema = Dbc.Schema()
        schema.name = "dbo"

        schema.tables = self.fetch_tables(schema)

        # rsd = list()
        # for domain in schema.domains:
        #     if all([domain != dom for dom in rsd]):
        #         rsd.append(domain)
        # schema.domains = rsd

        return schema
예제 #7
0
    def get_domains(self):
        """
        :return:    domain_list: list of domains.

        Parse an xml file to find domains in.
        """
        domain_list = list()
        for domain in self.xml_repr.getElementsByTagName("domain"):
            dom = Dbc.Domain()
            for an, av in domain.attributes.items():
                if an.lower() == "name":
                    dom.name = av
                elif an.lower() == "description":
                    dom.description = av
                elif an.lower() == "type":
                    dom.type = av
                elif an.lower() == "align":
                    dom.align = av
                elif an.lower() == "width":
                    dom.width = av
                elif an.lower() == "props":
                    for prop in av.split(", "):
                        if prop == "show_null":
                            dom.show_null = True
                        elif prop == "summable":
                            dom.summable = True
                        elif prop == "case_sensitive":
                            dom.case_sensitive = True
                        elif prop == "show_lead_nulls":
                            dom.show_lead_nulls = True
                        elif prop == "thousand_separator":
                            dom.thousands_separator = True
                        else:
                            raise WrongPropertyException(
                                ["show_null", "summable", "case_sensitive", "show_lead_nulls", "thousands_separator"],
                                prop)
                elif an.lower() == "char_length":
                    dom.char_length = av
                elif an.lower() == "length":
                    dom.length = av
                elif an.lower() == "precision":
                    dom.precision = av
                elif an.lower() == "scale":
                    dom.scale = av
                else:
                    raise WrongAttributeException(
                        ["props", "scale", "length", "char_length", "precision", "width", "align",
                         "type", "description", "name"], an)
            domain_list.append(dom)

        return domain_list
예제 #8
0
    def get_fields(table):
        """
        :param      table: Dbc.Table() to find fields in.

        :return:    fields_list: list of fields in table.

        Parse table to find fields.
        """
        if table.nodeName != "table":
            raise WrongNodeException("table", table.nodeName)

        fields_list = list()
        pos = 1
        for field in table.getElementsByTagName("field"):
            fld = Dbc.Field()
            fld.position = str(pos)
            for an, av in field.attributes.items():
                if an.lower() == "name":
                    fld.name = av
                elif an.lower() == "rname":
                    fld.rname = av
                elif an.lower() == "domain":
                    fld.domain = av
                elif an.lower() == "description":
                    fld.description = av
                elif an.lower() == "props":
                    for prop in av.split(", "):
                        if prop == "input":
                            fld.input = True
                        elif prop == "edit":
                            fld.edit = True
                        elif prop == "show_in_grid":
                            fld.show_in_grid = True
                        elif prop == "show_in_details":
                            fld.show_in_details = True
                        elif prop == "autocalculated":
                            fld.autocalculated = True
                        elif prop == "is_mean":
                            fld.is_mean = True
                        elif prop == "required":
                            fld.required = True
                        else:
                            raise WrongPropertyException(["input", "edit", "show_in_grid",
                                                          "show_in_details", "is_mean", "autocalculated", "required"],
                                                         prop)
                else:
                    raise WrongAttributeException(["name", "rname", "position", "domain", "description", "props"], an)
            pos += 1
            fields_list.append(fld)

        return fields_list
예제 #9
0
    def get_constraints(table):
        """
        :param      table: Dbc.Table() to find constraints in.

        :return:    constraints_list: list of constraints in table.

        Parse table to find constraints.
        """
        if table.nodeName != "table":
            raise WrongNodeException("table", table.nodeName)

        constraints_list = list()
        for constraint in table.getElementsByTagName("constraint"):
            const = Dbc.Constraint()
            for an, av in constraint.attributes.items():
                if an.lower() == "name":
                    const.name = av
                elif an.lower() == "kind":
                    const.kind = av
                elif an.lower() == "items":
                    const.items = av
                elif an.lower() == "unique_key_id":
                    const.unique_key_id = av
                elif an.lower() == "reference":
                    const.reference = av
                elif an.lower() == "expression":
                    const.expression = av
                elif an.lower() == "props":
                    for prop in av.split(", "):
                        if prop == "has_value_edit":
                            const.has_value_edit = True
                        elif prop == "cascading_delete":
                            const.cascading_delete = True
                        elif prop == "full_cascading_delete":
                            pass
                        else:
                            raise WrongPropertyException(
                                ["has_value_edit", "cascading_delete", "full_cascading_delete"], prop)
                else:
                    raise WrongAttributeException(["name", "constraint_type", "unique_key_id", "expression" "kind",
                                                   "items", "reference_type", "reference", "props"], an)
            constraints_list.append(const)

        return constraints_list
예제 #10
0
    def get_tables(self):
        """
        :return:    tables_list: list of tables in xml file.

        Parse a xml file to find tables.
        """
        tables_list = list()
        for table in self.xml_repr.getElementsByTagName("table"):
            tbl = Dbc.Table()
            for an, av in table.attributes.items():
                if an.lower() == "name":
                    tbl.name = av
                elif an.lower() == "description":
                    tbl.description = av
                elif an.lower() == "props":
                    for prop in av.split(", "):
                        if prop == "add":
                            tbl.add = True
                        elif prop == "edit":
                            tbl.edit = True
                        elif prop == "delete":
                            tbl.delete = True
                        elif prop == "temporal_mode":
                            tbl.temporal_mode = True
                        else:
                            raise WrongPropertyException(["delete", "temporal_mode", "edit", "add"], prop)
                elif an.lower() == "ht_table_flags":
                    pass
                elif an.lower() == "access_level":
                    pass
                elif an.lower() == "means":
                    tbl.means = av
                else:
                    raise WrongAttributeException(["props", "access_level", "ht_table_flags", "description", "name"],
                                                  an)
            tbl.fields = self.get_fields(table)
            tbl.indices = self.get_indices(table)
            tbl.constraints = self.get_constraints(table)
            tables_list.append(tbl)

        return tables_list
예제 #11
0
    def get_schema(self):
        """
        :return:    schema: Dbc.Schema() of data base.

        Parse a xml file to obtain schema.
        """
        schema = Dbc.Schema()

        for an, av in self.xml_repr.documentElement.attributes.items():
            if an.lower() == "fulltext_engine":
                pass
            elif an.lower() == "version":
                pass
            elif an.lower() == "name":
                schema.name = av
            elif an.lower() == "description":
                pass
            else:
                raise WrongAttributeException(["fulltext_engine", "version", "name", "description"], an)
        schema.domains = self.domain_list
        schema.tables = self.tables_list

        return schema
예제 #12
0
    def fetch_constraints(self, schema_name, table_name):
        cursor = self.connection.cursor()

        get_primary_keys = cursor.execute("""
        select 
            kc.name, 
            KCU.COLUMN_NAME as items, 
            kc.unique_index_id as unique_key_index
        from sys.tables as t
        join sys.key_constraints as kc
        on t.object_id = kc.parent_object_id
        join INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
        on KCU.CONSTRAINT_NAME = kc.name
        where t.object_id = object_id(?);""", (".".join([schema_name, table_name]))).fetchall()
        primary_keys = list()
        if get_primary_keys:
            for key in get_primary_keys:
                constraint = Dbc.Constraint()
                constraint.name = key[0]
                constraint.kind = "PRIMARY"
                constraint.items = key[1]
                constraint.unique_key_id = str(key[2])
                primary_keys.append(constraint)

        get_foreign_keys = cursor.execute("""
        select 
            fk.name, 
            ac.name, 
            tt.name, 
            fk.delete_referential_action
        from sys.tables as t
        join sys.all_columns as ac
        on t.object_id = ac.object_id
        join sys.foreign_key_columns as fkc
        on ac.column_id = fkc.parent_column_id and t.object_id = fkc.parent_object_id
        join sys.foreign_keys as fk
        on fkc.constraint_object_id = fk.object_id
        join sys.tables as tt
        on tt.object_id = fk.referenced_object_id
        where t.object_id = object_id(?);""", (".".join([schema_name, table_name]))).fetchall()
        foreign_keys = list()
        if get_foreign_keys:
            for key in get_foreign_keys:
                constraint = Dbc.Constraint()
                constraint.name = key[0]
                constraint.kind = "FOREIGN"
                constraint.items = key[1]
                constraint.reference = key[2]
                constraint.cascading_delete = bool(key[3])
                foreign_keys.append(constraint)

        get_check_constraints = cursor.execute("""
        select 
            cc.name, 
            ac.name as items, 
            cc.definition as expression
        from sys.tables as t
        join sys.all_columns as ac
        on t.object_id = ac.object_id
        join sys.check_constraints as cc
        on ac.column_id = cc.parent_column_id and t.object_id = cc.parent_object_id
        where t.object_id = object_id(?);""", (".".join([schema_name, table_name]))).fetchall()
        check_constraints = list()
        if get_check_constraints:
            for key in get_check_constraints:
                constraint = Dbc.Constraint()
                constraint.name = key[0]
                constraint.kind = "CHECK"
                constraint.items = key[1]
                constraint.expression = key[2]
                check_constraints.append(constraint)

        return primary_keys + foreign_keys + check_constraints