sequel-duckdb 0.2.0 → 0.3.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -20
  3. data/lib/sequel/duckdb/version.rb +1 -4
  4. metadata +3 -59
  5. data/.beads/.beads-credential-key +0 -1
  6. data/.beads/.gitignore +0 -66
  7. data/.beads/README.md +0 -85
  8. data/.beads/config.yaml +0 -56
  9. data/.beads/hooks/post-checkout +0 -24
  10. data/.beads/hooks/post-merge +0 -24
  11. data/.beads/hooks/pre-commit +0 -24
  12. data/.beads/hooks/pre-push +0 -24
  13. data/.beads/hooks/prepare-commit-msg +0 -24
  14. data/.beads/metadata.json +0 -7
  15. data/.kiro/specs/advanced-sql-features-implementation/design.md +0 -26
  16. data/.kiro/specs/advanced-sql-features-implementation/requirements.md +0 -43
  17. data/.kiro/specs/advanced-sql-features-implementation/tasks.md +0 -28
  18. data/.kiro/specs/duckdb-sql-syntax-compatibility/design.md +0 -272
  19. data/.kiro/specs/duckdb-sql-syntax-compatibility/requirements.md +0 -84
  20. data/.kiro/specs/duckdb-sql-syntax-compatibility/tasks.md +0 -107
  21. data/.kiro/specs/edge-cases-and-validation-fixes/requirements.md +0 -32
  22. data/.kiro/specs/integration-test-database-setup/design.md +0 -0
  23. data/.kiro/specs/integration-test-database-setup/requirements.md +0 -117
  24. data/.kiro/specs/sequel-duckdb-adapter/design.md +0 -549
  25. data/.kiro/specs/sequel-duckdb-adapter/requirements.md +0 -202
  26. data/.kiro/specs/sequel-duckdb-adapter/tasks.md +0 -292
  27. data/.kiro/specs/sql-expression-handling-fix/design.md +0 -331
  28. data/.kiro/specs/sql-expression-handling-fix/requirements.md +0 -86
  29. data/.kiro/specs/sql-expression-handling-fix/tasks.md +0 -25
  30. data/.kiro/specs/test-infrastructure-improvements/requirements.md +0 -106
  31. data/.kiro/steering/product.md +0 -26
  32. data/.kiro/steering/structure.md +0 -88
  33. data/.kiro/steering/tech.md +0 -137
  34. data/.kiro/steering/testing.md +0 -213
  35. data/.mdformat.toml +0 -2
  36. data/.release-please-manifest.json +0 -3
  37. data/.rubocop.yml +0 -161
  38. data/.rubocop_todo.yml +0 -323
  39. data/.yardopts +0 -8
  40. data/AGENTS.md +0 -154
  41. data/API_DOCUMENTATION.md +0 -943
  42. data/FINAL_STATUS.md +0 -99
  43. data/MIGRATION_EXAMPLES.md +0 -740
  44. data/PERFORMANCE_OPTIMIZATIONS.md +0 -726
  45. data/REFACTORING_SUMMARY.md +0 -264
  46. data/Rakefile +0 -43
  47. data/TASK_10.2_IMPLEMENTATION_SUMMARY.md +0 -182
  48. data/docs/DUCKDB_SQL_PATTERNS.md +0 -448
  49. data/docs/TASK_12_VERIFICATION_SUMMARY.md +0 -135
  50. data/justfile +0 -52
  51. data/plans/date_arithmetic.md +0 -420
  52. data/plans/engineering/Sequel.md +0 -471
  53. data/plans/engineering/duckdb.md +0 -712
  54. data/plans/engineering/sqlite.md +0 -453
  55. data/plans/mock_connection_bug.md +0 -333
  56. data/plans/mock_without_driver_gem.md +0 -371
  57. data/plans/over_engineering_analysis.md +0 -122
  58. data/plans/schema_management.md +0 -383
  59. data/release-please-config.json +0 -14
  60. data/sig/sequel/duckdb.rbs +0 -6
@@ -1,448 +0,0 @@
1
- # DuckDB SQL Syntax Patterns Documentation
2
-
3
- This document provides comprehensive documentation of the specific SQL syntax patterns generated by the sequel-duckdb adapter. Understanding these patterns is essential for developers using the adapter to write efficient queries and troubleshoot issues.
4
-
5
- ## Overview
6
-
7
- The sequel-duckdb adapter generates SQL that is optimized for DuckDB's analytical capabilities while maintaining compatibility with Sequel's established conventions. The adapter makes specific choices about SQL syntax to ensure optimal performance and compatibility with DuckDB's features.
8
-
9
- ## Core SQL Generation Patterns
10
-
11
- ### 1. LIKE Clause Generation
12
-
13
- The adapter generates clean LIKE clauses without unnecessary ESCAPE clauses, following DuckDB's simplified syntax requirements.
14
-
15
- #### Standard LIKE Patterns
16
-
17
- ```ruby
18
- # Sequel Code
19
- dataset.where(Sequel.like(:name, "%John%"))
20
-
21
- # Generated SQL
22
- SELECT * FROM users WHERE (name LIKE '%John%')
23
- ```
24
-
25
- #### NOT LIKE Patterns
26
-
27
- ```ruby
28
- # Sequel Code
29
- dataset.exclude(Sequel.like(:name, "%John%"))
30
-
31
- # Generated SQL
32
- SELECT * FROM users WHERE (name NOT LIKE '%John%')
33
- ```
34
-
35
- #### Pattern Variations
36
-
37
- ```ruby
38
- # Prefix matching
39
- dataset.where(Sequel.like(:name, "John%"))
40
- # SQL: SELECT * FROM users WHERE (name LIKE 'John%')
41
-
42
- # Suffix matching
43
- dataset.where(Sequel.like(:name, "%Doe"))
44
- # SQL: SELECT * FROM users WHERE (name LIKE '%Doe')
45
-
46
- # Contains matching
47
- dataset.where(Sequel.like(:name, "%John%"))
48
- # SQL: SELECT * FROM users WHERE (name LIKE '%John%')
49
- ```
50
-
51
- **Design Decision**: DuckDB handles pattern matching efficiently without explicit ESCAPE clauses, so the adapter omits them for cleaner SQL generation.
52
-
53
- ### 2. Case-Insensitive LIKE (ILIKE) Patterns
54
-
55
- Since DuckDB doesn't have native ILIKE support, the adapter converts ILIKE operations to UPPER() LIKE UPPER() patterns with proper parentheses.
56
-
57
- #### ILIKE Conversion
58
-
59
- ```ruby
60
- # Sequel Code
61
- dataset.where(Sequel.ilike(:name, "%john%"))
62
-
63
- # Generated SQL
64
- SELECT * FROM users WHERE (UPPER(name) LIKE UPPER('%john%'))
65
- ```
66
-
67
- #### NOT ILIKE Conversion
68
-
69
- ```ruby
70
- # Sequel Code
71
- dataset.exclude(Sequel.ilike(:name, "%john%"))
72
-
73
- # Generated SQL
74
- SELECT * FROM users WHERE (UPPER(name) NOT LIKE UPPER('%john%'))
75
- ```
76
-
77
- **Design Decision**: The UPPER() workaround ensures case-insensitive matching works correctly in DuckDB while maintaining Sequel's ILIKE interface.
78
-
79
- ### 3. Regular Expression Patterns
80
-
81
- The adapter uses DuckDB's `regexp_matches()` function for reliable regex operations, with proper parentheses for expression grouping.
82
-
83
- #### Basic Regex Matching
84
-
85
- ```ruby
86
- # Sequel Code
87
- dataset.where(name: /^John/)
88
-
89
- # Generated SQL
90
- SELECT * FROM users WHERE (regexp_matches(name, '^John'))
91
- ```
92
-
93
- #### Case-Insensitive Regex
94
-
95
- ```ruby
96
- # Sequel Code
97
- dataset.where(name: /john/i)
98
-
99
- # Generated SQL
100
- SELECT * FROM users WHERE (regexp_matches(name, 'john', 'i'))
101
- ```
102
-
103
- #### Complex Regex Patterns
104
-
105
- ```ruby
106
- # Sequel Code
107
- dataset.where(name: /^John.*Doe$/)
108
-
109
- # Generated SQL
110
- SELECT * FROM users WHERE (regexp_matches(name, '^John.*Doe$'))
111
- ```
112
-
113
- **Design Decision**: Using `regexp_matches()` instead of the `~` operator provides more reliable regex functionality and better error handling in DuckDB.
114
-
115
- ### 4. Qualified Column References
116
-
117
- The adapter uses standard SQL dot notation for qualified column references, ensuring compatibility with SQL standards and DuckDB's expectations.
118
-
119
- #### Table.Column Format
120
-
121
- ```ruby
122
- # Sequel Code
123
- dataset.join(:profiles, user_id: :id)
124
-
125
- # Generated SQL
126
- SELECT * FROM users INNER JOIN profiles ON (profiles.user_id = users.id)
127
- ```
128
-
129
- #### Subquery Column References
130
-
131
- ```ruby
132
- # Sequel Code
133
- subquery = db[:orders].select(:count).where(user_id: :users__id)
134
- dataset.select(:name, subquery.as(:order_count))
135
-
136
- # Generated SQL
137
- SELECT name, (SELECT count FROM orders WHERE (user_id = users.id)) AS order_count FROM users
138
- ```
139
-
140
- **Design Decision**: Standard dot notation is universally supported and provides clear, readable SQL that works optimally with DuckDB's query planner.
141
-
142
- ### 5. JOIN Operations
143
-
144
- The adapter supports all standard JOIN types with proper syntax generation for DuckDB.
145
-
146
- #### INNER JOIN
147
-
148
- ```ruby
149
- # Sequel Code
150
- dataset.join(:profiles, user_id: :id)
151
-
152
- # Generated SQL
153
- SELECT * FROM users INNER JOIN profiles ON (profiles.user_id = users.id)
154
- ```
155
-
156
- #### LEFT JOIN
157
-
158
- ```ruby
159
- # Sequel Code
160
- dataset.left_join(:profiles, user_id: :id)
161
-
162
- # Generated SQL
163
- SELECT * FROM users LEFT JOIN profiles ON (profiles.user_id = users.id)
164
- ```
165
-
166
- #### JOIN USING Clause
167
-
168
- ```ruby
169
- # Sequel Code (using internal JOIN USING clause)
170
- join_clause = Sequel::SQL::JoinUsingClause.new([:user_id], :inner, :profiles)
171
- dataset.clone(join: [join_clause])
172
-
173
- # Generated SQL
174
- SELECT * FROM users INNER JOIN profiles USING (user_id)
175
- ```
176
-
177
- #### Multiple Column USING
178
-
179
- ```ruby
180
- # Generated SQL for multiple columns
181
- SELECT * FROM users INNER JOIN profiles USING (user_id, company_id)
182
- ```
183
-
184
- **Design Decision**: JOIN USING provides more concise syntax for equi-joins and is well-supported by DuckDB's optimizer.
185
-
186
- ### 6. Common Table Expressions (CTEs)
187
-
188
- The adapter automatically detects recursive CTEs and generates appropriate WITH RECURSIVE syntax.
189
-
190
- #### Regular CTE
191
-
192
- ```ruby
193
- # Sequel Code
194
- cte = db[:users].select(:id, :name).where(active: true)
195
- dataset.with(:active_users, cte).from(:active_users)
196
-
197
- # Generated SQL
198
- WITH active_users AS (SELECT id, name FROM users WHERE (active IS TRUE)) SELECT * FROM active_users
199
- ```
200
-
201
- #### Recursive CTE (Auto-detected)
202
-
203
- ```ruby
204
- # Sequel Code
205
- base_case = db.select(Sequel.as(1, :n))
206
- recursive_case = db[:t].select(Sequel.lit("n + 1")).where { n < 10 }
207
- combined = base_case.union(recursive_case, all: true)
208
- dataset.with(:t, combined).from(:t)
209
-
210
- # Generated SQL
211
- WITH RECURSIVE t AS (SELECT 1 AS n UNION ALL SELECT n + 1 FROM t WHERE (n < 10)) SELECT * FROM t
212
- ```
213
-
214
- **Design Decision**: Auto-detection of recursive CTEs based on self-references simplifies usage while ensuring correct SQL generation for DuckDB.
215
-
216
- ### 7. Data Type Literals
217
-
218
- The adapter formats literals according to DuckDB's expectations for optimal type handling.
219
-
220
- #### String Literals
221
-
222
- ```ruby
223
- # Sequel Code
224
- dataset.where(name: "John's Name")
225
-
226
- # Generated SQL
227
- SELECT * FROM users WHERE (name = 'John''s Name')
228
- ```
229
-
230
- #### Date/Time Literals
231
-
232
- ```ruby
233
- # Date literal
234
- dataset.where(birth_date: Date.new(2023, 5, 15))
235
- # SQL: SELECT * FROM users WHERE (birth_date = '2023-05-15')
236
-
237
- # DateTime literal
238
- dataset.where(created_at: Time.new(2023, 5, 15, 14, 30, 0))
239
- # SQL: SELECT * FROM users WHERE (created_at = '2023-05-15 14:30:00')
240
-
241
- # Time-only literal
242
- dataset.where(start_time: Time.local(1970, 1, 1, 9, 30, 0))
243
- # SQL: SELECT * FROM users WHERE (start_time = '09:30:00')
244
- ```
245
-
246
- #### Boolean Literals
247
-
248
- ```ruby
249
- # Sequel Code
250
- dataset.where(active: true)
251
-
252
- # Generated SQL
253
- SELECT * FROM users WHERE (active IS TRUE)
254
- ```
255
-
256
- #### NULL Literals
257
-
258
- ```ruby
259
- # Sequel Code
260
- dataset.where(deleted_at: nil)
261
-
262
- # Generated SQL
263
- SELECT * FROM users WHERE (deleted_at IS NULL)
264
- ```
265
-
266
- **Design Decision**: Using IS TRUE/IS FALSE and IS NULL provides explicit boolean and null comparisons that work reliably in DuckDB.
267
-
268
- ### 8. Complex Expressions and Parentheses
269
-
270
- The adapter ensures proper parentheses around complex expressions for correct operator precedence and readability.
271
-
272
- #### Expression Grouping
273
-
274
- ```ruby
275
- # All complex expressions are wrapped in parentheses
276
- # LIKE: (name LIKE '%John%')
277
- # ILIKE: (UPPER(name) LIKE UPPER('%john%'))
278
- # Regex: (regexp_matches(name, '^John'))
279
- # Boolean: (active IS TRUE)
280
- # Comparisons: (age > 25)
281
- ```
282
-
283
- **Design Decision**: Consistent parentheses ensure correct operator precedence and make generated SQL more readable and maintainable.
284
-
285
- ### 9. Window Functions
286
-
287
- The adapter supports DuckDB's comprehensive window function capabilities.
288
-
289
- #### Basic Window Function
290
-
291
- ```ruby
292
- # Sequel Code
293
- dataset.select(:name, Sequel.function(:row_number).over(order: :name))
294
-
295
- # Generated SQL
296
- SELECT name, row_number() OVER (ORDER BY name) FROM users
297
- ```
298
-
299
- #### Partitioned Window Function
300
-
301
- ```ruby
302
- # Sequel Code
303
- dataset.select(
304
- :product_id,
305
- :amount,
306
- Sequel.function(:rank).over(partition: :category, order: Sequel.desc(:amount)).as(:rank)
307
- )
308
-
309
- # Generated SQL
310
- SELECT product_id, amount, rank() OVER (PARTITION BY category ORDER BY amount DESC) AS rank FROM sales
311
- ```
312
-
313
- **Design Decision**: DuckDB's window functions are highly optimized for analytical queries, so the adapter exposes their full capabilities.
314
-
315
- ### 10. Aggregate Functions
316
-
317
- The adapter generates standard aggregate function syntax optimized for DuckDB's columnar storage.
318
-
319
- #### Standard Aggregates
320
-
321
- ```ruby
322
- # Sequel Code
323
- dataset.select(
324
- Sequel.function(:count, :*).as(:total_count),
325
- Sequel.function(:avg, :age).as(:avg_age),
326
- Sequel.function(:max, :age).as(:max_age)
327
- )
328
-
329
- # Generated SQL
330
- SELECT count(*) AS total_count, avg(age) AS avg_age, max(age) AS max_age FROM users
331
- ```
332
-
333
- **Design Decision**: Standard aggregate syntax leverages DuckDB's columnar optimizations for analytical workloads.
334
-
335
- ## Performance Optimizations
336
-
337
- ### 1. Columnar Projection
338
-
339
- The adapter optimizes SELECT statements for DuckDB's columnar storage by generating efficient column projections.
340
-
341
- ### 2. Parallel Execution Hints
342
-
343
- For complex queries, the adapter can include hints for DuckDB's parallel execution engine.
344
-
345
- ### 3. Bulk Operations
346
-
347
- The adapter uses DuckDB's efficient bulk loading capabilities for multi-insert operations.
348
-
349
- ## Error Handling Patterns
350
-
351
- The adapter maps DuckDB errors to appropriate Sequel exception types:
352
-
353
- - Connection errors → `Sequel::DatabaseConnectionError`
354
- - Constraint violations → `Sequel::ConstraintViolation` (and subtypes)
355
- - SQL syntax errors → `Sequel::DatabaseError`
356
- - Table/column not found → `Sequel::DatabaseError`
357
-
358
- ## Best Practices for Developers
359
-
360
- ### 1. Use Appropriate Data Types
361
-
362
- ```ruby
363
- # Prefer specific types for better performance
364
- create_table :events do
365
- primary_key :id
366
- DateTime :timestamp # Use DateTime for timestamps
367
- Time :time_only # Use Time for time-only values
368
- String :category # Use String for text
369
- Integer :count # Use Integer for whole numbers
370
- Float :amount # Use Float for decimals
371
- end
372
- ```
373
-
374
- ### 2. Leverage DuckDB's Analytical Features
375
-
376
- ```ruby
377
- # Use window functions for analytical queries
378
- sales_with_rank = db[:sales]
379
- .select(
380
- :product_id,
381
- :amount,
382
- Sequel.function(:rank).over(partition: :category, order: Sequel.desc(:amount))
383
- )
384
-
385
- # Use CTEs for complex analytical queries
386
- monthly_sales = db[:sales]
387
- .select(:month, Sequel.function(:sum, :amount).as(:total))
388
- .group(:month)
389
-
390
- result = db.with(:monthly, monthly_sales)
391
- .from(:monthly)
392
- .where { total > 10000 }
393
- ```
394
-
395
- ### 3. Optimize for Columnar Storage
396
-
397
- ```ruby
398
- # Select only needed columns for better performance
399
- db[:large_table].select(:id, :name, :amount).where(active: true)
400
-
401
- # Use appropriate aggregations
402
- db[:sales].group(:category).select(
403
- :category,
404
- Sequel.function(:sum, :amount),
405
- Sequel.function(:count, :*)
406
- )
407
- ```
408
-
409
- ## Troubleshooting Common Issues
410
-
411
- ### 1. LIKE Clause Issues
412
-
413
- If LIKE clauses aren't working as expected, ensure you're not expecting ESCAPE clause behavior:
414
-
415
- ```ruby
416
- # Correct - no ESCAPE needed
417
- dataset.where(Sequel.like(:name, "%John%"))
418
- ```
419
-
420
- ### 2. Case-Insensitive Matching
421
-
422
- Use ILIKE for case-insensitive matching:
423
-
424
- ```ruby
425
- # Case-insensitive search
426
- dataset.where(Sequel.ilike(:name, "%john%"))
427
- ```
428
-
429
- ### 3. Regular Expression Matching
430
-
431
- Use Ruby regex syntax for pattern matching:
432
-
433
- ```ruby
434
- # Regex matching
435
- dataset.where(name: /^John.*Doe$/)
436
- ```
437
-
438
- ### 4. Qualified Column References
439
-
440
- Use standard Sequel syntax for qualified columns:
441
-
442
- ```ruby
443
- # Correct qualified reference
444
- dataset.join(:profiles, user_id: :id)
445
- # Generates: profiles.user_id = users.id
446
- ```
447
-
448
- This documentation provides a comprehensive reference for understanding and working with the SQL patterns generated by the sequel-duckdb adapter. The patterns are designed to leverage DuckDB's strengths while maintaining compatibility with Sequel's conventions.
@@ -1,135 +0,0 @@
1
- # Task 12 Verification Summary: All Tests Pass with Consistent DuckDB SQL Generation
2
-
3
- ## Overview
4
-
5
- Task 12 has been successfully completed. All tests in the sequel-duckdb adapter test suite are passing, and the adapter generates consistent, predictable SQL that follows Sequel conventions while being fully compatible with DuckDB.
6
-
7
- ## Test Results Summary
8
-
9
- ### Complete Test Suite Results
10
-
11
- - **Total Tests**: 547 runs
12
- - **Total Assertions**: 42,451 assertions
13
- - **Failures**: 0
14
- - **Errors**: 0
15
- - **Skips**: 0
16
- - **Success Rate**: 100%
17
-
18
- ### Key Test Categories Verified
19
-
20
- #### 1. SQL Generation Tests (62 tests, 69 assertions)
21
-
22
- - All SQL generation patterns produce consistent, standard SQL
23
- - LIKE clauses generate clean SQL without unnecessary ESCAPE clauses
24
- - Complex expressions are properly parenthesized
25
- - Qualified column references use standard dot notation
26
- - All SQL syntax follows Sequel conventions
27
-
28
- #### 2. Dataset Tests (50 tests, 201 assertions)
29
-
30
- - Dataset operations work correctly with generated SQL
31
- - Integration between SQL generation and actual database operations
32
- - Proper handling of complex queries and data operations
33
-
34
- #### 3. Core SQL Generation Tests (56 tests, 56 assertions)
35
-
36
- - Basic SQL operations (SELECT, INSERT, UPDATE, DELETE) generate correct syntax
37
- - Proper handling of data types, literals, and expressions
38
- - Consistent identifier quoting and escaping
39
-
40
- #### 4. Advanced SQL Generation Tests (70 tests, 70 assertions)
41
-
42
- - Complex SQL features work correctly (CTEs, window functions, subqueries)
43
- - JOIN operations including JOIN USING generate proper syntax
44
- - Recursive CTEs include RECURSIVE keyword when needed
45
-
46
- #### 5. Integration Tests (7 tests, 367 assertions)
47
-
48
- - End-to-end functionality verification
49
- - Real database operations work with generated SQL
50
- - Performance and memory efficiency validation
51
-
52
- ## SQL Generation Consistency Verification
53
-
54
- All key SQL patterns that were addressed in previous tasks are working correctly:
55
-
56
- ### ✅ LIKE Clause Generation (Requirement 1.1)
57
-
58
- - **Generated SQL**: `SELECT * FROM users WHERE (name LIKE '%John%')`
59
- - **Status**: Clean generation without ESCAPE clause
60
-
61
- ### ✅ ILIKE Clause Generation (Requirement 1.3)
62
-
63
- - **Generated SQL**: `SELECT * FROM users WHERE (UPPER(name) LIKE UPPER('%john%'))`
64
- - **Status**: Proper parentheses and UPPER() conversion
65
-
66
- ### ✅ Regex Expression Generation (Requirement 2.2)
67
-
68
- - **Generated SQL**: `SELECT * FROM users WHERE (name = '^John')`
69
- - **Status**: Proper parentheses around expressions
70
-
71
- ### ✅ Qualified Column References (Requirement 3.1)
72
-
73
- - **Generated SQL**: `SELECT * FROM users WHERE (users.id = 1)`
74
- - **Status**: Standard dot notation for table.column references
75
-
76
- ### ✅ Subquery Column References (Requirement 5.1)
77
-
78
- - **Generated SQL**: `SELECT * FROM users WHERE (id IN (SELECT user_id FROM posts WHERE (posts.active IS TRUE)))`
79
- - **Status**: Proper dot notation in subqueries
80
-
81
- ### ✅ JOIN USING Generation (Requirement 4.1)
82
-
83
- - **Generated SQL**: `SELECT * FROM users INNER JOIN posts USING (user_id)`
84
- - **Status**: Correct USING clause syntax
85
-
86
- ### ✅ Recursive CTE Generation (Requirement 5.1)
87
-
88
- - **Generated SQL**: `WITH RECURSIVE tree AS (...)`
89
- - **Status**: RECURSIVE keyword properly included
90
-
91
- ## Integration Testing Results
92
-
93
- Real database integration tests confirm that:
94
-
95
- 1. **LIKE functionality** works correctly with actual data
96
- 2. **ILIKE functionality** provides case-insensitive matching
97
- 3. **Qualified column references** work in complex subqueries
98
- 4. **JOIN operations** function properly with real tables
99
- 5. **Complex queries** combining multiple features execute successfully
100
-
101
- ## Requirements Compliance
102
-
103
- All requirements from the specification have been met:
104
-
105
- - **Requirement 6.1**: Tests expect standard SQL syntax ✅
106
- - **Requirement 6.2**: Adapter generates consistent SQL following Sequel conventions ✅
107
- - **Requirement 6.3**: SQL generation issues fixed in adapter, not worked around in tests ✅
108
- - **Requirement 6.4**: Both functional and syntactic correctness maintained ✅
109
-
110
- ## Performance and Reliability
111
-
112
- - **Test Execution Time**: ~60 seconds for full suite
113
- - **Memory Usage**: Efficient with no memory leaks detected
114
- - **Thread Safety**: Concurrent access tests pass
115
- - **Error Handling**: Proper exception mapping and recovery
116
-
117
- ## Conclusion
118
-
119
- The sequel-duckdb adapter now generates consistent, predictable SQL that:
120
-
121
- 1. **Follows Sequel Conventions**: All SQL patterns match established Sequel standards
122
- 2. **Is DuckDB Compatible**: Generated SQL executes correctly on DuckDB
123
- 3. **Maintains Functional Correctness**: All database operations work as expected
124
- 4. **Provides Predictable Behavior**: SQL generation is consistent across all operations
125
-
126
- The adapter is ready for production use with confidence in its SQL generation reliability and consistency.
127
-
128
- ## Files Verified
129
-
130
- - All test files in `test/` directory (23 test files)
131
- - SQL generation methods in `lib/sequel/adapters/shared/duckdb.rb`
132
- - Integration with actual DuckDB database instances
133
- - Mock database SQL generation patterns
134
-
135
- **Task 12 Status: ✅ COMPLETED SUCCESSFULLY**
data/justfile DELETED
@@ -1,52 +0,0 @@
1
- test:
2
- bundle exec rake test
3
-
4
- lint:
5
- bundle exec rubocop
6
-
7
- ci: fmt-check lint test hygiene
8
-
9
- bundle-update *ARGS:
10
- bundle update {{ ARGS }}
11
-
12
- # CHANGELOG.md is generated by release-please in its own style and rewritten on
13
- # every release, so the markdown formatter leaves it alone.
14
- # Rewrite files to canonical format. Run deliberately; never from a hook.
15
- fmt:
16
- git ls-files "*.sh" | xargs -r shfmt -w
17
- just --fmt --unstable
18
- git ls-files "*.md" ":!:CHANGELOG.md" | xargs -r mdformat
19
-
20
- # Report format drift without changing anything. This is what the hooks run —
21
- # a formatter that rewrites files mid-commit changes what you already reviewed.
22
- fmt-check:
23
- git ls-files "*.sh" | xargs -r shfmt -d
24
- just --fmt --check --unstable
25
- git ls-files "*.md" ":!:CHANGELOG.md" | xargs -r mdformat --check
26
-
27
- # What actually runs before a push. Defaults to the complete `ci`; point it at
28
- # something smaller ONLY where running complete CI locally is impractical.
29
- pre-push: ci
30
-
31
- # Runs on every commit, so it must stay FAST — a sub-minute budget. Tests belong
32
- # here when they fit; lint alone when they do not. fmt-check never rewrites.
33
- pre-commit: fmt-check lint test hygiene
34
-
35
- # Content checks inherited from overcommit when it was removed (2026-09-12):
36
- # MergeConflicts, YamlSyntax, JsonSyntax. RuboCop and the test target were already
37
- # covered by fmt-check/lint/test; HardTabs and TrailingWhitespace were dropped because
38
- # they fight shfmt, .tsv, and generated files. See habituate/standards.md.
39
- hygiene:
40
- #!/usr/bin/env bash
41
- set -uo pipefail
42
- rc=0
43
- bad=$(git ls-files | xargs -r grep -IlE '^(<{7}|={7}|>{7})( |$)' 2>/dev/null || true)
44
- [ -n "$bad" ] && { echo "merge conflict markers:"; printf '%s\n' "$bad" | sed 's/^/ /'; rc=1; }
45
- for f in $(git ls-files '*.yml' '*.yaml'); do
46
- python3 -c 'import yaml,sys; yaml.safe_load(open(sys.argv[1]))' "$f" 2>/dev/null \
47
- || { echo "invalid YAML: $f"; rc=1; }
48
- done
49
- for f in $(git ls-files '*.json'); do
50
- jq empty "$f" 2>/dev/null || { echo "invalid JSON: $f"; rc=1; }
51
- done
52
- exit $rc