ducklake 0.1.2 → 0.1.3
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 +8 -0
- data/README.md +14 -2
- data/lib/ducklake/client.rb +73 -2
- data/lib/ducklake/version.rb +1 -1
- data/lib/ducklake.rb +2 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98460f8bbd24007057521ad2749899aebd4e689c0183ab98551e7c0e9d7b8ffe
|
4
|
+
data.tar.gz: 726ea12c95079c99999b9415fb915e05818548bcab38647413eee44018c2a7f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 772924fb6262d3a3373eb2e92431b55dc73f81869e2aaf1a92746831c1d784f669a9e82a03a8c4d2538bda7c7980e940cd29f65c068ca996ea71a55c19d37dbd
|
7
|
+
data.tar.gz: c57170ee010ea949d4f8c250f3ff4fcc05a3153b1e25d9412ba12cd53e4ef7e866f088e2956886948757e0586f4005087e50c89fff1295404ce4c01baae79ce1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 0.1.3 (2025-09-23)
|
2
|
+
|
3
|
+
- Added `current_snapshot` and `last_committed_snapshot` methods
|
4
|
+
- Added `rewrite_data_files` and `delete_orphaned_files` methods
|
5
|
+
- Added `commit_message` and `commit_author` options to `transaction` method
|
6
|
+
- Added `migrate_if_required` option
|
7
|
+
- Added experimental support for encryption
|
8
|
+
|
1
9
|
## 0.1.2 (2025-08-23)
|
2
10
|
|
3
11
|
- Added `transaction` method
|
data/README.md
CHANGED
@@ -154,7 +154,7 @@ Note: This transfers ownership to the data lake, so the file may be deleted as p
|
|
154
154
|
Update data
|
155
155
|
|
156
156
|
```ruby
|
157
|
-
ducklake.sql("UPDATE events SET name = ? WHERE id =
|
157
|
+
ducklake.sql("UPDATE events SET name = ? WHERE id = ?", ["Test", 1])
|
158
158
|
```
|
159
159
|
|
160
160
|
Delete data
|
@@ -215,7 +215,7 @@ Query the data at a specific snapshot version or time
|
|
215
215
|
|
216
216
|
```ruby
|
217
217
|
ducklake.sql("SELECT * FROM events AT (VERSION => ?)", [3])
|
218
|
-
#
|
218
|
+
# or
|
219
219
|
ducklake.sql("SELECT * FROM events AT (TIMESTAMP => ?)", [Date.today - 7])
|
220
220
|
```
|
221
221
|
|
@@ -326,6 +326,16 @@ quoted_file = ducklake.quote("path/to/data.csv")
|
|
326
326
|
ducklake.sql("COPY #{quoted_table} FROM #{quoted_file}")
|
327
327
|
```
|
328
328
|
|
329
|
+
## Encryption
|
330
|
+
|
331
|
+
Note: This feature is unreleased and must be set when creating the catalog
|
332
|
+
|
333
|
+
Encrypt Parquet files
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
DuckLake::Client.new(encryption: true, ...)
|
337
|
+
```
|
338
|
+
|
329
339
|
## Polars
|
330
340
|
|
331
341
|
Note: This feature is experimental and does not currently work on tables with schema changes
|
@@ -402,10 +412,12 @@ bundle install
|
|
402
412
|
|
403
413
|
# Postgres
|
404
414
|
createdb ducklake_ruby_test
|
415
|
+
createdb ducklake_ruby_test2
|
405
416
|
bundle exec rake test:postgres
|
406
417
|
|
407
418
|
# MySQL and MariaDB
|
408
419
|
mysqladmin create ducklake_ruby_test
|
420
|
+
mysqladmin create ducklake_ruby_test2
|
409
421
|
bundle exec rake test:mysql
|
410
422
|
|
411
423
|
# SQLite
|
data/lib/ducklake/client.rb
CHANGED
@@ -8,7 +8,10 @@ module DuckLake
|
|
8
8
|
snapshot_time: nil,
|
9
9
|
data_inlining_row_limit: 0,
|
10
10
|
create_if_not_exists: false,
|
11
|
-
|
11
|
+
migrate_if_required: true, # TODO make false in 0.2.0
|
12
|
+
read_only: false, # experimental
|
13
|
+
override_storage_url: false, # experimental
|
14
|
+
encrypted: false # experimental
|
12
15
|
)
|
13
16
|
catalog_uri = URI.parse(catalog_url)
|
14
17
|
storage_uri = URI.parse(storage_url)
|
@@ -58,10 +61,13 @@ module DuckLake
|
|
58
61
|
|
59
62
|
attach_options = {data_path: storage_url}
|
60
63
|
attach_options[:read_only] = true if read_only
|
64
|
+
attach_options[:encrypted] = 1 if encrypted
|
61
65
|
attach_options[:snapshot_version] = snapshot_version if !snapshot_version.nil?
|
62
66
|
attach_options[:snapshot_time] = snapshot_time if !snapshot_time.nil?
|
63
67
|
attach_options[:data_inlining_row_limit] = data_inlining_row_limit if data_inlining_row_limit > 0
|
64
68
|
attach_options[:create_if_not_exists] = false unless create_if_not_exists
|
69
|
+
attach_options[:migrate_if_required] = false unless migrate_if_required
|
70
|
+
attach_options[:override_data_path] = true if override_storage_url
|
65
71
|
|
66
72
|
@catalog = "ducklake"
|
67
73
|
@storage_url = storage_url
|
@@ -106,10 +112,11 @@ module DuckLake
|
|
106
112
|
execute(sql, params)
|
107
113
|
end
|
108
114
|
|
109
|
-
def transaction
|
115
|
+
def transaction(commit_message: nil, commit_author: nil)
|
110
116
|
execute("BEGIN")
|
111
117
|
begin
|
112
118
|
yield
|
119
|
+
set_commit_message(commit_message, commit_author) if commit_message || commit_author
|
113
120
|
execute("COMMIT")
|
114
121
|
rescue => e
|
115
122
|
execute("ROLLBACK")
|
@@ -182,6 +189,14 @@ module DuckLake
|
|
182
189
|
symbolize_keys execute("SELECT * FROM ducklake_snapshots(?)", [@catalog])
|
183
190
|
end
|
184
191
|
|
192
|
+
def current_snapshot
|
193
|
+
execute("SELECT * FROM ducklake_current_snapshot(?)", [@catalog]).rows[0][0]
|
194
|
+
end
|
195
|
+
|
196
|
+
def last_committed_snapshot
|
197
|
+
execute("SELECT * FROM ducklake_last_committed_snapshot(?)", [@catalog]).rows[0][0]
|
198
|
+
end
|
199
|
+
|
185
200
|
# https://ducklake.select/docs/stable/duckdb/usage/configuration
|
186
201
|
def options
|
187
202
|
symbolize_keys execute("SELECT * FROM ducklake_options(?)", [@catalog])
|
@@ -257,6 +272,55 @@ module DuckLake
|
|
257
272
|
symbolize_keys execute("CALL ducklake_cleanup_old_files(#{args.join(", ")})", params)
|
258
273
|
end
|
259
274
|
|
275
|
+
# https://ducklake.select/docs/stable/duckdb/maintenance/cleanup_of_files#cleanup-of-orphaned-files
|
276
|
+
def delete_orphaned_files(cleanup_all: false, older_than: nil, dry_run: false)
|
277
|
+
args = ["?"]
|
278
|
+
params = [@catalog]
|
279
|
+
|
280
|
+
if cleanup_all
|
281
|
+
args << "cleanup_all => ?"
|
282
|
+
params << cleanup_all
|
283
|
+
end
|
284
|
+
|
285
|
+
if !older_than.nil?
|
286
|
+
args << "older_than => ?"
|
287
|
+
params << older_than
|
288
|
+
end
|
289
|
+
|
290
|
+
if dry_run
|
291
|
+
args << "dry_run => ?"
|
292
|
+
params << dry_run
|
293
|
+
end
|
294
|
+
|
295
|
+
symbolize_keys execute("CALL ducklake_delete_orphaned_files(#{args.join(", ")})", params)
|
296
|
+
end
|
297
|
+
|
298
|
+
# https://ducklake.select/docs/stable/duckdb/maintenance/rewrite_data_files
|
299
|
+
def rewrite_data_files(table = nil, delete_threshold: nil)
|
300
|
+
args = ["?"]
|
301
|
+
params = [@catalog]
|
302
|
+
|
303
|
+
if !table.nil?
|
304
|
+
args << "?"
|
305
|
+
params << table
|
306
|
+
end
|
307
|
+
|
308
|
+
if !delete_threshold.nil?
|
309
|
+
args << "delete_threshold => ?"
|
310
|
+
params << delete_threshold
|
311
|
+
end
|
312
|
+
|
313
|
+
execute("CALL ducklake_rewrite_data_files(#{args.join(", ")})", params)
|
314
|
+
nil
|
315
|
+
end
|
316
|
+
|
317
|
+
# experimental
|
318
|
+
# https://ducklake.select/docs/stable/duckdb/maintenance/checkpoint
|
319
|
+
def checkpoint
|
320
|
+
execute("CHECKPOINT")
|
321
|
+
nil
|
322
|
+
end
|
323
|
+
|
260
324
|
# https://ducklake.select/docs/stable/duckdb/advanced_features/data_inlining
|
261
325
|
def flush_inlined_data(table_name: nil)
|
262
326
|
args = ["?"]
|
@@ -397,8 +461,10 @@ module DuckLake
|
|
397
461
|
|
398
462
|
def error_mapping
|
399
463
|
@error_mapping ||= {
|
464
|
+
"Binder Error: " => BinderError,
|
400
465
|
"Catalog Error: " => CatalogError,
|
401
466
|
"Conversion Error: " => ConversionError,
|
467
|
+
"Invalid Configuration Error: " => InvalidConfigurationError,
|
402
468
|
"Invalid Input Error: " => InvalidInputError,
|
403
469
|
"IO Error: " => IOError,
|
404
470
|
"Not implemented Error: " => NotImplementedError,
|
@@ -442,6 +508,11 @@ module DuckLake
|
|
442
508
|
name
|
443
509
|
end
|
444
510
|
|
511
|
+
def set_commit_message(message, author)
|
512
|
+
execute("CALL ducklake_set_commit_message(?, ?, ?)", [@catalog, author, message])
|
513
|
+
nil
|
514
|
+
end
|
515
|
+
|
445
516
|
def symbolize_keys(result)
|
446
517
|
result.map { |v| v.transform_keys(&:to_sym) }
|
447
518
|
end
|
data/lib/ducklake/version.rb
CHANGED
data/lib/ducklake.rb
CHANGED
@@ -11,8 +11,10 @@ require_relative "ducklake/version"
|
|
11
11
|
|
12
12
|
module DuckLake
|
13
13
|
class Error < StandardError; end
|
14
|
+
class BinderError < Error; end
|
14
15
|
class CatalogError < Error; end
|
15
16
|
class ConversionError < Error; end
|
17
|
+
class InvalidConfigurationError < Error; end
|
16
18
|
class InvalidInputError < Error; end
|
17
19
|
class IOError < Error; end
|
18
20
|
class NotImplementedError < Error; end
|