From b8225ccc168f04789db1935a90462b5cb0bbd6a6 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sun, 25 Sep 2016 18:14:47 +0300 Subject: [PATCH] Use SQLObject for string quoting --- ChangeLog | 4 +++- requirements.txt | 2 ++ requirements_dev.txt | 2 -- setup.py | 2 +- sqlconvert/process_tokens.py | 10 ++++++++++ tests/test_mysql2postgres.py | 4 +++- tests/test_tokens.py | 19 ++++++++++++++++++- 7 files changed, 37 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index a15fe36..cd39888 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,7 +6,9 @@ Version 0.0.6 (2016-09-??) Unescape strings. Add a test for Postgres. - Use pytest, coverage, tox and SQLObject for testing. + Use SQLObject for string quoting and connection handling for tests. + + Use pytest, coverage and tox for testing. Version 0.0.5 (2016-09-07) diff --git a/requirements.txt b/requirements.txt index f1bf8b4..930537a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,7 @@ argparse; python_version == '2.6' sqlparse +SQLObject>=2.2.1; python_version >= '2.6' and python_version < '3.0' +SQLObject>=3.0.0; python_version >= '3.4' m_lib>=2.0; python_version >= '2.6' and python_version < '3.0' m_lib>=3.0; python_version >= '3.4' diff --git a/requirements_dev.txt b/requirements_dev.txt index 18f30f8..ca2ff5d 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -3,5 +3,3 @@ pytest pytest-cov tox >= 1.8 -SQLObject>=2.2.1; python_version >= '2.6' and python_version < '3.0' -SQLObject>=3.0.0; python_version >= '3.4' diff --git a/setup.py b/setup.py index aeb04b0..d25281f 100755 --- a/setup.py +++ b/setup.py @@ -45,5 +45,5 @@ setup(name='sqlconvert', packages=['sqlconvert'], package_data={}, scripts=['scripts/mysql2sql'], - requires=['sqlparse', 'm_lib'], + requires=['sqlparse', 'SQLObject', 'm_lib'], ) diff --git a/sqlconvert/process_tokens.py b/sqlconvert/process_tokens.py index b1c2602..6bd618b 100644 --- a/sqlconvert/process_tokens.py +++ b/sqlconvert/process_tokens.py @@ -1,4 +1,5 @@ +from sqlobject.converters import sqlrepr from sqlparse import parse from sqlparse.compat import PY3 from sqlparse import tokens as T @@ -19,6 +20,15 @@ def is_newline_statement(statement): return True +def escape_strings(token_list, dbname): + """Escape strings""" + for token in token_list.flatten(): + if token.ttype is T.String.Single: + value = token.value[1:-1] # unquote by removing apostrophes + value = sqlrepr(value, dbname) + token.normalized = token.value = value + + if PY3: xrange = range diff --git a/tests/test_mysql2postgres.py b/tests/test_mysql2postgres.py index 971970c..6782c54 100644 --- a/tests/test_mysql2postgres.py +++ b/tests/test_mysql2postgres.py @@ -4,6 +4,7 @@ import pytest from sqlconvert.print_tokens import tlist2str from sqlconvert.process_mysql import unescape_strings +from sqlconvert.process_tokens import escape_strings connection = getConnection() pytestmark = pytest.mark.skipif(connection.dbName != "postgres", @@ -22,9 +23,10 @@ def test_mysql2postgres_string(): parsed = parse("insert into test (id, test_str) values " "(1, '\"te\\'st\\\"\\n')")[0] unescape_strings(parsed) + escape_strings(parsed, 'postgres') query = tlist2str(parsed) assert query == u"INSERT INTO test (id, test_str) VALUES " \ - u"(1, '\"te''st\"\n')" + u"(1, E'\"te''st\"\\n')" connection.query(query) test_str = connection.queryOne("SELECT test_str FROM test WHERE id=1")[0] assert test_str == u"\"te'st\"\n" diff --git a/tests/test_tokens.py b/tests/test_tokens.py index d537d73..4e48ab0 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -6,6 +6,7 @@ from sqlconvert.print_tokens import tlist2str from sqlconvert.process_mysql import remove_directive_tokens, \ is_directive_statement, requote_names, unescape_strings, \ process_statement +from sqlconvert.process_tokens import escape_strings def test_encoding(): @@ -42,10 +43,26 @@ def test_requote(): assert query == u'SELECT * FROM "T"' -def test_string(): +def test_unescape_string(): parsed = parse("insert into test values ('\"te\\'st\\\"\\n')")[0] unescape_strings(parsed) query = tlist2str(parsed) + assert query == u"INSERT INTO test VALUES ('\"te'st\"\n')" + + +def test_escape_string_postgres(): + parsed = parse("insert into test values ('\"te\\'st\\\"\\n')")[0] + unescape_strings(parsed) + escape_strings(parsed, 'postgres') + query = tlist2str(parsed) + assert query == u"INSERT INTO test VALUES (E'\"te''st\"\\n')" + + +def test_escape_string_sqlite(): + parsed = parse("insert into test values ('\"te\\'st\\\"\\n')")[0] + unescape_strings(parsed) + escape_strings(parsed, 'sqlite') + query = tlist2str(parsed) assert query == u"INSERT INTO test VALUES ('\"te''st\"\n')" -- 2.39.2