sequel-xtdb 0.2.1 → 0.3.2

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: d0f7d61f6d6a7c9ccb319122b964eb284815e959dfc2fa2b529f00195e2b8c91
4
+ data.tar.gz: 142f6c92856959dff66759cabef3c5cfbbe480eafda22d50ccc62d1e7178ebdb
5
5
  SHA512:
6
- metadata.gz: 5603a63bd7d20916755c3e4375ed4a5162832925c3615f0ac72459e1f37d46f3bd32a96b686cc1e09075f48c4cc766582750eb6e7b4c8e0961bb8c621c10eaed
7
- data.tar.gz: 418b300f8ab58dbeda2b786953911eed8ddece9885132833f0b328e5f551ac79ca81e18751b5ab6668b9ca5e40b483b51ab5237a4630f581f858d5c325c111f6
6
+ metadata.gz: '0089ee3ce060d52540bac403359f66e334630787f1314a238482a28a8c2c49dd9415655d49c3d653cb8acefd052640d2c337f62b41e30f89ca3edd822625ca36'
7
+ data.tar.gz: 0f9a8848f64aba9c29424c073add18d6e64f78430add511866ce02b428254b741926ab89787473acfe8c72b9137ae6f61b0a8b1e2640b1fd8c346003faf4b8ba
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
@@ -1,6 +1,8 @@
1
- # Sequel::XTDB
1
+ # sequel-xtdb
2
2
 
3
- Adapter to connect to XTDB v2 using Sequel.
3
+ [![Gem Version](https://badge.fury.io/rb/sequel-xtdb.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/sequel-xtdb)
4
+
5
+ Adapter to connect to [XTDB](https://docs.xtdb.com/) v2 using [Sequel](https://sequel.jeremyevans.net/).
4
6
 
5
7
  ## Installation
6
8
 
@@ -24,7 +26,7 @@ Shortcut to happiness:
24
26
  $ sequel 'xtdb://localhost:5432/xtdb'
25
27
 
26
28
  # ..or from repl/your project
27
- DB = Sequel.connect("xtdb://localhost:54321/xtdb")
29
+ DB = Sequel.connect("xtdb://localhost:5432/xtdb")
28
30
 
29
31
  # then
30
32
  irb(main)> DB << "insert into products(_id, name, price) values(1, 'Spam', 1000), (2, 'Ham', 1200)"
@@ -32,17 +34,47 @@ irb(main)> DB["select * from products"].all
32
34
  => [{:_id=>2, :name=>"Ham", :price=>1200}, {:_id=>1, :name=>"Spam", :price=>1100}]
33
35
  ```
34
36
 
37
+ ### time-travel
38
+
39
+ ```ruby
40
+ def shift_days(n, from: Time.now)= from + (60 * 60 * 24 * n)
41
+ DB = Sequel.connect("xtdb://localhost:5432/xtdb")
42
+
43
+ # get a dataset (ie query)
44
+ users = DB[:users]
45
+ ds1, ds2 = users.as_of(valid: shift_days(-2)), users.as_of(valid: shift_days(2))
46
+
47
+ # expect empty
48
+ ds1.all
49
+ ds1.insert(_id: 1, name: "James")
50
+
51
+ # expect a user
52
+ ds1.as_of(valid: shift_days(-1)).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: shift_days(3)).all
61
+ ```
62
+
35
63
  ## Status
36
64
 
37
- Very early days :)
38
- Currently it's essentially the postgres-adapter with support for a xtdb-scheme url.
65
+ Very early days :)
39
66
 
40
67
 
41
68
  ## Development
42
69
 
43
70
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
44
71
 
45
- You can also run `bin/console [xtdb-url]` for an interactive prompt that will allow you to experiment. The script will pick up on env-var `XTDB_URL`, though the argument takes precedence.
72
+ You can also run `bin/console [xtdb-url]` for an interactive prompt that will allow you to experiment. The script will pick up on env-var `XTDB_URL`, though the argument takes precedence. The console-script sets up (query-)logging.
73
+
74
+ Speaking of logging: best to start the XTDB docker container with debug-logging:
75
+ ```
76
+ docker run -it --pull=always -e XTDB_LOGGING_LEVEL=debug -v $PWD/tmp/db:/var/lib/xtdb -p 6543:3000 -p 5432:5432 ghcr.io/xtdb/xtdb:nightly
77
+ ```
46
78
 
47
79
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
80
 
@@ -1,12 +1,125 @@
1
+ require "sequel/adapters/utils/unmodified_identifiers"
2
+
1
3
  module Sequel
2
4
  module XTDB
5
+ Sequel::Database.set_shared_adapter_scheme :xtdb, self
6
+
7
+ def self.mock_adapter_setup(db)
8
+ db.instance_exec do
9
+ @server_version = 0
10
+
11
+ # def schema_parse_table(*)
12
+ # []
13
+ # end
14
+ # singleton_class.send(:private, :schema_parse_table)
15
+ # adapter_initialize
16
+ # extend(MockAdapterDatabaseMethods)
17
+ end
18
+ end
19
+
3
20
  module DatabaseMethods
21
+ include UnmodifiedIdentifiers::DatabaseMethods # ensure lowercase identifiers
22
+
4
23
  def database_type
5
24
  :xtdb
6
25
  end
26
+
27
+ def primary_key(_table)
28
+ # eg used for RETURNING on insert (prevents crash)
29
+ :_id
30
+ end
31
+
32
+ # Get a dataset with `current`, `valid` and `system` set.
33
+ def as_of(...)
34
+ @default_dataset.as_of(...)
35
+ end
7
36
  end
8
37
 
9
38
  module DatasetMethods
39
+ include UnmodifiedIdentifiers::DatasetMethods # ensure lowercase identifiers
40
+
41
+ Dataset.def_sql_method(self, :select,
42
+ [["if opts[:values]",
43
+ %w[values compounds order limit]],
44
+ ["else",
45
+ %w[select distinct columns from join where group having compounds order limit lock]]])
46
+
47
+ def as_of(valid: nil, system: nil, current: nil)
48
+ {valid: valid, system: system, current: current}.reject { |_k, v| v.nil? }.then do |opts|
49
+ clone(opts)
50
+ end
51
+ end
52
+
53
+ def server_version
54
+ # TODO 2_000_000 from xt.version() output
55
+ # requires all def_sql_methods
56
+ 0
57
+ end
58
+
59
+ def insert_values_sql(sql)
60
+ if (from_ix = opts[:columns].index(:_valid_from))
61
+ opts[:values][from_ix] = Sequel.lit("TIMESTAMP ?", opts[:values][from_ix])
62
+ end
63
+
64
+ if (to_ix = opts[:columns].index(:_valid_to))
65
+ opts[:values][to_ix] = Sequel.lit("TIMESTAMP ?", opts[:values][to_ix])
66
+ end
67
+
68
+ super
69
+ end
70
+
71
+ def insert_columns_sql(sql)
72
+ if opts[:valid] && !opts[:columns].index(:_valid_from)
73
+ opts[:columns] << :_valid_from
74
+ opts[:values] << opts[:valid]
75
+ end
76
+ super
77
+ end
78
+
79
+ def select_sql
80
+ sql = super
81
+
82
+ if (setting = select_setting_sql)
83
+ if sql.frozen?
84
+ setting += sql
85
+ setting.freeze
86
+ elsif @opts[:append_sql] || @opts[:placeholder_literalizer]
87
+ setting << sql
88
+ else
89
+ setting + sql
90
+ end
91
+ else
92
+ sql
93
+ end
94
+ end
95
+
96
+ def select_setting_sql
97
+ setting = opts.slice(:current, :valid, :system)
98
+ return if setting.empty?
99
+
100
+ cast_value = ->(v) do
101
+ type = case v
102
+ when DateTime, Time then "TIMESTAMP"
103
+ when Date then "DATE"
104
+ end
105
+ literal_append "#{type} ", v.iso8601
106
+ end
107
+ sql = "SETTING "
108
+ sql.concat(setting.map do |k, v|
109
+ if k == :current
110
+ "CURRENT_TIME TO #{cast_value[v.to_time]}"
111
+ else
112
+ "DEFAULT #{k.upcase}_TIME AS OF #{cast_value[v]}"
113
+ end
114
+ end.join(", "))
115
+ sql.concat " "
116
+ end
117
+
118
+ private
119
+
120
+ def default_timestamp_format
121
+ "'%Y-%m-%d %H:%M:%S'"
122
+ end
10
123
  end
11
124
  end
12
125
  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
 
@@ -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.2"
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.2
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-18 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