Ticket #4680: 4680-3.diff

File 4680-3.diff, 4.8 KB (added by Claude Paroz, 13 years ago)

Possible resolution of the issue

  • django/core/management/sql.py

    diff --git a/django/core/management/sql.py b/django/core/management/sql.py
    index 19b7ec2..472f486 100644
    a b def sql_all(app, style, connection):  
    144144    "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
    145145    return sql_create(app, style, connection) + sql_custom(app, style, connection) + sql_indexes(app, style, connection)
    146146
     147def _split_statements(content):
     148    comment_re = re.compile(r"^((?:'[^']*'|[^'])*?)--.*$")
     149    statements = []
     150    statement = u""
     151    for line in content.split("\n"):
     152        cleaned_line = comment_re.sub(r"\1", line).strip()
     153        if not cleaned_line:
     154            continue
     155        statement += cleaned_line
     156        if statement.endswith(";"):
     157            statements.append(statement)
     158            statement = u""
     159    return statements
     160
    147161def custom_sql_for_model(model, style, connection):
    148162    opts = model._meta
    149163    app_dir = os.path.normpath(os.path.join(os.path.dirname(models.get_app(model._meta.app_label).__file__), 'sql'))
    def custom_sql_for_model(model, style, connection):  
    157171        for f in post_sql_fields:
    158172            output.extend(f.post_create_sql(style, model._meta.db_table))
    159173
    160     # Some backends can't execute more than one SQL statement at a time,
    161     # so split into separate statements.
    162     statements = re.compile(r";[ \t]*$", re.M)
    163 
    164174    # Find custom SQL, if it's available.
    165175    backend_name = connection.settings_dict['ENGINE'].split('.')[-1]
    166176    sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), backend_name)),
    def custom_sql_for_model(model, style, connection):  
    168178    for sql_file in sql_files:
    169179        if os.path.exists(sql_file):
    170180            fp = open(sql_file, 'U')
    171             for statement in statements.split(fp.read().decode(settings.FILE_CHARSET)):
    172                 # Remove any comments from the file
    173                 statement = re.sub(ur"--.*([\n\Z]|$)", "", statement)
    174                 if statement.strip():
    175                     output.append(statement + u";")
     181            # Some backends can't execute more than one SQL statement at a time,
     182            # so split into separate statements.
     183            output.extend(_split_statements(fp.read().decode(settings.FILE_CHARSET)))
    176184            fp.close()
    177185
    178186    return output
  • tests/regressiontests/initial_sql_regress/sql/simple.sql

    diff --git a/tests/regressiontests/initial_sql_regress/sql/simple.sql b/tests/regressiontests/initial_sql_regress/sql/simple.sql
    index ca9bd40..ef2be49 100644
    a b  
    1 INSERT INTO initial_sql_regress_simple (name) VALUES ('John');
     1-- a comment
     2INSERT INTO initial_sql_regress_simple (name) VALUES ('John'); -- another comment
     3INSERT INTO initial_sql_regress_simple (name) VALUES ('-- Comment Man');
    24INSERT INTO initial_sql_regress_simple (name) VALUES ('Paul');
    35INSERT INTO initial_sql_regress_simple (name) VALUES ('Ringo');
    46INSERT INTO initial_sql_regress_simple (name) VALUES ('George');
  • tests/regressiontests/initial_sql_regress/tests.py

    diff --git a/tests/regressiontests/initial_sql_regress/tests.py b/tests/regressiontests/initial_sql_regress/tests.py
    index 815b75a..03a91cb 100644
    a b from .models import Simple  
    44
    55
    66class InitialSQLTests(TestCase):
    7     def test_initial_sql(self):
    8         # The format of the included SQL file for this test suite is important.
    9         # It must end with a trailing newline in order to test the fix for #2161.
     7    # The format of the included SQL file for this test suite is important.
     8    # It must end with a trailing newline in order to test the fix for #2161.
    109
    11         # However, as pointed out by #14661, test data loaded by custom SQL
     10    def test_initial_sql(self):
     11        # As pointed out by #14661, test data loaded by custom SQL
    1212        # can't be relied upon; as a result, the test framework flushes the
    1313        # data contents before every test. This test validates that this has
    1414        # occurred.
    1515        self.assertEqual(Simple.objects.count(), 0)
     16
     17    def test_custom_sql(self):
     18        from django.core.management.sql import custom_sql_for_model
     19        from django.core.management.color import no_style
     20        from django.db import connections, DEFAULT_DB_ALIAS
     21
     22        # Simulate the custom SQL loading by syncdb
     23        connection = connections[DEFAULT_DB_ALIAS]
     24        custom_sql = custom_sql_for_model(Simple, no_style(), connection)
     25        self.assertEqual(len(custom_sql), 8)
     26        cursor = connection.cursor()
     27        for sql in custom_sql:
     28            cursor.execute(sql)
     29        self.assertEqual(Simple.objects.count(), 8)
Back to Top