Example #1
0
    def runTest(self, template_mock):
        template_mock.return_value = 'Some SQL'
        connection = Mock()
        connection.execute_2darray.return_value = [
            True, {
                'rows': self.execute_return_values
            }
        ]

        reader = DataTypeReader()
        reader.manager = Mock()
        reader.manager.server_type = self.manager['server_type']
        reader.manager.version = self.manager['version']
        try:
            reader.data_type_template_path = self.data_type_template_path
        except AttributeError:
            ''
        result = reader.get_types(connection, self.sql_condition,
                                  self.add_serials, self.schema_oid)
        self.assertEqual(result[1], self.expected_function_output)
        self.assertTrue(result[0])

        connection.execute_2darray.assert_called_with('Some SQL')
        template_mock.assert_called_with(self.expected_sql_template_path +
                                         '/get_types.sql',
                                         condition=self.sql_condition,
                                         add_serials=self.add_serials,
                                         schema_oid=self.schema_oid)
Example #2
0
    def runTest(self, template_mock):
        template_mock.return_value = 'Some SQL'
        connection = Mock()
        connection.execute_2darray.return_value = [
            True,
            {
                'rows': self.execute_return_values

            }
        ]

        reader = DataTypeReader()
        reader.manager = Mock()
        reader.manager.server_type = self.manager['server_type']
        reader.manager.version = self.manager['version']
        try:
            reader.data_type_template_path = self.data_type_template_path
        except AttributeError:
            ''
        result = reader.get_types(connection, self.sql_condition,
                                  self.add_serials, self.schema_oid)
        self.assertEqual(result[1], self.expected_function_output)
        self.assertTrue(result[0])

        connection.execute_2darray.assert_called_with('Some SQL')
        template_mock.assert_called_with(
            self.expected_sql_template_path + '/get_types.sql',
            condition=self.sql_condition,
            add_serials=self.add_serials,
            schema_oid=self.schema_oid
        )
Example #3
0
def fetch_length_precision(data):
    """
    This function is used to fetch the length and precision.

    :param data:
    :return:
    """
    # Find length & precision of column data type
    fulltype = DataTypeReader.get_full_type(data['typnspname'],
                                            data['typname'], data['isdup'],
                                            data['attndims'],
                                            data['atttypmod'])

    length = False
    precision = False
    if 'elemoid' in data:
        length, precision, typeval = \
            DataTypeReader.get_length_precision(data['elemoid'])

    # Set length and precision to None
    data['attlen'] = None
    data['attprecision'] = None

    import re

    # If we have length & precision both
    if length and precision:
        matchObj = re.search(r'(\d+),(\d+)', fulltype)
        if matchObj:
            data['attlen'] = matchObj.group(1)
            data['attprecision'] = matchObj.group(2)
    elif length:
        # If we have length only
        matchObj = re.search(r'(\d+)', fulltype)
        if matchObj:
            data['attlen'] = matchObj.group(1)
            data['attprecision'] = None

    return data
Example #4
0
    def _formatter(self, scid, tid, clid, data):
        """
        Args:
             scid: schema oid
             tid: table oid
             clid: position of column in table
             data: dict of query result

        Returns:
            It will return formatted output of collections
        """
        # To check if column is primary key
        if 'attnum' in data and 'indkey' in data:
            # Current column
            attnum = str(data['attnum'])

            # Single/List of primary key column(s)
            indkey = str(data['indkey'])

            # We will check if column is in primary column(s)
            if attnum in indkey.split(" "):
                data['is_pk'] = True
            else:
                data['is_pk'] = False

        # Find length & precision of column data type
        fulltype = self.get_full_type(data['typnspname'], data['typname'],
                                      data['isdup'], data['attndims'],
                                      data['atttypmod'])

        length = False
        precision = False
        if 'elemoid' in data:
            length, precision, typeval = \
                self.get_length_precision(data['elemoid'])

        # Set length and precision to None
        data['attlen'] = None
        data['attprecision'] = None

        import re

        # If we have length & precision both
        if length and precision:
            matchObj = re.search(r'(\d+),(\d+)', fulltype)
            if matchObj:
                data['attlen'] = matchObj.group(1)
                data['attprecision'] = matchObj.group(2)
        elif length:
            # If we have length only
            matchObj = re.search(r'(\d+)', fulltype)
            if matchObj:
                data['attlen'] = matchObj.group(1)
                data['attprecision'] = None

        # We need to fetch inherited tables for each table
        SQL = render_template("/".join(
            [self.template_path, 'get_inherited_tables.sql']),
                              tid=tid)
        status, inh_res = self.conn.execute_dict(SQL)
        if not status:
            return internal_server_error(errormsg=inh_res)
        for row in inh_res['rows']:
            if row['attrname'] == data['name']:
                data['is_inherited'] = True
                data['tbls_inherited'] = row['inhrelname']

        # We need to format variables according to client js collection
        if 'attoptions' in data and data['attoptions'] is not None:
            spcoptions = []
            for spcoption in data['attoptions']:
                k, v = spcoption.split('=')
                spcoptions.append({'name': k, 'value': v})

            data['attoptions'] = spcoptions

        # Need to format security labels according to client js collection
        if 'seclabels' in data and data['seclabels'] is not None:
            seclabels = []
            for seclbls in data['seclabels']:
                k, v = seclbls.split('=')
                seclabels.append({'provider': k, 'label': v})

            data['seclabels'] = seclabels

        # We need to parse & convert ACL coming from database to json format
        SQL = render_template("/".join([self.template_path, 'acl.sql']),
                              tid=tid,
                              clid=clid)
        status, acl = self.conn.execute_dict(SQL)

        if not status:
            return internal_server_error(errormsg=acl)

        # We will set get privileges from acl sql so we don't need
        # it from properties sql
        data['attacl'] = []

        for row in acl['rows']:
            priv = parse_priv_from_db(row)
            data.setdefault(row['deftype'], []).append(priv)

        # we are receiving request when in edit mode
        # we will send filtered types related to current type
        present_type = data['cltype']
        type_id = data['atttypid']

        SQL = render_template("/".join(
            [self.template_path, 'is_referenced.sql']),
                              tid=tid,
                              clid=clid)

        status, is_reference = self.conn.execute_scalar(SQL)

        edit_types_list = list()
        # We will need present type in edit mode
        if data['typnspname'] == "pg_catalog" or \
                data['typnspname'] == "public":
            edit_types_list.append(present_type)
        else:
            t = self.qtTypeIdent(self.conn, data['typnspname'], present_type)
            edit_types_list.append(t)
            data['cltype'] = t

        if int(is_reference) == 0:
            SQL = render_template("/".join(
                [self.template_path, 'edit_mode_types.sql']),
                                  type_id=type_id)
            status, rset = self.conn.execute_2darray(SQL)

            for row in rset['rows']:
                edit_types_list.append(row['typname'])
        else:
            edit_types_list.append(present_type)

        data['edit_types'] = edit_types_list

        data['cltype'] = DataTypeReader.parse_type_name(data['cltype'])

        return data
Example #5
0
def column_formatter(conn, tid, clid, data, edit_types_list=None,
                     fetch_inherited_tables=True, template_path=None):
    """
    This function will return formatted output of query result
    as per client model format for column node
    :param conn: Connection Object
    :param tid: Table ID
    :param clid: Column ID
    :param data: Data
    :param edit_types_list:
    :param fetch_inherited_tables:
    :param template_path: Optional template path
    :return:
    """

    # To check if column is primary key
    _check_primary_column(data)

    # Fetch length and precision
    data = fetch_length_precision(data)

    # We need to fetch inherited tables for each table
    is_error, errmsg = _fetch_inherited_tables(
        tid, data, fetch_inherited_tables, template_path, conn)

    if is_error:
        return errmsg

    # We need to format variables according to client js collection
    if 'attoptions' in data and data['attoptions'] is not None:
        spcoptions = []
        for spcoption in data['attoptions']:
            k, v = spcoption.split('=')
            spcoptions.append({'name': k, 'value': v})

        data['attoptions'] = spcoptions

    # Need to format security labels according to client js collection
    if 'seclabels' in data and data['seclabels'] is not None:
        seclabels = []
        for seclbls in data['seclabels']:
            k, v = seclbls.split('=')
            seclabels.append({'provider': k, 'label': v})

        data['seclabels'] = seclabels

    # We need to parse & convert ACL coming from database to json format
    SQL = render_template("/".join([template_path, 'acl.sql']),
                          tid=tid, clid=clid)
    status, acl = conn.execute_dict(SQL)

    if not status:
        return internal_server_error(errormsg=acl)

    # We will set get privileges from acl sql so we don't need
    # it from properties sql
    data['attacl'] = []

    for row in acl['rows']:
        priv = parse_priv_from_db(row)
        data.setdefault(row['deftype'], []).append(priv)

    # we are receiving request when in edit mode
    # we will send filtered types related to current type
    type_id = data['atttypid']

    if edit_types_list is None:
        edit_types_list = []
        SQL = render_template("/".join([template_path,
                                        'edit_mode_types.sql']),
                              type_id=type_id)
        status, rset = conn.execute_2darray(SQL)
        edit_types_list = [row['typname'] for row in rset['rows']]

    # We will need present type in edit mode
    edit_types_list.append(data['typname'])
    data['edit_types'] = sorted(edit_types_list)

    data['cltype'] = DataTypeReader.parse_type_name(data['cltype'])

    return data
Example #6
0
    def additional_properties(self, copy_dict, tid):
        """
        We will use this function to add additional properties according to
        type

        Returns:
            additional properties for type like range/composite/enum

        """
        # Fetching type of type
        of_type = copy_dict['typtype']
        res = dict()
        # If type is of Composite then we need to add members list in our
        # output
        if of_type == 'c':
            SQL = render_template("/".join(
                [self.template_path, 'additional_properties.sql']),
                                  type='c',
                                  typrelid=copy_dict['typrelid'])
            status, rset = self.conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            # To display in properties
            properties_list = []
            # To display in composite collection grid
            composite_lst = []

            for row in rset['rows']:
                # We will fetch Full type name

                typelist = ' '.join([row['attname'], row['fulltype']])
                if (not row['collname']
                        or (row['collname'] == 'default'
                            and row['collnspname'] == 'pg_catalog')):
                    full_collate = ''
                    collate = ''
                else:
                    full_collate = get_driver(PG_DEFAULT_DRIVER).qtIdent(
                        self.conn, row['collnspname'], row['collname'])
                    collate = ' COLLATE ' + full_collate
                typelist += collate
                properties_list.append(typelist)

                is_tlength = False
                is_precision = False
                if 'elemoid' in row:
                    is_tlength, is_precision, typeval = \
                        self.get_length_precision(row['elemoid'])

                # Below logic will allow us to split length, precision from
                # type name for grid
                import re
                t_len = None
                t_prec = None

                # If we have length & precision both
                if is_tlength and is_precision:
                    matchObj = re.search(r'(\d+),(\d+)', row['fulltype'])
                    if matchObj:
                        t_len = matchObj.group(1)
                        t_prec = matchObj.group(2)
                elif is_tlength:
                    # If we have length only
                    matchObj = re.search(r'(\d+)', row['fulltype'])
                    if matchObj:
                        t_len = matchObj.group(1)
                        t_prec = None

                type_name = DataTypeReader.parse_type_name(row['typname'])

                row['type'] = self._cltype_formatter(type_name)
                row['hasSqrBracket'] = self.hasSqrBracket
                row = self.convert_length_precision_to_string(row)
                composite_lst.append({
                    'attnum': row['attnum'],
                    'member_name': row['attname'],
                    'type': type_name,
                    'collation': full_collate,
                    'cltype': row['type'],
                    'tlength': t_len,
                    'precision': t_prec,
                    'is_tlength': is_tlength,
                    'is_precision': is_precision,
                    'hasSqrBracket': row['hasSqrBracket'],
                    'fulltype': row['fulltype']
                })

            # Adding both results
            res['member_list'] = ', '.join(properties_list)
            res['composite'] = composite_lst

        # If type is of ENUM then we need to add labels in our output
        if of_type == 'e':
            SQL = render_template("/".join(
                [self.template_path, 'additional_properties.sql']),
                                  type='e',
                                  tid=tid)
            status, rset = self.conn.execute_2darray(SQL)
            if not status:
                return internal_server_error(errormsg=res)
            # To display in properties
            properties_list = []
            # To display in enum grid
            enum_list = []
            for row in rset['rows']:
                properties_list.append(row['enumlabel'])
                enum_list.append({'label': row['enumlabel']})

            # Adding both results in ouput
            res['enum_list'] = ', '.join(properties_list)
            res['enum'] = enum_list

        # If type is of Range then we need to add collation,subtype etc in our
        # output
        if of_type == 'r':
            SQL = render_template("/".join(
                [self.template_path, 'additional_properties.sql']),
                                  type='r',
                                  tid=tid)
            status, res = self.conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)
            range_dict = dict(res['rows'][0])
            res.update(range_dict)

        if 'seclabels' in copy_dict and copy_dict['seclabels'] is not None:
            sec_labels = []
            for sec in copy_dict['seclabels']:
                sec = re.search(r'([^=]+)=(.*$)', sec)
                sec_labels.append({
                    'provider': sec.group(1),
                    'label': sec.group(2)
                })
            res['seclabels'] = sec_labels

        # Returning only additional properties only
        return res
Example #7
0
 def get_types(self, conn_id=None, did=None, sid=None):
     condition = self.get_types_condition_sql(False)
     return DataTypeReader.get_types(self, self.conn, condition, True)
Example #8
0
    def additional_properties(self, copy_dict, tid):
        """
        We will use this function to add additional properties according to
        type

        Returns:
            additional properties for type like range/composite/enum

        """
        # Fetching type of type
        of_type = copy_dict['typtype']
        res = dict()
        # If type is of Composite then we need to add members list in our
        # output
        if of_type == 'c':
            SQL = render_template("/".join([self.template_path,
                                            'additional_properties.sql']),
                                  type='c',
                                  typrelid=copy_dict['typrelid'])
            status, rset = self.conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            # To display in properties
            properties_list = []
            # To display in composite collection grid
            composite_lst = []

            for row in rset['rows']:
                # We will fetch Full type name

                typelist = ' '.join([row['attname'], row['fulltype']])
                if (
                    not row['collname'] or
                    (
                        row['collname'] == 'default' and
                        row['collnspname'] == 'pg_catalog'
                    )
                ):
                    full_collate = ''
                    collate = ''
                else:
                    full_collate = get_driver(PG_DEFAULT_DRIVER).qtIdent(
                        self.conn, row['collnspname'], row['collname'])
                    collate = ' COLLATE ' + full_collate
                typelist += collate
                properties_list.append(typelist)

                is_tlength = False
                is_precision = False
                if 'elemoid' in row:
                    is_tlength, is_precision, typeval = \
                        self.get_length_precision(row['elemoid'])

                # Below logic will allow us to split length, precision from
                # type name for grid
                import re
                t_len = None
                t_prec = None

                # If we have length & precision both
                if is_tlength and is_precision:
                    matchObj = re.search(r'(\d+),(\d+)', row['fulltype'])
                    if matchObj:
                        t_len = matchObj.group(1)
                        t_prec = matchObj.group(2)
                elif is_tlength:
                    # If we have length only
                    matchObj = re.search(r'(\d+)', row['fulltype'])
                    if matchObj:
                        t_len = matchObj.group(1)
                        t_prec = None

                type_name = DataTypeReader.parse_type_name(row['typname'])

                row['type'] = self._cltype_formatter(type_name)
                row['hasSqrBracket'] = self.hasSqrBracket
                row = self.convert_length_precision_to_string(row)
                composite_lst.append({
                    'attnum': row['attnum'], 'member_name': row['attname'],
                    'type': type_name,
                    'collation': full_collate, 'cltype': row['type'],
                    'tlength': t_len, 'precision': t_prec,
                    'is_tlength': is_tlength, 'is_precision': is_precision,
                    'hasSqrBracket': row['hasSqrBracket'],
                    'fulltype': row['fulltype']})

            # Adding both results
            res['member_list'] = ', '.join(properties_list)
            res['composite'] = composite_lst

        # If type is of ENUM then we need to add labels in our output
        if of_type == 'e':
            SQL = render_template("/".join([self.template_path,
                                            'additional_properties.sql']),
                                  type='e', tid=tid)
            status, rset = self.conn.execute_2darray(SQL)
            if not status:
                return internal_server_error(errormsg=res)
            # To display in properties
            properties_list = []
            # To display in enum grid
            enum_list = []
            for row in rset['rows']:
                properties_list.append(row['enumlabel'])
                enum_list.append({'label': row['enumlabel']})

            # Adding both results in ouput
            res['enum_list'] = ', '.join(properties_list)
            res['enum'] = enum_list

        # If type is of Range then we need to add collation,subtype etc in our
        # output
        if of_type == 'r':
            SQL = render_template("/".join([self.template_path,
                                            'additional_properties.sql']),
                                  type='r', tid=tid)
            status, res = self.conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)
            range_dict = dict(res['rows'][0])
            res.update(range_dict)

        if 'seclabels' in copy_dict and copy_dict['seclabels'] is not None:
            sec_labels = []
            for sec in copy_dict['seclabels']:
                sec = re.search(r'([^=]+)=(.*$)', sec)
                sec_labels.append({
                    'provider': sec.group(1),
                    'label': sec.group(2)
                })
            res['seclabels'] = sec_labels

        # Returning only additional properties only
        return res