mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			203 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import unittest
 | |
| 
 | |
| import sqlparse
 | |
| 
 | |
| from django.db import connection
 | |
| from django.test import TestCase
 | |
| 
 | |
| 
 | |
| @unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
 | |
| class IntrospectionTests(TestCase):
 | |
|     def test_get_primary_key_column(self):
 | |
|         """
 | |
|         Get the primary key column regardless of whether or not it has
 | |
|         quotation.
 | |
|         """
 | |
|         testable_column_strings = (
 | |
|             ("id", "id"),
 | |
|             ("[id]", "id"),
 | |
|             ("`id`", "id"),
 | |
|             ('"id"', "id"),
 | |
|             ("[id col]", "id col"),
 | |
|             ("`id col`", "id col"),
 | |
|             ('"id col"', "id col"),
 | |
|         )
 | |
|         with connection.cursor() as cursor:
 | |
|             for column, expected_string in testable_column_strings:
 | |
|                 sql = "CREATE TABLE test_primary (%s int PRIMARY KEY NOT NULL)" % column
 | |
|                 with self.subTest(column=column):
 | |
|                     try:
 | |
|                         cursor.execute(sql)
 | |
|                         field = connection.introspection.get_primary_key_column(
 | |
|                             cursor, "test_primary"
 | |
|                         )
 | |
|                         self.assertEqual(field, expected_string)
 | |
|                     finally:
 | |
|                         cursor.execute("DROP TABLE test_primary")
 | |
| 
 | |
|     def test_get_primary_key_column_pk_constraint(self):
 | |
|         sql = """
 | |
|             CREATE TABLE test_primary(
 | |
|                 id INTEGER NOT NULL,
 | |
|                 created DATE,
 | |
|                 PRIMARY KEY(id)
 | |
|             )
 | |
|         """
 | |
|         with connection.cursor() as cursor:
 | |
|             try:
 | |
|                 cursor.execute(sql)
 | |
|                 field = connection.introspection.get_primary_key_column(
 | |
|                     cursor,
 | |
|                     "test_primary",
 | |
|                 )
 | |
|                 self.assertEqual(field, "id")
 | |
|             finally:
 | |
|                 cursor.execute("DROP TABLE test_primary")
 | |
| 
 | |
| 
 | |
| @unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
 | |
| class ParsingTests(TestCase):
 | |
|     def parse_definition(self, sql, columns):
 | |
|         """Parse a column or constraint definition."""
 | |
|         statement = sqlparse.parse(sql)[0]
 | |
|         tokens = (token for token in statement.flatten() if not token.is_whitespace)
 | |
|         with connection.cursor():
 | |
|             return connection.introspection._parse_column_or_constraint_definition(
 | |
|                 tokens, set(columns)
 | |
|             )
 | |
| 
 | |
|     def assertConstraint(self, constraint_details, cols, unique=False, check=False):
 | |
|         self.assertEqual(
 | |
|             constraint_details,
 | |
|             {
 | |
|                 "unique": unique,
 | |
|                 "columns": cols,
 | |
|                 "primary_key": False,
 | |
|                 "foreign_key": None,
 | |
|                 "check": check,
 | |
|                 "index": False,
 | |
|             },
 | |
|         )
 | |
| 
 | |
|     def test_unique_column(self):
 | |
|         tests = (
 | |
|             ('"ref" integer UNIQUE,', ["ref"]),
 | |
|             ("ref integer UNIQUE,", ["ref"]),
 | |
|             ('"customname" integer UNIQUE,', ["customname"]),
 | |
|             ("customname integer UNIQUE,", ["customname"]),
 | |
|         )
 | |
|         for sql, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertIsNone(constraint)
 | |
|                 self.assertConstraint(details, columns, unique=True)
 | |
|                 self.assertIsNone(check)
 | |
| 
 | |
|     def test_unique_constraint(self):
 | |
|         tests = (
 | |
|             ('CONSTRAINT "ref" UNIQUE ("ref"),', "ref", ["ref"]),
 | |
|             ("CONSTRAINT ref UNIQUE (ref),", "ref", ["ref"]),
 | |
|             (
 | |
|                 'CONSTRAINT "customname1" UNIQUE ("customname2"),',
 | |
|                 "customname1",
 | |
|                 ["customname2"],
 | |
|             ),
 | |
|             (
 | |
|                 "CONSTRAINT customname1 UNIQUE (customname2),",
 | |
|                 "customname1",
 | |
|                 ["customname2"],
 | |
|             ),
 | |
|         )
 | |
|         for sql, constraint_name, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertEqual(constraint, constraint_name)
 | |
|                 self.assertConstraint(details, columns, unique=True)
 | |
|                 self.assertIsNone(check)
 | |
| 
 | |
|     def test_unique_constraint_multicolumn(self):
 | |
|         tests = (
 | |
|             (
 | |
|                 'CONSTRAINT "ref" UNIQUE ("ref", "customname"),',
 | |
|                 "ref",
 | |
|                 ["ref", "customname"],
 | |
|             ),
 | |
|             ("CONSTRAINT ref UNIQUE (ref, customname),", "ref", ["ref", "customname"]),
 | |
|         )
 | |
|         for sql, constraint_name, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertEqual(constraint, constraint_name)
 | |
|                 self.assertConstraint(details, columns, unique=True)
 | |
|                 self.assertIsNone(check)
 | |
| 
 | |
|     def test_check_column(self):
 | |
|         tests = (
 | |
|             ('"ref" varchar(255) CHECK ("ref" != \'test\'),', ["ref"]),
 | |
|             ("ref varchar(255) CHECK (ref != 'test'),", ["ref"]),
 | |
|             (
 | |
|                 '"customname1" varchar(255) CHECK ("customname2" != \'test\'),',
 | |
|                 ["customname2"],
 | |
|             ),
 | |
|             (
 | |
|                 "customname1 varchar(255) CHECK (customname2 != 'test'),",
 | |
|                 ["customname2"],
 | |
|             ),
 | |
|         )
 | |
|         for sql, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertIsNone(constraint)
 | |
|                 self.assertIsNone(details)
 | |
|                 self.assertConstraint(check, columns, check=True)
 | |
| 
 | |
|     def test_check_constraint(self):
 | |
|         tests = (
 | |
|             ('CONSTRAINT "ref" CHECK ("ref" != \'test\'),', "ref", ["ref"]),
 | |
|             ("CONSTRAINT ref CHECK (ref != 'test'),", "ref", ["ref"]),
 | |
|             (
 | |
|                 'CONSTRAINT "customname1" CHECK ("customname2" != \'test\'),',
 | |
|                 "customname1",
 | |
|                 ["customname2"],
 | |
|             ),
 | |
|             (
 | |
|                 "CONSTRAINT customname1 CHECK (customname2 != 'test'),",
 | |
|                 "customname1",
 | |
|                 ["customname2"],
 | |
|             ),
 | |
|         )
 | |
|         for sql, constraint_name, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertEqual(constraint, constraint_name)
 | |
|                 self.assertIsNone(details)
 | |
|                 self.assertConstraint(check, columns, check=True)
 | |
| 
 | |
|     def test_check_column_with_operators_and_functions(self):
 | |
|         tests = (
 | |
|             ('"ref" integer CHECK ("ref" BETWEEN 1 AND 10),', ["ref"]),
 | |
|             ('"ref" varchar(255) CHECK ("ref" LIKE \'test%\'),', ["ref"]),
 | |
|             (
 | |
|                 '"ref" varchar(255) CHECK (LENGTH(ref) > "max_length"),',
 | |
|                 ["ref", "max_length"],
 | |
|             ),
 | |
|         )
 | |
|         for sql, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertIsNone(constraint)
 | |
|                 self.assertIsNone(details)
 | |
|                 self.assertConstraint(check, columns, check=True)
 | |
| 
 | |
|     def test_check_and_unique_column(self):
 | |
|         tests = (
 | |
|             ('"ref" varchar(255) CHECK ("ref" != \'test\') UNIQUE,', ["ref"]),
 | |
|             ("ref varchar(255) UNIQUE CHECK (ref != 'test'),", ["ref"]),
 | |
|         )
 | |
|         for sql, columns in tests:
 | |
|             with self.subTest(sql=sql):
 | |
|                 constraint, details, check, _ = self.parse_definition(sql, columns)
 | |
|                 self.assertIsNone(constraint)
 | |
|                 self.assertConstraint(details, columns, unique=True)
 | |
|                 self.assertConstraint(check, columns, check=True)
 |