sequel-xtdb 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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