sql-dialect.vala 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using Invercargill.DataStructures;
  2. using Invercargill.Expressions;
  3. using InvercargillSql.Migrations;
  4. using InvercargillSql.Orm;
  5. using InvercargillSql.Orm.Projections;
  6. namespace InvercargillSql.Dialects {
  7. /**
  8. * Interface for SQL dialects.
  9. *
  10. * SqlDialect provides methods for translating types, expressions,
  11. * and generating SQL statements for a specific database backend.
  12. *
  13. * It also provides schema introspection capabilities for discovering
  14. * database metadata at runtime.
  15. */
  16. public interface SqlDialect : Object {
  17. /**
  18. * Translates a ColumnType to the database-specific type string.
  19. *
  20. * @param type The column type to translate
  21. * @return The database-specific type string
  22. */
  23. public abstract string translate_type(ColumnType type);
  24. /**
  25. * Translates an expression tree to SQL.
  26. *
  27. * @param expr The expression to translate
  28. * @param mapper The entity mapper for column resolution
  29. * @return The SQL string representation
  30. */
  31. public abstract string translate_expression(Expression expr, EntityMapper mapper);
  32. /**
  33. * Builds a SELECT statement for all rows in a table.
  34. *
  35. * @param table_name The name of the table
  36. * @return The SQL SELECT statement
  37. */
  38. public abstract string build_select_all(string table_name);
  39. /**
  40. * Builds a SELECT statement for a single row by ID.
  41. *
  42. * @param table_name The name of the table
  43. * @param id_column The name of the ID column
  44. * @return The SQL SELECT statement with parameter placeholder
  45. */
  46. public abstract string build_select_by_id(string table_name, string id_column);
  47. /**
  48. * Builds an INSERT statement.
  49. *
  50. * @param table_name The name of the table
  51. * @param columns The column names to insert into
  52. * @return The SQL INSERT statement with parameter placeholders
  53. */
  54. public abstract string build_insert_sql(string table_name, Vector<string> columns);
  55. /**
  56. * Builds an UPDATE statement.
  57. *
  58. * @param table_name The name of the table
  59. * @param columns The column names to update
  60. * @param id_column The name of the ID column for the WHERE clause
  61. * @return The SQL UPDATE statement with parameter placeholders
  62. */
  63. public abstract string build_update_sql(string table_name, Vector<string> columns, string id_column);
  64. /**
  65. * Builds a DELETE statement.
  66. *
  67. * @param table_name The name of the table
  68. * @param id_column The name of the ID column for the WHERE clause
  69. * @return The SQL DELETE statement with parameter placeholder
  70. */
  71. public abstract string build_delete_sql(string table_name, string id_column);
  72. /**
  73. * Builds a CREATE TABLE statement.
  74. *
  75. * @param table_name The name of the table
  76. * @param columns The column definitions
  77. * @return The SQL CREATE TABLE statement
  78. */
  79. public abstract string build_create_table(string table_name, Vector<ColumnDefinition> columns);
  80. /**
  81. * Builds a CREATE INDEX statement.
  82. *
  83. * @param table_name The name of the table
  84. * @param index The index definition
  85. * @return The SQL CREATE INDEX statement
  86. */
  87. public abstract string build_create_index(string table_name, IndexDefinition index);
  88. // Migration DDL methods
  89. /**
  90. * Generates SQL for a CREATE TABLE operation.
  91. *
  92. * @param op The create table operation
  93. * @return The SQL CREATE TABLE statement
  94. */
  95. public abstract string create_table_sql(CreateTableOperation op);
  96. /**
  97. * Generates SQL for a DROP TABLE operation.
  98. *
  99. * @param op The drop table operation
  100. * @return The SQL DROP TABLE statement
  101. */
  102. public abstract string drop_table_sql(DropTableOperation op);
  103. /**
  104. * Generates SQL for an ADD COLUMN operation.
  105. *
  106. * @param op The add column operation
  107. * @return The SQL ALTER TABLE ADD COLUMN statement
  108. */
  109. public abstract string add_column_sql(AddColumnOperation op);
  110. /**
  111. * Generates SQL for a DROP COLUMN operation.
  112. *
  113. * @param op The drop column operation
  114. * @return The SQL ALTER TABLE DROP COLUMN statement
  115. */
  116. public abstract string drop_column_sql(DropColumnOperation op);
  117. /**
  118. * Generates SQL for a RENAME COLUMN operation.
  119. *
  120. * @param op The rename column operation
  121. * @return The SQL ALTER TABLE RENAME COLUMN statement
  122. */
  123. public abstract string rename_column_sql(RenameColumnOperation op);
  124. /**
  125. * Generates SQL for a CREATE INDEX operation.
  126. *
  127. * @param op The create index operation
  128. * @return The SQL CREATE INDEX statement
  129. */
  130. public abstract string create_index_sql(CreateIndexOperation op);
  131. /**
  132. * Generates SQL for a DROP INDEX operation.
  133. *
  134. * @param op The drop index operation
  135. * @return The SQL DROP INDEX statement
  136. */
  137. public abstract string drop_index_sql(DropIndexOperation op);
  138. /**
  139. * Generates SQL for a DROP FOREIGN KEY operation.
  140. *
  141. * Note: SQLite requires table recreation to drop constraints,
  142. * which is handled transparently by the dialect implementation.
  143. *
  144. * @param op The drop foreign key operation
  145. * @return The SQL statement(s) to drop the foreign key constraint
  146. */
  147. public abstract string drop_foreign_key_sql(DropForeignKeyOperation op);
  148. // Schema introspection methods
  149. /**
  150. * Introspects table schema from the database.
  151. *
  152. * This method queries the database to discover column metadata,
  153. * primary keys, auto-increment settings, and other schema information.
  154. *
  155. * @param connection The database connection
  156. * @param table_name The table to introspect
  157. * @return A TableSchema containing column metadata
  158. * @throws SqlError if introspection fails
  159. */
  160. public abstract TableSchema introspect_schema(Connection connection, string table_name) throws SqlError;
  161. // Projection query methods
  162. /**
  163. * Builds a SELECT statement with JOINs for a projection query.
  164. *
  165. * This method constructs a complete SELECT query from a ProjectionDefinition,
  166. * including all JOINs, selections, WHERE/HAVING clauses, GROUP BY, ORDER BY,
  167. * LIMIT, and OFFSET.
  168. *
  169. * @param definition The projection definition containing source, joins, and selections
  170. * @param translator The variable translator for alias resolution
  171. * @param where_clause Optional pre-built WHERE clause SQL
  172. * @param having_clause Optional pre-built HAVING clause SQL
  173. * @param order_by ORDER BY clauses
  174. * @param limit Optional LIMIT value
  175. * @param offset Optional OFFSET value
  176. * @return The complete SQL SELECT statement
  177. */
  178. public abstract string build_projection_select(
  179. ProjectionDefinition definition,
  180. VariableTranslator translator,
  181. string? where_clause,
  182. string? having_clause,
  183. Vector<OrderByClause> order_by,
  184. int64? limit,
  185. int64? offset
  186. );
  187. /**
  188. * Builds a subquery wrapper for mixed aggregate/non-aggregate OR conditions.
  189. *
  190. * When a WHERE clause contains OR conditions that mix aggregate and non-aggregate
  191. * expressions, SQL requires special handling. This method wraps the inner query
  192. * and applies the combined WHERE clause to the outer query.
  193. *
  194. * Example output:
  195. * {{{
  196. * SELECT * FROM (inner_query) subq WHERE combined_where
  197. * }}}
  198. *
  199. * @param inner_query The inner SELECT query
  200. * @param combined_where The WHERE clause to apply to the outer query
  201. * @return The wrapped query SQL
  202. */
  203. public abstract string wrap_subquery_for_mixed_or(
  204. string inner_query,
  205. string combined_where
  206. );
  207. /**
  208. * Generates a table alias with type information for debugging.
  209. *
  210. * The alias format includes an index and the entity type name to make
  211. * generated SQL more readable and easier to debug.
  212. *
  213. * Format: val_N_TypeName (e.g., val_1_User, val_2_Order)
  214. *
  215. * @param index The 1-based index for this alias
  216. * @param type_name The entity type name
  217. * @return The generated alias string
  218. */
  219. public abstract string generate_table_alias(int index, string type_name);
  220. }
  221. }