velocity-python 0.0.161__tar.gz → 0.0.163__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {velocity_python-0.0.161 → velocity_python-0.0.163}/PKG-INFO +1 -1
  2. {velocity_python-0.0.161 → velocity_python-0.0.163}/pyproject.toml +1 -1
  3. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/__init__.py +1 -1
  4. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/table.py +26 -4
  5. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/mysql/sql.py +9 -3
  6. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/postgres/sql.py +66 -5
  7. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlite/sql.py +9 -3
  8. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlserver/sql.py +9 -3
  9. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity_python.egg-info/PKG-INFO +1 -1
  10. {velocity_python-0.0.161 → velocity_python-0.0.163}/LICENSE +0 -0
  11. {velocity_python-0.0.161 → velocity_python-0.0.163}/README.md +0 -0
  12. {velocity_python-0.0.161 → velocity_python-0.0.163}/setup.cfg +0 -0
  13. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/__init__.py +0 -0
  14. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/invoices.py +0 -0
  15. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/orders.py +0 -0
  16. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/payments.py +0 -0
  17. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/purchase_orders.py +0 -0
  18. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/tests/__init__.py +0 -0
  19. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/tests/test_email_processing.py +0 -0
  20. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/tests/test_payment_profile_sorting.py +0 -0
  21. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/app/tests/test_spreadsheet_functions.py +0 -0
  22. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/__init__.py +0 -0
  23. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/amplify.py +0 -0
  24. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/__init__.py +0 -0
  25. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/base_handler.py +0 -0
  26. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/context.py +0 -0
  27. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/exceptions.py +0 -0
  28. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/lambda_handler.py +0 -0
  29. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
  30. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/mixins/activity_tracker.py +0 -0
  31. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/mixins/aws_session_mixin.py +0 -0
  32. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/mixins/error_handler.py +0 -0
  33. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/mixins/legacy_mixin.py +0 -0
  34. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/mixins/standard_mixin.py +0 -0
  35. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/response.py +0 -0
  36. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/handlers/sqs_handler.py +0 -0
  37. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/tests/__init__.py +0 -0
  38. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
  39. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/aws/tests/test_response.py +0 -0
  40. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/__init__.py +0 -0
  41. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/__init__.py +0 -0
  42. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/column.py +0 -0
  43. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/database.py +0 -0
  44. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/decorators.py +0 -0
  45. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/engine.py +0 -0
  46. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/result.py +0 -0
  47. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/row.py +0 -0
  48. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/sequence.py +0 -0
  49. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/core/transaction.py +0 -0
  50. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/exceptions.py +0 -0
  51. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/__init__.py +0 -0
  52. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/base/__init__.py +0 -0
  53. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/base/initializer.py +0 -0
  54. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/base/operators.py +0 -0
  55. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/base/sql.py +0 -0
  56. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/base/types.py +0 -0
  57. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/mysql/__init__.py +0 -0
  58. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/mysql/operators.py +0 -0
  59. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/mysql/reserved.py +0 -0
  60. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/mysql/types.py +0 -0
  61. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/postgres/__init__.py +0 -0
  62. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/postgres/operators.py +0 -0
  63. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/postgres/reserved.py +0 -0
  64. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/postgres/types.py +0 -0
  65. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlite/__init__.py +0 -0
  66. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlite/operators.py +0 -0
  67. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlite/reserved.py +0 -0
  68. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlite/types.py +0 -0
  69. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
  70. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlserver/operators.py +0 -0
  71. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
  72. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/sqlserver/types.py +0 -0
  73. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/servers/tablehelper.py +0 -0
  74. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/__init__.py +0 -0
  75. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/common_db_test.py +0 -0
  76. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/__init__.py +0 -0
  77. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/common.py +0 -0
  78. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_column.py +0 -0
  79. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_connections.py +0 -0
  80. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_database.py +0 -0
  81. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_engine.py +0 -0
  82. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
  83. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_imports.py +0 -0
  84. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_result.py +0 -0
  85. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_row.py +0 -0
  86. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
  87. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
  88. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
  89. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
  90. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
  91. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_table.py +0 -0
  92. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
  93. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
  94. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/sql/__init__.py +0 -0
  95. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/sql/common.py +0 -0
  96. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
  97. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
  98. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
  99. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_db_utils.py +0 -0
  100. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_postgres.py +0 -0
  101. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
  102. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
  103. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_result_caching.py +0 -0
  104. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
  105. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
  106. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
  107. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
  108. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_sql_builder.py +0 -0
  109. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/tests/test_tablehelper.py +0 -0
  110. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/db/utils.py +0 -0
  111. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/__init__.py +0 -0
  112. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/conv/__init__.py +0 -0
  113. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/conv/iconv.py +0 -0
  114. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/conv/oconv.py +0 -0
  115. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/db.py +0 -0
  116. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/export.py +0 -0
  117. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/format.py +0 -0
  118. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/mail.py +0 -0
  119. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/merge.py +0 -0
  120. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/__init__.py +0 -0
  121. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_db.py +0 -0
  122. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_fix.py +0 -0
  123. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_format.py +0 -0
  124. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_iconv.py +0 -0
  125. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_merge.py +0 -0
  126. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_oconv.py +0 -0
  127. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_original_error.py +0 -0
  128. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tests/test_timer.py +0 -0
  129. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/timer.py +0 -0
  130. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity/misc/tools.py +0 -0
  131. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity_python.egg-info/SOURCES.txt +0 -0
  132. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity_python.egg-info/dependency_links.txt +0 -0
  133. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity_python.egg-info/requires.txt +0 -0
  134. {velocity_python-0.0.161 → velocity_python-0.0.163}/src/velocity_python.egg-info/top_level.txt +0 -0
  135. {velocity_python-0.0.161 → velocity_python-0.0.163}/tests/test_decorators.py +0 -0
  136. {velocity_python-0.0.161 → velocity_python-0.0.163}/tests/test_sys_modified_count_postgres_demo.py +0 -0
  137. {velocity_python-0.0.161 → velocity_python-0.0.163}/tests/test_table_alter.py +0 -0
  138. {velocity_python-0.0.161 → velocity_python-0.0.163}/tests/test_where_clause_validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.161
3
+ Version: 0.0.163
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "velocity-python"
7
- version = "0.0.161"
7
+ version = "0.0.163"
8
8
  authors = [
9
9
  { name="Velocity Team", email="info@codeclubs.org" },
10
10
  ]
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.0.161"
1
+ __version__ = version = "0.0.163"
2
2
 
3
3
  from . import aws
4
4
  from . import db
@@ -34,10 +34,15 @@ SYSTEM_COLUMN_NAMES = (
34
34
  "sys_modified_count",
35
35
  "sys_dirty",
36
36
  "sys_table",
37
- "description",
37
+ "sys_keywords",
38
38
  )
39
39
 
40
- _SYSTEM_COLUMN_SET = {name.lower() for name in SYSTEM_COLUMN_NAMES}
40
+ # Legacy system columns retained for transitional compatibility checks.
41
+ LEGACY_SYSTEM_COLUMN_NAMES = ("description",)
42
+
43
+ _SYSTEM_COLUMN_SET = {
44
+ name.lower() for name in (*SYSTEM_COLUMN_NAMES, *LEGACY_SYSTEM_COLUMN_NAMES)
45
+ }
41
46
 
42
47
  _NULLABLE_TRUE = {"YES", "TRUE", "T", "1", "Y"}
43
48
  _NULLABLE_FALSE = {"NO", "FALSE", "F", "0", "N"}
@@ -347,6 +352,16 @@ class Table:
347
352
  except Exception:
348
353
  columns = []
349
354
 
355
+ try:
356
+ index_rows = self.indexes()
357
+ existing_indexes = {
358
+ (row[0] or "").lower(): row[3]
359
+ for row in index_rows.as_tuple().all()
360
+ if row and len(row) >= 4
361
+ }
362
+ except Exception:
363
+ existing_indexes = {}
364
+
350
365
  sql_method = getattr(self.sql, "ensure_system_columns", None)
351
366
 
352
367
  if sql_method is None:
@@ -355,7 +370,10 @@ class Table:
355
370
  )
356
371
 
357
372
  result = sql_method(
358
- self.name, existing_columns=columns, force=force
373
+ self.name,
374
+ existing_columns=columns,
375
+ existing_indexes=existing_indexes,
376
+ force=force,
359
377
  )
360
378
 
361
379
  if not result:
@@ -1294,7 +1312,11 @@ class Table:
1294
1312
  """
1295
1313
  Returns detailed information about all indexes on this table.
1296
1314
  """
1297
- sql, vals = self.sql.indexes(self.name)
1315
+ sql_spec = self.sql.indexes(self.name)
1316
+ if isinstance(sql_spec, tuple):
1317
+ sql, vals = sql_spec
1318
+ else:
1319
+ sql, vals = sql_spec, tuple()
1298
1320
  if kwds.get("sql_only", False):
1299
1321
  return sql, vals
1300
1322
  return self.tx.execute(sql, vals, cursor=self.cursor())
@@ -26,7 +26,7 @@ system_fields = [
26
26
  "sys_dirty",
27
27
  "sys_table",
28
28
  "sys_modified_count",
29
- "description",
29
+ "sys_keywords",
30
30
  ]
31
31
 
32
32
 
@@ -396,7 +396,7 @@ CREATE TABLE {table_identifier} (
396
396
  `sys_modified_by` TEXT,
397
397
  `sys_modified_count` INT NOT NULL DEFAULT 0,
398
398
  `sys_dirty` TINYINT(1) NOT NULL DEFAULT 0,
399
- `description` TEXT,
399
+ `sys_keywords` TEXT,
400
400
  PRIMARY KEY (`sys_id`)
401
401
  ) ENGINE=InnoDB;
402
402
  """.strip()
@@ -450,7 +450,13 @@ END;
450
450
  return "\n".join(statements), tuple()
451
451
 
452
452
  @classmethod
453
- def ensure_system_columns(cls, name, existing_columns=None, force=False):
453
+ def ensure_system_columns(
454
+ cls,
455
+ name,
456
+ existing_columns=None,
457
+ force=False,
458
+ existing_indexes=None,
459
+ ):
454
460
  """Ensure MySQL tables maintain the Velocity system metadata."""
455
461
  existing_columns = {col.lower() for col in existing_columns or []}
456
462
 
@@ -27,7 +27,7 @@ system_fields = [
27
27
  "sys_modified_count",
28
28
  "sys_dirty",
29
29
  "sys_table",
30
- "description",
30
+ "sys_keywords",
31
31
  ]
32
32
 
33
33
 
@@ -836,6 +836,16 @@ class SQL(BaseSQLDialect):
836
836
  COST 100;
837
837
  """
838
838
 
839
+ @staticmethod
840
+ def _sys_keywords_index_name(schema_unquoted, table_unquoted):
841
+ base_index_name = f"idx_{schema_unquoted}_{table_unquoted}_sys_keywords_tsv"
842
+ base_index_name = re.sub(r"[^0-9a-zA-Z_]+", "_", base_index_name)
843
+ if len(base_index_name) > 60:
844
+ digest = hashlib.sha256(base_index_name.encode("utf-8")).hexdigest()
845
+ base_index_name = f"idx_{table_unquoted[:30]}_{digest[:8]}_sk"
846
+ base_index_name = re.sub(r"[^0-9a-zA-Z_]+", "_", base_index_name)
847
+ return base_index_name[:63]
848
+
839
849
  @classmethod
840
850
  def create_table(cls, name, columns={}, drop=False):
841
851
  if "." in name:
@@ -865,7 +875,7 @@ class SQL(BaseSQLDialect):
865
875
  sys_modified_count INTEGER NOT NULL DEFAULT 0,
866
876
  sys_dirty BOOLEAN NOT NULL DEFAULT FALSE,
867
877
  sys_table TEXT NOT NULL,
868
- description TEXT
878
+ sys_keywords TEXT
869
879
  );
870
880
 
871
881
  SELECT SETVAL(PG_GET_SERIAL_SEQUENCE('{fqtn}', 'sys_id'),1000,TRUE);
@@ -889,16 +899,33 @@ class SQL(BaseSQLDialect):
889
899
  f"ALTER TABLE {TableHelper.quote(fqtn)} ADD COLUMN {TableHelper.quote(key)} {TYPES.get_type(val)};"
890
900
  )
891
901
 
902
+ index_name = cls._sys_keywords_index_name(schema_unquoted, table_unquoted)
903
+ index_identifier = TableHelper.quote(index_name)
904
+ sql.append(
905
+ f"CREATE INDEX {index_identifier} ON {fqtn} USING GIN (TO_TSVECTOR('simple', COALESCE(sys_keywords, '')));"
906
+ )
907
+
892
908
  sql = sqlparse.format(" ".join(sql), reindent=True, keyword_case="upper")
893
909
  return sql, tuple()
894
910
 
895
911
  @classmethod
896
- def ensure_system_columns(cls, name, existing_columns=None, force=False):
912
+ def ensure_system_columns(
913
+ cls,
914
+ name,
915
+ existing_columns=None,
916
+ force=False,
917
+ existing_indexes=None,
918
+ ):
897
919
  """Ensure all Velocity system columns and triggers exist for the table."""
898
920
  existing_columns = {
899
921
  col.lower() for col in (existing_columns or [])
900
922
  }
901
923
 
924
+ existing_indexes = {
925
+ (idx or "").lower(): (definition or "")
926
+ for idx, definition in (existing_indexes or {}).items()
927
+ }
928
+
902
929
  required_columns = [
903
930
  "sys_id",
904
931
  "sys_created",
@@ -908,7 +935,7 @@ class SQL(BaseSQLDialect):
908
935
  "sys_modified_count",
909
936
  "sys_dirty",
910
937
  "sys_table",
911
- "description",
938
+ "sys_keywords",
912
939
  ]
913
940
 
914
941
  missing_columns = [
@@ -955,7 +982,7 @@ class SQL(BaseSQLDialect):
955
982
  "sys_modified_count": "INTEGER NOT NULL DEFAULT 0",
956
983
  "sys_dirty": "BOOLEAN NOT NULL DEFAULT FALSE",
957
984
  "sys_table": "TEXT",
958
- "description": "TEXT",
985
+ "sys_keywords": "TEXT",
959
986
  }
960
987
 
961
988
  for column, definition in column_definitions.items():
@@ -1023,6 +1050,27 @@ class SQL(BaseSQLDialect):
1023
1050
  """
1024
1051
  )
1025
1052
 
1053
+ if "sys_keywords" in columns_after:
1054
+ index_name = cls._sys_keywords_index_name(schema_unquoted, table_unquoted)
1055
+ quoted_index_name = TableHelper.quote(index_name)
1056
+
1057
+ current_definition = existing_indexes.get(index_name.lower(), "")
1058
+ current_definition_lower = current_definition.lower()
1059
+ has_target = (
1060
+ "to_tsvector" in current_definition_lower
1061
+ and "coalesce" in current_definition_lower
1062
+ and "sys_keywords" in current_definition_lower
1063
+ )
1064
+ needs_rebuild = force or not has_target
1065
+
1066
+ if needs_rebuild:
1067
+ statements.append(
1068
+ f"DROP INDEX IF EXISTS {quoted_index_name};"
1069
+ )
1070
+ statements.append(
1071
+ f"CREATE INDEX {quoted_index_name} ON {fqtn} USING GIN (TO_TSVECTOR('simple', COALESCE(sys_keywords, '')));"
1072
+ )
1073
+
1026
1074
  if not statements:
1027
1075
  return None
1028
1076
 
@@ -1508,6 +1556,19 @@ class SQL(BaseSQLDialect):
1508
1556
  """
1509
1557
  Returns SQL for retrieving all indexes on a given table with detailed attributes.
1510
1558
  """
1559
+ if "." in table:
1560
+ schema, tbl = table.split(".", 1)
1561
+ schema = schema.replace('"', "")
1562
+ tbl = tbl.replace('"', "")
1563
+ return (
1564
+ """
1565
+ SELECT indexname, tablename, schemaname, indexdef
1566
+ FROM pg_indexes
1567
+ WHERE tablename = %s AND schemaname = %s
1568
+ """,
1569
+ (tbl, schema),
1570
+ )
1571
+
1511
1572
  return (
1512
1573
  """
1513
1574
  SELECT indexname, tablename, schemaname, indexdef
@@ -26,7 +26,7 @@ system_fields = [
26
26
  "sys_dirty",
27
27
  "sys_table",
28
28
  "sys_modified_count",
29
- "description",
29
+ "sys_keywords",
30
30
  ]
31
31
 
32
32
 
@@ -379,7 +379,7 @@ CREATE TABLE {table_identifier} (
379
379
  "sys_modified_by" TEXT,
380
380
  "sys_modified_count" INTEGER NOT NULL DEFAULT 0,
381
381
  "sys_dirty" INTEGER NOT NULL DEFAULT 0,
382
- "description" TEXT
382
+ "sys_keywords" TEXT
383
383
  );
384
384
  """.strip()
385
385
  )
@@ -431,7 +431,13 @@ END;
431
431
  return "\n".join(statements), tuple()
432
432
 
433
433
  @classmethod
434
- def ensure_system_columns(cls, name, existing_columns=None, force=False):
434
+ def ensure_system_columns(
435
+ cls,
436
+ name,
437
+ existing_columns=None,
438
+ force=False,
439
+ existing_indexes=None,
440
+ ):
435
441
  """Ensure SQLite tables maintain the Velocity system triggers/columns."""
436
442
  existing_columns = {col.lower() for col in existing_columns or []}
437
443
 
@@ -26,7 +26,7 @@ system_fields = [
26
26
  "sys_dirty",
27
27
  "sys_table",
28
28
  "sys_modified_count",
29
- "description",
29
+ "sys_keywords",
30
30
  ]
31
31
 
32
32
 
@@ -426,7 +426,7 @@ CREATE TABLE {table_identifier} (
426
426
  [sys_modified_by] NVARCHAR(255),
427
427
  [sys_modified_count] INT NOT NULL DEFAULT 0,
428
428
  [sys_dirty] BIT NOT NULL DEFAULT 0,
429
- [description] NVARCHAR(MAX)
429
+ [sys_keywords] NVARCHAR(MAX)
430
430
  );
431
431
  """.strip()
432
432
  )
@@ -485,7 +485,13 @@ END;
485
485
  return "\n".join(statements), tuple()
486
486
 
487
487
  @classmethod
488
- def ensure_system_columns(cls, name, existing_columns=None, force=False):
488
+ def ensure_system_columns(
489
+ cls,
490
+ name,
491
+ existing_columns=None,
492
+ force=False,
493
+ existing_indexes=None,
494
+ ):
489
495
  """Ensure SQL Server tables maintain Velocity system metadata."""
490
496
  existing_columns = {col.lower() for col in existing_columns or []}
491
497
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.161
3
+ Version: 0.0.163
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT