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
    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
Esempio n. 3
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
    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":
            #     schema.fulltext_engine = av
            # elif an.lower() == "version":
            #     schema.version = av
            # elif an.lower() == "name":
            #     schema.name = av
            # elif an.lower() == "description":
            #     schema.description = av
            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
Esempio n. 5
0
    def fetch_domains(self):
        cursor = self.connection.cursor()

        domain_list = list()
        domain_attributes = cursor.execute("""\
        select name, description, data_type_id, align, width, length, precision, show_null, summable, case_sensitive, \
        show_lead_nulls, thousands_separator, char_length, scale from dbd$domains"""
                                           ).fetchall()
        for attr_tuple in domain_attributes:
            domain = Dbc.Domain()
            domain.name, domain.description, domain.type, domain.align, domain.width, domain.length, \
                domain.precision, domain.show_null, domain.summable, domain.case_sensitive, domain.show_lead_nulls, \
                domain.thousands_separator, domain.char_length, domain.scale = attr_tuple

            domain.show_null, domain.show_lead_nulls, domain.thousands_separator, domain.summable, \
                domain.case_sensitive = map(bool, [domain.show_null, domain.show_lead_nulls, domain.thousands_separator,
                                                   domain.summable, domain.case_sensitive])

            # domain.char_length, domain.length, domain.scale, domain.precision, domain.width = \
            #     map(str, [domain.char_length, domain.length, domain.scale, domain.precision, domain.width])

            domain.char_length = str(
                domain.char_length) if domain.char_length else None
            domain.length = str(domain.length) if domain.length else None
            domain.scale = str(domain.scale) if domain.scale else None
            domain.precision = str(
                domain.precision) if domain.precision else None
            domain.width = str(domain.width) if domain.width else None

            domain.type = cursor.execute(
                """select type_id from dbd$data_types where dbd$data_types.id = ?""",
                (domain.type, )).fetchone()[0]
            domain_list.append(domain)

        return domain_list
    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
Esempio n. 7
0
    def fetch_constraints(self, table_id):
        cursor = self.connection.cursor()

        constraints_list = list()
        constraints_attributes = cursor.execute(
            """\
        select id, table_id, name, constraint_type, reference, unique_key_id, has_value_edit, cascading_delete, expression\
        from dbd$constraints\
        where dbd$constraints.table_id = ?""", (table_id, )).fetchall()
        for attr_tuple in constraints_attributes:
            constraint = Dbc.Constraint()
            _, tbl_id, constraint.name, constraint.kind, constraint.reference, constraint.unique_key_id, \
                constraint.has_value_edit, constraint.cascading_delete, constraint.expression = attr_tuple
            constraint.has_value_edit, constraint.cascading_delete = map(
                bool, [constraint.has_value_edit, constraint.cascading_delete])

            constraint.items = cursor.execute(
                """\
                        select name from dbd$fields\
                        where dbd$fields.id = (\
                        select field_id from dbd$constraint_details\
                        where dbd$constraint_details.constraint_id = ?)""",
                (attr_tuple[0], )).fetchone()[0]

            constraint.reference = None if constraint.kind == "PRIMARY" else cursor.execute(
                """\
            select name from dbd$tables where dbd$tables.id = ?""",
                (constraint.reference, )).fetchone()[0]
            constraints_list.append(constraint)

        return constraints_list
    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
    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
    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
Esempio n. 11
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":
                        #     const.full_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
Esempio n. 12
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":
                #     tbl.ht_table_flags = av
                # elif an.lower() == "access_level":
                #     tbl.access_level = av
                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
Esempio n. 13
0
    def fetch_schema(self):
        schema = Dbc.Schema()
        cursor = self.connection.cursor()

        # sid, name = cursor.execute("""select id, name from dbd$schemas where name = ?""",
        #                            (self.schema_name,)).fetchone()
        # if name is None:
        #     raise SchemaNameError("Can't find schema with {} name".format(self.schema_name))
        # else:
        #     schema.name = name
        schema.domains = self.fetch_domains()
        schema.tables = self.fetch_tables()
        self.connection.commit()
        self.connection.close()
        return schema
Esempio n. 14
0
    def fetch_tables(self):
        cursor = self.connection.cursor()

        tables_list = list()
        tables_attributes = cursor.execute("""\
        select id, name, description, can_add, can_edit, can_delete, temporal_mode, means from dbd$tables"""
                                           ).fetchall()
        for attr_tuple in tables_attributes:
            table = Dbc.Table()
            tid, table.name, table.description, table.add, table.edit, table.delete, table.temporal_mode, \
                table.means = attr_tuple
            table.add, table.edit, table.delete = map(
                bool, [table.add, table.edit, table.delete])
            table.fields = self.fetch_fields(tid)
            table.constraints = self.fetch_constraints(tid)
            table.indices = self.fetch_indices(tid)
            tables_list.append(table)

        return tables_list
Esempio n. 15
0
    def fetch_fields(self, table_id):
        cursor = self.connection.cursor()

        field_list = list()
        filed_attributes = cursor.execute(
            """\
        select name, russian_short_name, description, domain_id, can_input, can_edit, \
        show_in_grid, show_in_details, is_mean, autocalculated, required from dbd$fields\
        where dbd$fields.table_id = ?""", (table_id, )).fetchall()
        for attr_tuple in filed_attributes:
            field = Dbc.Field()
            field.name, field.rname, field.description, field.domain, field.input, field.edit, \
                field.show_in_grid, field.show_in_details, field.is_mean, field.autocalculated, \
                field.required = attr_tuple
            field.input, field.edit, field.show_in_grid, field.show_in_details, field.is_mean, field.autocalculated, \
                field.required = map(bool, [field.input, field.edit, field.show_in_grid, field.show_in_details,
                                            field.is_mean, field.autocalculated, field.required])
            field.domain = cursor.execute(
                """select name from dbd$domains where dbd$domains.id = ?""",
                (field.domain, )).fetchone()[0]
            field_list.append(field)

        return field_list
Esempio n. 16
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
    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