sequel-xtdb 0.2.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b33179262aa907817cbbf65cb0980a19bea740bc3bda9ab569a10fd49544e25
4
- data.tar.gz: 25b43d46d3e1f2c9ceb846f6d09590d600a2fea2a9bad02cae930cc457494105
3
+ metadata.gz: feef2fdeeefa8b1adfd9d214aab772c02250814aa8e6ef36a79bc7eddc4a8386
4
+ data.tar.gz: 417e16888185230ad9f7714b7d0d322594457f6f0d8645c033a9203463103293
5
5
  SHA512:
6
- metadata.gz: 5603a63bd7d20916755c3e4375ed4a5162832925c3615f0ac72459e1f37d46f3bd32a96b686cc1e09075f48c4cc766582750eb6e7b4c8e0961bb8c621c10eaed
7
- data.tar.gz: 418b300f8ab58dbeda2b786953911eed8ddece9885132833f0b328e5f551ac79ca81e18751b5ab6668b9ca5e40b483b51ab5237a4630f581f858d5c325c111f6
6
+ metadata.gz: 28456e08dfc22572d63a5de8dbfba0b8f849a78478f1ec43336e2495212a4217bacf665d53faf7f205d54c75ef8df931064288dd079bf496dd85389bcb3d1911
7
+ data.tar.gz: cb4e306b7641e07812e146843d982104e143935c83d58ffc7cd480246f1dec99fc0f5946fa2ebd964eed4c50e338051785fa772119fe497d156cf88e82e2925c
data/.envrc ADDED
@@ -0,0 +1,7 @@
1
+ # env-var using [direnv](https://github.com/direnv/direnv)
2
+ PATH_add bin
3
+
4
+ export XTDB_URL=xtdb://localhost:5432/xtdb
5
+
6
+ # put overrides in .envrc.local
7
+ source_env_if_exists .envrc.local
data/README.md CHANGED
@@ -24,7 +24,7 @@ Shortcut to happiness:
24
24
  $ sequel 'xtdb://localhost:5432/xtdb'
25
25
 
26
26
  # ..or from repl/your project
27
- DB = Sequel.connect("xtdb://localhost:54321/xtdb")
27
+ DB = Sequel.connect("xtdb://localhost:5432/xtdb")
28
28
 
29
29
  # then
30
30
  irb(main)> DB << "insert into products(_id, name, price) values(1, 'Spam', 1000), (2, 'Ham', 1200)"
@@ -32,6 +32,35 @@ irb(main)> DB["select * from products"].all
32
32
  => [{:_id=>2, :name=>"Ham", :price=>1200}, {:_id=>1, :name=>"Spam", :price=>1100}]
33
33
  ```
34
34
 
35
+ ### time-travel
36
+
37
+ _these examples use the [activesupport time helpers](https://api.rubyonrails.org/classes/ActiveSupport/Duration.html)_
38
+
39
+ ```ruby
40
+ DB = Sequel.connect("xtdb://localhost:5432/xtdb")
41
+
42
+ # get a dataset (ie query)
43
+ users = DB[:users]
44
+ past, future = 2.days.ago, 2.days.from_now
45
+ ds1, ds2 = users.as_of(valid: past), users.as_of(valid: future)
46
+
47
+ # expect empty
48
+ ds1.all
49
+ ds1.insert(_id: 1, name: "James")
50
+
51
+ # expect a user
52
+ ds1.as_of(valid: 2.days.ago).all
53
+
54
+ # add to future
55
+ ds2.insert(_id: 2, name: "Jeremy")
56
+
57
+ # expect only James
58
+ users.all
59
+ # expect both James and Jeremy
60
+ ds2.as_of(valid: 2.days.from_now).all
61
+ ```
62
+
63
+
35
64
  ## Status
36
65
 
37
66
  Very early days :)
@@ -4,9 +4,101 @@ module Sequel
4
4
  def database_type
5
5
  :xtdb
6
6
  end
7
+
8
+ def primary_key(_table)
9
+ # eg used for RETURNING on insert (prevents crash)
10
+ :_id
11
+ end
12
+
13
+ # Get a dataset with `current`, `valid` and `system` set.
14
+ #
15
+ # For selects this creates the SETTING pre-amble, e.g. 'SETTING DEFAULT VALID_TIME ...':
16
+ # ```
17
+ # DB.as_of(current: 2.weeks.ago).select(Sequel.lit('current_timestamp')).single_value
18
+ # ```
19
+ #
20
+ # A block can be provided as a convenience to stay in SQL-land (selects only):
21
+ # ```
22
+ # DB.as_of(current: 2.hours.ago) do
23
+ # DB["select current_timestamp"]
24
+ # end.sql
25
+ # =>
26
+ # SETTING
27
+ # CURRENT_TIME TO TIMESTAMP '2024-12-17T12:59:48+01:00'
28
+ # select current_timestamp
29
+ # ```
30
+ #
31
+ # When doing inserts, the `_valid_from` will be added (if not provided):
32
+ # ```
33
+ # DB[:products].as_of(valid: 2.weeks.ago).insert(_id: 1, name: 'Spam')
34
+ # ```
35
+ def as_of(...)
36
+ ds = @default_dataset.as_of(...)
37
+ return ds unless block_given?
38
+
39
+ yield.clone(append_sql: ds.select_setting_sql(""))
40
+ end
7
41
  end
8
42
 
9
43
  module DatasetMethods
44
+ Dataset.def_sql_method(self, :select,
45
+ [["if opts[:values]",
46
+ %w[values compounds order limit]],
47
+ ["else",
48
+ %w[setting select distinct columns from join where group having compounds order limit lock]]])
49
+
50
+ def as_of(valid: nil, system: nil, current: nil)
51
+ {valid: valid, system: system, current: current}.reject { |_k, v| v.nil? }.then do |opts|
52
+ clone(opts)
53
+ end
54
+ end
55
+
56
+ def server_version
57
+ 0
58
+ end
59
+
60
+ def insert_values_sql(sql)
61
+ if (from_ix = opts[:columns].index(:_valid_from))
62
+ opts[:values][from_ix] = Sequel.lit("TIMESTAMP ?", opts[:values][from_ix])
63
+ end
64
+
65
+ if (to_ix = opts[:columns].index(:_valid_to))
66
+ opts[:values][to_ix] = Sequel.lit("TIMESTAMP ?", opts[:values][to_ix])
67
+ end
68
+
69
+ super
70
+ end
71
+
72
+ def insert_columns_sql(sql)
73
+ if opts[:valid] && !opts[:columns].index(:_valid_from)
74
+ opts[:columns] << :_valid_from
75
+ opts[:values] << opts[:valid]
76
+ end
77
+ super
78
+ end
79
+
80
+ def select_setting_sql(sql)
81
+ setting = opts.slice(:current, :valid, :system)
82
+ return sql if setting.empty?
83
+
84
+ cast_value = ->(v) do
85
+ case v
86
+ when DateTime, Time
87
+ literal_append "TIMESTAMP ", v.iso8601
88
+ when Date
89
+ literal_append "DATE ", v.iso8601
90
+ end
91
+ end
92
+ sql << "SETTING "
93
+ sql << setting.map do |k, v|
94
+ if k == :current
95
+ literal_append "CURRENT_TIME TO TIMESTAMP ", v.iso8601
96
+ else
97
+ "DEFAULT #{k.upcase}_TIME AS OF #{cast_value[v]}"
98
+ end
99
+ end.join(", ")
100
+ sql << " "
101
+ end
10
102
  end
11
103
  end
12
104
  end
@@ -13,6 +13,15 @@ module Sequel
13
13
  def adapter_initialize
14
14
  # XTDB can't handle this SET-command
15
15
  @opts[:force_standard_strings] = false
16
+
17
+ Sequel.database_timezone = :utc
18
+ Sequel.application_timezone = :local
19
+
20
+ if (app_tz = @opts[:application_timezone])
21
+ Sequel.extension(:named_timezones)
22
+ Sequel.application_timezone = app_tz
23
+ end
24
+
16
25
  super
17
26
  end
18
27
 
@@ -23,6 +32,12 @@ module Sequel
23
32
 
24
33
  class Dataset < Sequel::Postgres::Dataset
25
34
  include ::Sequel::XTDB::DatasetMethods
35
+
36
+ private
37
+
38
+ def default_timestamp_format
39
+ "'%Y-%m-%d %H:%M:%S'"
40
+ end
26
41
  end
27
42
  end
28
43
  end
@@ -3,6 +3,6 @@
3
3
  module Sequel
4
4
  module XTDB
5
5
  # NOTE when releasing the git-tag will replace the version below
6
- VERSION = "0.2.1"
6
+ VERSION = "0.3.0"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-xtdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gert Goet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-13 00:00:00.000000000 Z
11
+ date: 2024-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".envrc"
48
49
  - ".rspec"
49
50
  - ".standard.yml"
50
51
  - CHANGELOG.md