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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9366806f0dee7b0277dfee65be6c4718c339b6e9ab53e595e1f88534d5144534
4
- data.tar.gz: 3b3c01d575bb8d0c380b49cbbc8b6deb62cc7de5542449dc73d0fd3b5ccffb1f
3
+ metadata.gz: 98460f8bbd24007057521ad2749899aebd4e689c0183ab98551e7c0e9d7b8ffe
4
+ data.tar.gz: 726ea12c95079c99999b9415fb915e05818548bcab38647413eee44018c2a7f3
5
5
  SHA512:
6
- metadata.gz: 2e1fb28d47b8efeedaedba54727d678bdf946efd6aac1001ae0a2ad9aa9fbdc5b28bf8df06b2a10be13f6684195e2f684eafe71c7bedb27b36eff7af36d65abf
7
- data.tar.gz: 4feea1505445b4347e722ea31d87c6dd9ed759489550f7a69997fced7b9a45827b4beaa81c4bc5e12abb801226af82f1c4903aff5ab6fd4b0851b6772b2c83c3
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 = 1", ["Test", 1])
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
@@ -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
- read_only: false # experimental
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
@@ -1,3 +1,3 @@
1
1
  module DuckLake
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ducklake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane