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 +4 -4
- data/.envrc +7 -0
- data/README.md +30 -1
- data/lib/sequel/adapters/shared/xtdb.rb +92 -0
- data/lib/sequel/adapters/xtdb.rb +15 -0
- data/lib/sequel/xtdb/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: feef2fdeeefa8b1adfd9d214aab772c02250814aa8e6ef36a79bc7eddc4a8386
|
4
|
+
data.tar.gz: 417e16888185230ad9f7714b7d0d322594457f6f0d8645c033a9203463103293
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28456e08dfc22572d63a5de8dbfba0b8f849a78478f1ec43336e2495212a4217bacf665d53faf7f205d54c75ef8df931064288dd079bf496dd85389bcb3d1911
|
7
|
+
data.tar.gz: cb4e306b7641e07812e146843d982104e143935c83d58ffc7cd480246f1dec99fc0f5946fa2ebd964eed4c50e338051785fa772119fe497d156cf88e82e2925c
|
data/.envrc
ADDED
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:
|
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
|
data/lib/sequel/adapters/xtdb.rb
CHANGED
@@ -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
|
data/lib/sequel/xtdb/version.rb
CHANGED
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.
|
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-
|
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
|