diff --git a/py_dbcn/connectors/core/clauses.py b/py_dbcn/connectors/core/clauses.py index bac05a66253a79bfd0ebc223f50e1d2b5e6d0de9..d04bb4c8a421af6055cb7bcb98088617f404928c 100644 --- a/py_dbcn/connectors/core/clauses.py +++ b/py_dbcn/connectors/core/clauses.py @@ -81,7 +81,19 @@ class BaseClauseBuilder(object): @property def context(self): - return ', '.join('{}' for i in range(len(self.array))) + if len(self.array) > 0: + context = ', '.join('%s' for i in range(len(self.array))) + return context + else: + return '' + + @property + def data(self): + single_depth_array = [] + for index in range(len(self.array)): + single_depth_array.append(self.array[index]) + + return single_depth_array def _to_array(self, value): """Converts clause to array format for initial parsing.""" @@ -252,16 +264,19 @@ class BaseClauseBuilder(object): # ): # item = """'{0}'""".format(item) + # # Check if apostrophe in value. + # if "'" in item: + # print('\n\n\n\n') + # print('replacing quote in {0}'.format(item)) + # item.replace("'", '\0027') + # print('replaced quote in {0}'.format(item)) + # If we made it this far, item is valid. Escape with proper quote format and readd. is_quoted = False if self.is_quoted(item): item = item[1:-1].strip() is_quoted = True - # Check if apostrophe in value. - if "'" in item: - item.replace("'", '\0027') - # Skip items that are empty. Otherwise append. if len(item) > 0: print('') @@ -291,6 +306,8 @@ class BaseClauseBuilder(object): # Save item to clause. new_clause.append(item) + print('final result: {0}'.format(item)) + return new_clause @staticmethod @@ -572,6 +589,10 @@ class ValuesManyClauseBuilder(ValuesClauseBuilder): else: return '' + @property + def orig_context(self): + return super().context + @property def data(self): single_depth_array = [] diff --git a/py_dbcn/connectors/core/records.py b/py_dbcn/connectors/core/records.py index 40bfaf955c12dbe01efdc22fc6193b4f81e413b7..df5b6224c720c7f243cacb0f516c01328b503029 100644 --- a/py_dbcn/connectors/core/records.py +++ b/py_dbcn/connectors/core/records.py @@ -103,11 +103,11 @@ class BaseRecords: query = textwrap.dedent( """ INSERT INTO {0}{1} - {2}; - """.format(table_name, columns_clause, values_clause) + VALUES ({2}); + """.format(table_name, columns_clause, values_clause.context) ) - results = self._base.query.execute(query, display_query=display_query) + results = self._base.query.execute(query, data=values_clause.data, display_query=display_query) if display_results: self._base.display.results('{0}'.format(results)) @@ -128,18 +128,18 @@ class BaseRecords: raise ValueError('VALUES clause for INSERT_MANY queries must be in list/tuple format.') if len(values_clause) < 1: raise ValueError('VALUES clause cannot be empty for INSERT_MANY queries.') - values_clause = self._base.validate.sanitize_values_clause(values_clause) - values_context = ', '.join('%s' for i in range(len(values_clause.array[0]))) + values_clause = self._base.validate.sanitize_values_many_clause(values_clause) # Insert record. query = textwrap.dedent( """ INSERT INTO {0}{1} - VALUES ({2}); - """.format(table_name, columns_clause, values_context) + VALUES + {2}; + """.format(table_name, columns_clause, values_clause.context) ) - results = self._base.query.execute_many(query, values_clause.array, display_query=display_query) + results = self._base.query.execute(query, data=values_clause.data, display_query=display_query) if display_results: self._base.display.results('{0}'.format(results)) diff --git a/tests/connectors/core/test_records.py b/tests/connectors/core/test_records.py index d5c9151e47df29a981b9be444b9e4e2afc5bd27b..b4e23832660ef511cabfc3f8927af5cd73de43f8 100644 --- a/tests/connectors/core/test_records.py +++ b/tests/connectors/core/test_records.py @@ -853,33 +853,33 @@ class CoreRecordsTestMixin: self.assertEqual(len(results), 0) # Run test query. - row = (1, "'test_name_1'", "'test_desc_1'") + row = (1, 'test_name_1', 'test_desc_1') self.connector.records.insert(table_name, row) results = self.connector.query.execute('SELECT * FROM {0};'.format(table_name)) # Verify one record returned. self.assertEqual(len(results), 1) - self.assertIn((1, 'test_name_1', 'test_desc_1'), results) + self.assertIn(row, results) # Run test query. - row = (2, "'test_name_2'", "'test_desc_2'") + row = (2, 'test_name_2', 'test_desc_2') self.connector.records.insert(table_name, row) results = self.connector.query.execute('SELECT * FROM {0};'.format(table_name)) # Verify two records returned. self.assertEqual(len(results), 2) - self.assertIn((2, 'test_name_2', 'test_desc_2'), results) + self.assertIn(row, results) # Works for 0, 1, and 2. Assume works for all further n+1 values. # Test with columns defined. - row = (3, "'test_name_3'", "'test_desc_3'") + row = (3, 'test_name_3', 'test_desc_3') self.connector.records.insert(table_name, row, columns_clause='id, name, description') results = self.connector.query.execute('SELECT * FROM {0};'.format(table_name)) # Verify two records returned. self.assertEqual(len(results), 3) - self.assertIn((3, 'test_name_3', 'test_desc_3'), results) + self.assertIn(row, results) def test__insert__datetime__success(self): """ @@ -976,6 +976,39 @@ class CoreRecordsTestMixin: # # self.assertEqual(len(results), 2) # # self.assertIn(row, results) + # def test__insert__with_quote_types(self): + # """""" + # table_name = 'test_queries__insert__with_quote_types' + # + # # Verify table exists. + # try: + # self.connector.query.execute('CREATE TABLE {0}{1};'.format(table_name, self._columns_clause__basic)) + # except self.connector.errors.table_already_exists: + # # Table already exists, as we want. + # pass + # + # # Verify starting state. + # results = self.connector.query.execute('SELECT * FROM {0};'.format(table_name)) + # self.assertEqual(len(results), 0) + # + # # Run test query. + # row = (1, """2" nail""", """2 inch nail""") + # self.connector.records.insert(table_name, row) + # results = self.connector.query.execute('SELECT * FROM {0};'.format(table_name)) + # + # # Verify one record returned. + # self.assertEqual(len(results), 1) + # self.assertIn(row, results) + # + # # Run test query. + # row = (2, """'1\' ruler'""", """'1 foot ruler'""") + # self.connector.records.insert(table_name, row) + # results = self.connector.query.execute('SELECT * FROM {0};'.format(table_name)) + # + # # Verify two records returned. + # self.assertEqual(len(results), 2) + # self.assertIn(row, results) + def test__insert_many__basic__success(self): """ Test execute_many `INSERT` query. @@ -1382,11 +1415,11 @@ class CoreRecordsTestMixin: self.connector.records.update( table_name, ( - 'test_datetime = {1}{0}{1}, '.format( + """test_datetime = {1}{0}{1}, """.format( updated_test_datetime_str__2021, self.connector.validate._quote_str_literal_format, ) - + 'test_date = {1}{0}{1}'.format( + + """test_date = {1}{0}{1}""".format( updated_test_date_str__2021, self.connector.validate._quote_str_literal_format, ) @@ -1425,11 +1458,11 @@ class CoreRecordsTestMixin: self.connector.records.update( table_name, ( - 'test_datetime = {1}{0}{1}, '.format( + """test_datetime = {1}{0}{1}, """.format( updated_test_datetime__2022, self.connector.validate._quote_str_literal_format, ) - + 'test_date = {1}{0}{1}'.format( + + """test_date = {1}{0}{1}""".format( updated_test_date__2022, self.connector.validate._quote_str_literal_format, ) diff --git a/tests/connectors/postgresql/expected_display_output.py b/tests/connectors/postgresql/expected_display_output.py index f94e17496e50160602d418a02abc4616ee9e7395..29ee37a9624b4ff80888f4653cfae808c9bbe59d 100644 --- a/tests/connectors/postgresql/expected_display_output.py +++ b/tests/connectors/postgresql/expected_display_output.py @@ -127,239 +127,239 @@ EXPECTED__RECORD__SELECT__PT_1 = """ +----+------+-------------+ | id | name | description | +----+------+-------------+ -| 1 | tn | td | +| 1 | 'tn' | 'td' | +----+------+-------------+ """.strip() EXPECTED__RECORD__SELECT__PT_2 = """ -+----+------+-------------+ -| id | name | description | -+----+------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -+----+------+-------------+ -""".strip() - - -EXPECTED__RECORD__SELECT__PT_3 = """ -+----+------+-------------+ -| id | name | description | -+----+------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -+----+------+-------------+ -""".strip() - - -EXPECTED__RECORD__SELECT__PT_4 = """ +----+-------+-------------+ | id | name | description | +----+-------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +----+-------+-------------+ """.strip() -EXPECTED__RECORD__SELECT__PT_5 = """ +EXPECTED__RECORD__SELECT__PT_3 = """ +----+--------+-------------+ | id | name | description | +----+--------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +----+--------+-------------+ """.strip() -EXPECTED__RECORD__SELECT__PT_6 = """ +EXPECTED__RECORD__SELECT__PT_4 = """ +----+---------+-------------+ | id | name | description | +----+---------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +----+---------+-------------+ """.strip() -EXPECTED__RECORD__SELECT__PT_7 = """ +EXPECTED__RECORD__SELECT__PT_5 = """ +----+----------+-------------+ | id | name | description | +----+----------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +----+----------+-------------+ """.strip() -EXPECTED__RECORD__SELECT__PT_8 = """ +EXPECTED__RECORD__SELECT__PT_6 = """ +----+-----------+-------------+ | id | name | description | +----+-----------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +----+-----------+-------------+ """.strip() +EXPECTED__RECORD__SELECT__PT_7 = """ ++----+------------+-------------+ +| id | name | description | ++----+------------+-------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | ++----+------------+-------------+ +""".strip() + + +EXPECTED__RECORD__SELECT__PT_8 = """ ++----+-------------+-------------+ +| id | name | description | ++----+-------------+-------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | ++----+-------------+-------------+ +""".strip() + + EXPECTED__RECORD__SELECT__PT_9 = """ -+----+-----------+-------------+ -| id | name | description | -+----+-----------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -+----+-----------+-------------+ ++----+-------------+--------------+ +| id | name | description | ++----+-------------+--------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | ++----+-------------+--------------+ """.strip() EXPECTED__RECORD__SELECT__PT_10 = """ -+----+-----------+-------------+ -| id | name | description | -+----+-----------+-------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -| 10 | test name | test descri | -+----+-----------+-------------+ ++----+-------------+---------------+ +| id | name | description | ++----+-------------+---------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | +| 10 | 'test name' | 'test descri' | ++----+-------------+---------------+ """.strip() EXPECTED__RECORD__SELECT__PT_11 = """ -+-----+-----------+--------------+ -| id | name | description | -+-----+-----------+--------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -| 10 | test name | test descri | -| 101 | test name | test descrip | -+-----+-----------+--------------+ ++-----+-------------+----------------+ +| id | name | description | ++-----+-------------+----------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | +| 10 | 'test name' | 'test descri' | +| 101 | 'test name' | 'test descrip' | ++-----+-------------+----------------+ """.strip() EXPECTED__RECORD__SELECT__PT_12 = """ -+------+-----------+---------------+ -| id | name | description | -+------+-----------+---------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -| 10 | test name | test descri | -| 101 | test name | test descrip | -| 1010 | test name | test descript | -+------+-----------+---------------+ ++------+-------------+-----------------+ +| id | name | description | ++------+-------------+-----------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | +| 10 | 'test name' | 'test descri' | +| 101 | 'test name' | 'test descrip' | +| 1010 | 'test name' | 'test descript' | ++------+-------------+-----------------+ """.strip() EXPECTED__RECORD__SELECT__PT_13 = """ -+-------+-----------+----------------+ -| id | name | description | -+-------+-----------+----------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -| 10 | test name | test descri | -| 101 | test name | test descrip | -| 1010 | test name | test descript | -| 10101 | test name | test descripti | -+-------+-----------+----------------+ ++-------+-------------+------------------+ +| id | name | description | ++-------+-------------+------------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | +| 10 | 'test name' | 'test descri' | +| 101 | 'test name' | 'test descrip' | +| 1010 | 'test name' | 'test descript' | +| 10101 | 'test name' | 'test descripti' | ++-------+-------------+------------------+ """.strip() EXPECTED__RECORD__SELECT__PT_14 = """ -+--------+-----------+-----------------+ -| id | name | description | -+--------+-----------+-----------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -| 10 | test name | test descri | -| 101 | test name | test descrip | -| 1010 | test name | test descript | -| 10101 | test name | test descripti | -| 101010 | test name | test descriptio | -+--------+-----------+-----------------+ ++--------+-------------+-------------------+ +| id | name | description | ++--------+-------------+-------------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | +| 10 | 'test name' | 'test descri' | +| 101 | 'test name' | 'test descrip' | +| 1010 | 'test name' | 'test descript' | +| 10101 | 'test name' | 'test descripti' | +| 101010 | 'test name' | 'test descriptio' | ++--------+-------------+-------------------+ """.strip() EXPECTED__RECORD__SELECT__PT_15 = """ -+---------+-----------+------------------+ -| id | name | description | -+---------+-----------+------------------+ -| 1 | tn | td | -| 2 | t n | t d | -| 3 | te n | te d | -| 4 | tes n | tes d | -| 5 | test n | test d | -| 6 | test na | test de | -| 7 | test nam | test des | -| 8 | test name | test desc | -| 9 | test name | test descr | -| 10 | test name | test descri | -| 101 | test name | test descrip | -| 1010 | test name | test descript | -| 10101 | test name | test descripti | -| 101010 | test name | test descriptio | -| 1010101 | test name | test description | -+---------+-----------+------------------+ ++---------+-------------+--------------------+ +| id | name | description | ++---------+-------------+--------------------+ +| 1 | 'tn' | 'td' | +| 2 | 't n' | 't d' | +| 3 | 'te n' | 'te d' | +| 4 | 'tes n' | 'tes d' | +| 5 | 'test n' | 'test d' | +| 6 | 'test na' | 'test de' | +| 7 | 'test nam' | 'test des' | +| 8 | 'test name' | 'test desc' | +| 9 | 'test name' | 'test descr' | +| 10 | 'test name' | 'test descri' | +| 101 | 'test name' | 'test descrip' | +| 1010 | 'test name' | 'test descript' | +| 10101 | 'test name' | 'test descripti' | +| 101010 | 'test name' | 'test descriptio' | +| 1010101 | 'test name' | 'test description' | ++---------+-------------+--------------------+ """.strip()