sequel-duckdb 0.2.1 → 0.3.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/sequel/adapters/duckdb.rb +3 -3
- data/lib/sequel/adapters/shared/duckdb.rb +17 -17
- data/lib/sequel/duckdb/version.rb +1 -1
- metadata +21 -60
- data/.beads/.beads-credential-key +0 -1
- data/.beads/.gitignore +0 -66
- data/.beads/README.md +0 -85
- data/.beads/config.yaml +0 -56
- data/.beads/hooks/post-checkout +0 -24
- data/.beads/hooks/post-merge +0 -24
- data/.beads/hooks/pre-commit +0 -24
- data/.beads/hooks/pre-push +0 -24
- data/.beads/hooks/prepare-commit-msg +0 -24
- data/.beads/metadata.json +0 -7
- data/.kiro/specs/advanced-sql-features-implementation/design.md +0 -26
- data/.kiro/specs/advanced-sql-features-implementation/requirements.md +0 -43
- data/.kiro/specs/advanced-sql-features-implementation/tasks.md +0 -28
- data/.kiro/specs/duckdb-sql-syntax-compatibility/design.md +0 -272
- data/.kiro/specs/duckdb-sql-syntax-compatibility/requirements.md +0 -84
- data/.kiro/specs/duckdb-sql-syntax-compatibility/tasks.md +0 -107
- data/.kiro/specs/edge-cases-and-validation-fixes/requirements.md +0 -32
- data/.kiro/specs/integration-test-database-setup/design.md +0 -0
- data/.kiro/specs/integration-test-database-setup/requirements.md +0 -117
- data/.kiro/specs/sequel-duckdb-adapter/design.md +0 -549
- data/.kiro/specs/sequel-duckdb-adapter/requirements.md +0 -202
- data/.kiro/specs/sequel-duckdb-adapter/tasks.md +0 -292
- data/.kiro/specs/sql-expression-handling-fix/design.md +0 -331
- data/.kiro/specs/sql-expression-handling-fix/requirements.md +0 -86
- data/.kiro/specs/sql-expression-handling-fix/tasks.md +0 -25
- data/.kiro/specs/test-infrastructure-improvements/requirements.md +0 -106
- data/.kiro/steering/product.md +0 -26
- data/.kiro/steering/structure.md +0 -88
- data/.kiro/steering/tech.md +0 -137
- data/.kiro/steering/testing.md +0 -213
- data/.mdformat.toml +0 -2
- data/.rubocop.yml +0 -161
- data/.rubocop_todo.yml +0 -323
- data/.yardopts +0 -8
- data/AGENTS.md +0 -180
- data/API_DOCUMENTATION.md +0 -943
- data/FINAL_STATUS.md +0 -99
- data/MIGRATION_EXAMPLES.md +0 -740
- data/PERFORMANCE_OPTIMIZATIONS.md +0 -726
- data/REFACTORING_SUMMARY.md +0 -264
- data/Rakefile +0 -43
- data/TASK_10.2_IMPLEMENTATION_SUMMARY.md +0 -182
- data/docs/DUCKDB_SQL_PATTERNS.md +0 -448
- data/docs/TASK_12_VERIFICATION_SUMMARY.md +0 -135
- data/justfile +0 -50
- data/plans/date_arithmetic.md +0 -420
- data/plans/engineering/Sequel.md +0 -471
- data/plans/engineering/duckdb.md +0 -712
- data/plans/engineering/sqlite.md +0 -453
- data/plans/mock_connection_bug.md +0 -333
- data/plans/mock_without_driver_gem.md +0 -371
- data/plans/over_engineering_analysis.md +0 -122
- data/plans/schema_management.md +0 -383
- data/sig/sequel/duckdb.rbs +0 -6
data/plans/schema_management.md
DELETED
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
# Schema Management Implementation Plan
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Implement DuckDB schema management functionality in the sequel-duckdb adapter to support creating, dropping, and managing schemas. This plan addresses schema operations that are natively supported by DuckDB.
|
|
6
|
-
|
|
7
|
-
## Background Research
|
|
8
|
-
|
|
9
|
-
### DuckDB Schema Support
|
|
10
|
-
|
|
11
|
-
DuckDB supports SQL schema management with the following capabilities:
|
|
12
|
-
|
|
13
|
-
1. **CREATE SCHEMA**
|
|
14
|
-
|
|
15
|
-
- Basic: `CREATE SCHEMA s1;`
|
|
16
|
-
- Conditional: `CREATE SCHEMA IF NOT EXISTS s2;`
|
|
17
|
-
- Replace: `CREATE OR REPLACE SCHEMA s2;`
|
|
18
|
-
- Default schema is `main`
|
|
19
|
-
|
|
20
|
-
2. **DROP SCHEMA**
|
|
21
|
-
|
|
22
|
-
- Basic: `DROP SCHEMA sch;`
|
|
23
|
-
- Conditional: `DROP SCHEMA IF EXISTS sch;`
|
|
24
|
-
- With cascade: `DROP SCHEMA sch CASCADE;`
|
|
25
|
-
- Dependency tracking for tables, views, functions, indexes, sequences, types, macros
|
|
26
|
-
- Note: Dependencies are NOT tracked for views (limitation)
|
|
27
|
-
|
|
28
|
-
3. **Schema Usage**
|
|
29
|
-
|
|
30
|
-
- Tables can be created in schemas: `CREATE TABLE s1.t (id INTEGER);`
|
|
31
|
-
- Cross-schema queries are supported
|
|
32
|
-
- Schemas provide logical namespaces for organizing database objects
|
|
33
|
-
|
|
34
|
-
### DuckDB Database Support
|
|
35
|
-
|
|
36
|
-
**Important Finding**: DuckDB does NOT support traditional `CREATE DATABASE` or `DROP DATABASE` commands.
|
|
37
|
-
|
|
38
|
-
Instead, DuckDB uses:
|
|
39
|
-
|
|
40
|
-
- **ATTACH DATABASE**: Attach existing database files to current session
|
|
41
|
-
- `ATTACH 'file.db' AS alias;`
|
|
42
|
-
- `ATTACH 'file.db' (READ_ONLY);`
|
|
43
|
-
- Not persisted between sessions
|
|
44
|
-
- **DETACH DATABASE**: Detach database files from current session
|
|
45
|
-
- Database creation happens implicitly when opening a connection to a file path
|
|
46
|
-
|
|
47
|
-
### Sequel Schema Support
|
|
48
|
-
|
|
49
|
-
Sequel provides schema management methods (primarily in PostgreSQL adapter):
|
|
50
|
-
|
|
51
|
-
1. **create_schema(name, opts={})**
|
|
52
|
-
|
|
53
|
-
- Creates a schema
|
|
54
|
-
- Options: `:if_not_exists`, `:owner` (PostgreSQL-specific)
|
|
55
|
-
|
|
56
|
-
2. **create_schema_sql(name, opts={})**
|
|
57
|
-
|
|
58
|
-
- Generates CREATE SCHEMA SQL
|
|
59
|
-
|
|
60
|
-
3. **drop_schema(name, opts={})**
|
|
61
|
-
|
|
62
|
-
- Drops a schema
|
|
63
|
-
- Calls `remove_all_cached_schemas` to clear caches
|
|
64
|
-
- Options: `:if_exists`, `:cascade`
|
|
65
|
-
|
|
66
|
-
4. **drop_schema_sql(name, opts={})**
|
|
67
|
-
|
|
68
|
-
- Generates DROP SCHEMA SQL
|
|
69
|
-
|
|
70
|
-
5. **rename_schema(name, new_name)** (PostgreSQL-specific)
|
|
71
|
-
|
|
72
|
-
- Renames a schema
|
|
73
|
-
|
|
74
|
-
6. **remove_all_cached_schemas**
|
|
75
|
-
|
|
76
|
-
- Clears cached schema information
|
|
77
|
-
- Resets `@primary_keys`, `@primary_key_sequences`, `@schemas`
|
|
78
|
-
|
|
79
|
-
## Implementation Plan
|
|
80
|
-
|
|
81
|
-
### Phase 1: Core Schema Operations
|
|
82
|
-
|
|
83
|
-
Implement basic schema creation and deletion in `DatabaseMethods` module:
|
|
84
|
-
|
|
85
|
-
#### 1.1 `create_schema(name, opts={})`
|
|
86
|
-
|
|
87
|
-
```ruby
|
|
88
|
-
def create_schema(name, opts=OPTS)
|
|
89
|
-
self << create_schema_sql(name, opts)
|
|
90
|
-
end
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Supported options:**
|
|
94
|
-
|
|
95
|
-
- `:if_not_exists` - Add IF NOT EXISTS clause
|
|
96
|
-
|
|
97
|
-
**Not supported (PostgreSQL-specific):**
|
|
98
|
-
|
|
99
|
-
- `:owner` - DuckDB doesn't support AUTHORIZATION/OWNER syntax
|
|
100
|
-
|
|
101
|
-
#### 1.2 `create_schema_sql(name, opts={})`
|
|
102
|
-
|
|
103
|
-
```ruby
|
|
104
|
-
def create_schema_sql(name, opts=OPTS)
|
|
105
|
-
sql = "CREATE"
|
|
106
|
-
sql += " OR REPLACE" if opts[:or_replace]
|
|
107
|
-
sql += " SCHEMA"
|
|
108
|
-
sql += " IF NOT EXISTS" if opts[:if_not_exists]
|
|
109
|
-
sql += " #{quote_identifier(name)}"
|
|
110
|
-
sql
|
|
111
|
-
end
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**DuckDB-specific considerations:**
|
|
115
|
-
|
|
116
|
-
- Support both `IF NOT EXISTS` and `OR REPLACE`
|
|
117
|
-
- Cannot use both simultaneously (mutually exclusive)
|
|
118
|
-
|
|
119
|
-
#### 1.3 `drop_schema(name, opts={})`
|
|
120
|
-
|
|
121
|
-
```ruby
|
|
122
|
-
def drop_schema(name, opts=OPTS)
|
|
123
|
-
self << drop_schema_sql(name, opts)
|
|
124
|
-
remove_all_cached_schemas
|
|
125
|
-
end
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
**Supported options:**
|
|
129
|
-
|
|
130
|
-
- `:if_exists` - Add IF EXISTS clause
|
|
131
|
-
- `:cascade` - Add CASCADE clause to drop dependent objects
|
|
132
|
-
|
|
133
|
-
#### 1.4 `drop_schema_sql(name, opts={})`
|
|
134
|
-
|
|
135
|
-
```ruby
|
|
136
|
-
def drop_schema_sql(name, opts=OPTS)
|
|
137
|
-
sql = "DROP SCHEMA"
|
|
138
|
-
sql += " IF EXISTS" if opts[:if_exists]
|
|
139
|
-
sql += " #{quote_identifier(name)}"
|
|
140
|
-
sql += " CASCADE" if opts[:cascade]
|
|
141
|
-
sql
|
|
142
|
-
end
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
#### 1.5 `remove_all_cached_schemas`
|
|
146
|
-
|
|
147
|
-
```ruby
|
|
148
|
-
def remove_all_cached_schemas
|
|
149
|
-
@schema_cache = {}
|
|
150
|
-
@schemas = {}
|
|
151
|
-
@primary_keys = {}
|
|
152
|
-
@primary_key_sequences = {}
|
|
153
|
-
end
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**Important**: All cache variables MUST be initialized as empty hashes (`{}`), not `nil`. Sequel's internal `remove_cached_schema` method expects `@schemas` to be a Hash and will call `.delete()` on it. Setting it to `nil` will cause a `NoMethodError` when `create_view` or other methods call `remove_cached_schema` internally.
|
|
157
|
-
|
|
158
|
-
**Note**: DuckDB adapter uses `@schema_cache` for caching schema information (see line 505-510 in shared/duckdb.rb). Need to clear this when schemas are modified.
|
|
159
|
-
|
|
160
|
-
### Phase 2: Schema Introspection
|
|
161
|
-
|
|
162
|
-
Implement methods to list and inspect schemas:
|
|
163
|
-
|
|
164
|
-
#### 2.1 `schemas(opts={})`
|
|
165
|
-
|
|
166
|
-
```ruby
|
|
167
|
-
def schemas(opts=OPTS)
|
|
168
|
-
sql = "SELECT schema_name FROM information_schema.schemata"
|
|
169
|
-
sql += " WHERE catalog_name = ?" if opts[:catalog]
|
|
170
|
-
|
|
171
|
-
schemas = []
|
|
172
|
-
execute(sql, opts[:catalog] ? [opts[:catalog]] : []) do |row|
|
|
173
|
-
schemas << row[:schema_name].to_sym
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
schemas
|
|
177
|
-
end
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### 2.2 `schema_exists?(name, opts={})`
|
|
181
|
-
|
|
182
|
-
```ruby
|
|
183
|
-
def schema_exists?(name, opts=OPTS)
|
|
184
|
-
sql = "SELECT 1 FROM information_schema.schemata WHERE schema_name = ? LIMIT 1"
|
|
185
|
-
|
|
186
|
-
result = nil
|
|
187
|
-
execute(sql, [name.to_s]) do |_row|
|
|
188
|
-
result = true
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
!!result
|
|
192
|
-
end
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Phase 3: Database File Operations (ATTACH/DETACH)
|
|
196
|
-
|
|
197
|
-
**Decision**: Do NOT implement `create_database` / `drop_database` because:
|
|
198
|
-
|
|
199
|
-
1. DuckDB doesn't support these SQL commands
|
|
200
|
-
2. Database creation is implicit (happens when connecting to a file path)
|
|
201
|
-
3. ATTACH/DETACH are session-specific, not DDL operations
|
|
202
|
-
4. These operations are outside the scope of typical Sequel adapter functionality
|
|
203
|
-
|
|
204
|
-
Instead, document that users should:
|
|
205
|
-
|
|
206
|
-
- Use connection strings to create/open database files
|
|
207
|
-
- Use ATTACH/DETACH via raw SQL if needed: `db.run("ATTACH 'other.db' AS other")`
|
|
208
|
-
|
|
209
|
-
### Phase 4: Testing
|
|
210
|
-
|
|
211
|
-
Create comprehensive tests for schema operations:
|
|
212
|
-
|
|
213
|
-
#### 4.1 Schema Creation Tests
|
|
214
|
-
|
|
215
|
-
- Test basic CREATE SCHEMA
|
|
216
|
-
- Test CREATE SCHEMA IF NOT EXISTS
|
|
217
|
-
- Test CREATE OR REPLACE SCHEMA
|
|
218
|
-
- Test error handling for duplicate schemas (without IF NOT EXISTS)
|
|
219
|
-
|
|
220
|
-
#### 4.2 Schema Deletion Tests
|
|
221
|
-
|
|
222
|
-
- Test basic DROP SCHEMA (empty schema)
|
|
223
|
-
- Test DROP SCHEMA IF EXISTS
|
|
224
|
-
- Test DROP SCHEMA CASCADE (with dependent objects)
|
|
225
|
-
- Test error handling for non-existent schemas (without IF EXISTS)
|
|
226
|
-
- Test dependency error (dropping schema with objects, without CASCADE)
|
|
227
|
-
|
|
228
|
-
#### 4.3 Schema Introspection Tests
|
|
229
|
-
|
|
230
|
-
- Test listing all schemas
|
|
231
|
-
- Test schema_exists? for existing and non-existing schemas
|
|
232
|
-
- Test that default 'main' schema exists
|
|
233
|
-
|
|
234
|
-
#### 4.4 Schema Usage Tests
|
|
235
|
-
|
|
236
|
-
- Test creating tables in custom schemas
|
|
237
|
-
- Test cross-schema queries
|
|
238
|
-
- Test that schema cache is properly cleared after drop
|
|
239
|
-
|
|
240
|
-
#### 4.5 Edge Cases
|
|
241
|
-
|
|
242
|
-
- Test schema names that require quoting (with special characters)
|
|
243
|
-
- Test schema names that are reserved words
|
|
244
|
-
- Test mutually exclusive options (:if_not_exists vs :or_replace)
|
|
245
|
-
|
|
246
|
-
### Phase 5: Documentation
|
|
247
|
-
|
|
248
|
-
#### 5.1 Update README
|
|
249
|
-
|
|
250
|
-
Add section on schema management:
|
|
251
|
-
|
|
252
|
-
```markdown
|
|
253
|
-
## Schema Management
|
|
254
|
-
|
|
255
|
-
sequel-duckdb supports DuckDB's schema functionality:
|
|
256
|
-
|
|
257
|
-
### Creating Schemas
|
|
258
|
-
db.create_schema(:analytics)
|
|
259
|
-
db.create_schema(:staging, if_not_exists: true)
|
|
260
|
-
db.create_schema(:temp, or_replace: true)
|
|
261
|
-
|
|
262
|
-
### Dropping Schemas
|
|
263
|
-
db.drop_schema(:analytics)
|
|
264
|
-
db.drop_schema(:staging, if_exists: true)
|
|
265
|
-
db.drop_schema(:temp, cascade: true) # Drops all objects in schema
|
|
266
|
-
|
|
267
|
-
### Listing Schemas
|
|
268
|
-
db.schemas # => [:main, :analytics, :staging]
|
|
269
|
-
|
|
270
|
-
### Using Schemas
|
|
271
|
-
db.create_table(Sequel[:analytics][:sales]) do
|
|
272
|
-
primary_key :id
|
|
273
|
-
String :product
|
|
274
|
-
Numeric :amount
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
db[:analytics__sales].insert(product: 'Widget', amount: 99.99)
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
#### 5.2 Document Limitations
|
|
281
|
-
|
|
282
|
-
- DuckDB does not support schema ownership/authorization
|
|
283
|
-
- DuckDB does not support renaming schemas (no ALTER SCHEMA RENAME)
|
|
284
|
-
- View dependencies are not tracked by DuckDB
|
|
285
|
-
|
|
286
|
-
## Implementation Checklist
|
|
287
|
-
|
|
288
|
-
- [x] Phase 1: Core schema operations
|
|
289
|
-
|
|
290
|
-
- [x] Implement `create_schema(name, opts={})`
|
|
291
|
-
- [x] Implement `create_schema_sql(name, opts={})`
|
|
292
|
-
- [x] Implement `drop_schema(name, opts={})`
|
|
293
|
-
- [x] Implement `drop_schema_sql(name, opts={})`
|
|
294
|
-
- [x] Implement `remove_all_cached_schemas`
|
|
295
|
-
- [x] Add validation for mutually exclusive options
|
|
296
|
-
|
|
297
|
-
- [x] Phase 2: Schema introspection
|
|
298
|
-
|
|
299
|
-
- [x] Implement `schemas(opts={})`
|
|
300
|
-
- [x] Implement `schema_exists?(name, opts={})`
|
|
301
|
-
|
|
302
|
-
- [x] Phase 3: Document ATTACH/DETACH approach
|
|
303
|
-
|
|
304
|
-
- [x] Add documentation for database file operations
|
|
305
|
-
- [x] Explain why create_database/drop_database are not implemented
|
|
306
|
-
|
|
307
|
-
- [x] Phase 4: Testing
|
|
308
|
-
|
|
309
|
-
- [x] Write schema creation tests (6 tests)
|
|
310
|
-
- [x] Write schema deletion tests (6 tests)
|
|
311
|
-
- [x] Write schema introspection tests (5 tests)
|
|
312
|
-
- [x] Write schema usage tests (4 tests)
|
|
313
|
-
- [x] Write edge case tests (3 tests)
|
|
314
|
-
- [x] Write cache clearing tests (3 tests)
|
|
315
|
-
- [x] Add regression test for `remove_cached_schema` compatibility
|
|
316
|
-
|
|
317
|
-
- [x] Phase 5: Documentation
|
|
318
|
-
|
|
319
|
-
- [x] Update README with schema management section
|
|
320
|
-
- [x] Document limitations
|
|
321
|
-
- [x] Add examples for common use cases
|
|
322
|
-
- [x] Document ATTACH/DETACH for multiple database files
|
|
323
|
-
|
|
324
|
-
## Implementation Summary
|
|
325
|
-
|
|
326
|
-
### Completed Features
|
|
327
|
-
|
|
328
|
-
All planned features have been implemented and tested:
|
|
329
|
-
|
|
330
|
-
1. **Core Schema Operations** (`lib/sequel/adapters/shared/duckdb.rb`)
|
|
331
|
-
|
|
332
|
-
- `create_schema(name, opts={})` - Lines 1191-1193
|
|
333
|
-
- `create_schema_sql(name, opts={})` - Lines 1202-1214
|
|
334
|
-
- `drop_schema(name, opts={})` - Lines 1227-1230
|
|
335
|
-
- `drop_schema_sql(name, opts={})` - Lines 1239-1245
|
|
336
|
-
- `remove_all_cached_schemas` - Lines 1257-1262
|
|
337
|
-
|
|
338
|
-
2. **Schema Introspection** (`lib/sequel/adapters/shared/duckdb.rb`)
|
|
339
|
-
|
|
340
|
-
- `schemas(opts={})` - Lines 1270-1280
|
|
341
|
-
- `schema_exists?(name, opts={})` - Lines 1291-1300
|
|
342
|
-
|
|
343
|
-
3. **Comprehensive Test Suite** (`test/schema_management_test.rb`)
|
|
344
|
-
|
|
345
|
-
- 38 tests covering all functionality
|
|
346
|
-
- All tests passing
|
|
347
|
-
- Regression tests to prevent cache-related bugs
|
|
348
|
-
|
|
349
|
-
4. **Documentation** (`README.md`)
|
|
350
|
-
|
|
351
|
-
- Complete schema management section
|
|
352
|
-
- Usage examples
|
|
353
|
-
- Limitations documented
|
|
354
|
-
- ATTACH/DETACH examples
|
|
355
|
-
|
|
356
|
-
### Bug Fixes
|
|
357
|
-
|
|
358
|
-
- **Cache initialization bug**: Fixed `remove_all_cached_schemas` to initialize cache variables as empty hashes instead of `nil`. This prevents `NoMethodError` when Sequel's `remove_cached_schema` is called internally by methods like `create_view`.
|
|
359
|
-
|
|
360
|
-
### Test Results
|
|
361
|
-
|
|
362
|
-
- **Schema management tests**: 38 tests, 73 assertions, 0 failures
|
|
363
|
-
- **Full test suite**: 539 tests, 2362 assertions, 0 failures
|
|
364
|
-
|
|
365
|
-
### Files Modified
|
|
366
|
-
|
|
367
|
-
- `lib/sequel/adapters/shared/duckdb.rb` - Added schema management methods
|
|
368
|
-
- `test/schema_management_test.rb` - New comprehensive test file
|
|
369
|
-
- `README.md` - Added schema management documentation section
|
|
370
|
-
|
|
371
|
-
## Related Files
|
|
372
|
-
|
|
373
|
-
- Implementation: `lib/sequel/adapters/shared/duckdb.rb` (DatabaseMethods module)
|
|
374
|
-
- Tests: `spec/sequel/adapters/duckdb_spec.rb` or new `spec/schema_management_spec.rb`
|
|
375
|
-
- Documentation: `README.md`
|
|
376
|
-
|
|
377
|
-
## References
|
|
378
|
-
|
|
379
|
-
- [DuckDB CREATE SCHEMA](https://duckdb.org/docs/stable/sql/statements/create_schema.html)
|
|
380
|
-
- [DuckDB DROP Statement](https://duckdb.org/docs/stable/sql/statements/drop.html)
|
|
381
|
-
- [DuckDB ATTACH/DETACH](https://duckdb.org/docs/stable/sql/statements/attach.html)
|
|
382
|
-
- [Sequel PostgreSQL Adapter](https://github.com/jeremyevans/sequel/blob/master/lib/sequel/adapters/shared/postgres.rb)
|
|
383
|
-
- [Sequel Schema Modification Docs](https://github.com/jeremyevans/sequel/blob/master/doc/schema_modification.rdoc)
|