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)
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 )
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
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
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
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
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)
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