tarantool-crud 0.1.0 → 0.2.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: 8ecc01ae9122ffa4404d90dc8257541b26eed6fbb503a2eefaaa8be7d10b4ccf
4
- data.tar.gz: e5ed1f866cee6873e51dcc70490ffaede45c79fdd690f49c2457649afee4fafc
3
+ metadata.gz: 94250daa4b601caa86d7135bc072d19acab551444b77abbbc5baf5f815392e72
4
+ data.tar.gz: 87548a43bb0e3cb74289bddbc67b49ad942ca644c5d0420e4c0a88e5b16f2488
5
5
  SHA512:
6
- metadata.gz: 9bc5da2356ccb4477cb6b37053cac70743bf952d2799675fef5d442c1202a270d947c1f5e21a8fd478d929dcdfbf0c441050f4a798d06594895d034fa316c154
7
- data.tar.gz: d9bd55c7c4f033b0943b9782daa5bd8441544a574c4722f1d5e83eb071bf2b8cba5045ea669e883ce649bd2288bea16ca4fb56dd5bf07ca108bec136157262f4
6
+ metadata.gz: ee11036c413af3b0694382947e77d72f24a224c49cb18bf7d6d6efd18e612ffd7ddc99401ff2eb390b8db3ab913e5e7b7003ff061d56b7c4d59a5f8ba6d15d12
7
+ data.tar.gz: 20a4045f278bd37758357ddd19a82e9371b8efa31b0d19e684612919a436666cdcfa9fedd332920853fe6dc66bf8e9c5bf901ee5752d73090451754771d69d84
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.0 (unreleased)
3
+ ## 0.2.0 (unreleased)
4
+
5
+ - `Client#schema(space = nil)`: `crud.schema` through the router, returned in the shape of a tarantool-schema
6
+ declaration (`MemoryStorage.new(crud.schema, behaves_like: :crud)` works); `Crud::SchemaError`.
7
+ - Depends on `tarantool-client ~> 0.3`.
8
+
9
+ ## 0.1.1 (2026-10-17)
10
+
11
+ - Depends on `tarantool-client ~> 0.2.0`.
12
+
13
+ ## 0.1.0 (2026-10-16)
4
14
 
5
15
  First release.
6
16
 
data/README.md CHANGED
@@ -58,6 +58,10 @@ Any object responding to `call(function, arguments, timeout:)` can serve as the
58
58
 
59
59
  Write Hash tuples and Hash conditions with braces. Bare `key: value` arguments are crud options.
60
60
 
61
+ Requests go through the `Tarantool::Client` you pass in, so its `instrumenter:` and `logger:` see every crud call
62
+ as `request.tarantool` with `request: :call` and `function: 'crud.select'` (or the other crud function), without
63
+ arguments.
64
+
61
65
  ## Results
62
66
 
63
67
  `select` returns a `Result`: Enumerable of Hash rows (Symbol keys, taken from crud's metadata), plus `tuples`
@@ -69,6 +73,21 @@ returns an Enumerator without a block. Single-row operations (`get`, `insert`, `
69
73
  call fails (missing space, empty row list, ...), crud reports it as `InsertManyError`/`ReplaceManyError`/
70
74
  `UpsertManyError` inside `errors` with no rows, rather than raising.
71
75
 
76
+ ## Schema
77
+
78
+ ```ruby
79
+ crud.schema(:users) # => { format: [{ name: :id, type: 'unsigned', is_nullable: false }, ...],
80
+ # indexes: [{ name: :primary, type: 'tree', unique: true,
81
+ # parts: [{ field: :id, type: 'unsigned', is_nullable: false }] }, ...] }
82
+ crud.schema # => { users: { format: ..., indexes: ... }, ... }
83
+ ```
84
+
85
+ `crud.schema` through the router, for applications without read access to `_space`. The shape is the one
86
+ tarantool-schema declares (Symbol names, String types, indexes in id order, parts named by their field), so
87
+ tarantool-model's in-memory storage takes it as is: `MemoryStorage.new(crud.schema, behaves_like: :crud)`.
88
+ `exclude_null` is dropped; a part past the format is named `:"#N"` by its position. An unknown space raises
89
+ `SchemaError`. Options: `timeout:`, `vshard_router:`, and crud's `cached:`.
90
+
72
91
  ## Conditions
73
92
 
74
93
  An Array of `[operator, field, value]` or a Hash:
@@ -98,7 +117,7 @@ The `mode:` option here is the crud/vshard router option (`'read'` or `'write'`
98
117
 
99
118
  `Tarantool::Crud::Error` has `message` (the crud error message), `str` (crud's `tostring` of the full error, e.g. `"InsertError: ..."`), `class_name`, `file`, `line`, and `operation_data`. Subclasses: `InsertError`,
100
119
  `ReplaceError`, `UpsertError`, `GetError`, `UpdateError`, `DeleteError`, `SelectError`, `CountError`, `MinMaxError`,
101
- `LenError`, `TruncateError`, `CallError`, `InsertManyError`, `ReplaceManyError`, `UpsertManyError`.
120
+ `LenError`, `TruncateError`, `SchemaError`, `CallError`, `InsertManyError`, `ReplaceManyError`, `UpsertManyError`.
102
121
  `Tarantool::Crud::ManyError` is a separate `Tarantool::Error` subclass raised by the `*_many!` bang variants; it
103
122
  carries `result` (and `errors`), not the crud error fields. Transport and server errors from tarantool-client
104
123
  propagate unchanged.
@@ -110,11 +129,19 @@ in the message. Only a request that gets no answer within the transport timeout
110
129
  ## Development
111
130
 
112
131
  ```sh
113
- podman compose -f tarantool-crud/docker-compose.yml up -d --wait --build
132
+ podman compose -f tarantool-crud/docker-compose.yml up -d --wait
114
133
  cd tarantool-crud
115
134
  INTEGRATION=1 TARANTOOL_CRUD_URI=tcp://app:secret@localhost:3311 bundle exec rspec
116
135
  ```
117
136
 
137
+ Compose pulls `ghcr.io/starlexxx/tarantool-crud:2.11` and `:3` (Tarantool with vshard and crud from
138
+ `docker/Dockerfile`), built by the `Images` workflow whenever `docker/` changes. If the pull is denied, log in
139
+ with `podman login ghcr.io` and a token that has `read:packages`. To try a Dockerfile change locally:
140
+
141
+ ```sh
142
+ docker build -t ghcr.io/starlexxx/tarantool-crud:3 --build-arg TARANTOOL_VERSION=3 tarantool-crud/docker
143
+ ```
144
+
118
145
  ## Public API
119
146
 
120
147
  `Tarantool::Crud::Client`, `Space`, `Result`, `ManyResult`, and the error classes above.
@@ -12,6 +12,15 @@ module Tarantool
12
12
 
13
13
  def storage_info(**options) = @call.value('storage_info', [], options)
14
14
 
15
+ # The format and indexes of one space, or of every space keyed by name, as crud sees them through the
16
+ # router: the same shape as a tarantool-schema declaration, so MemoryStorage.new(crud.schema, behaves_like: :crud)
17
+ # works. An unknown space raises SchemaError.
18
+ def schema(space = nil, **options)
19
+ raw = @call.value('schema', [space&.to_s], options)
20
+
21
+ space ? Schema.space(raw) : Schema.all(raw)
22
+ end
23
+
15
24
  # crud.stats takes no options and encodes an empty table as an Array.
16
25
  def stats(space = nil, timeout: nil)
17
26
  stats = @call.without_options('stats', [space&.to_s].compact, timeout).first
@@ -6,7 +6,7 @@ module Tarantool
6
6
  # narrowed to what each function accepts (crud 1.8.0); options given to a call are sent as is.
7
7
  # @api private
8
8
  class Defaults
9
- READ_FUNCTIONS = %w[get select count min max len storage_info stats].freeze
9
+ READ_FUNCTIONS = %w[get select count min max len storage_info stats schema].freeze
10
10
 
11
11
  READ = %i[timeout request_timeout bucket_id prefer_replica balance mode vshard_router].freeze
12
12
  BORDERS = %i[timeout request_timeout fields mode vshard_router fetch_latest_metadata].freeze
@@ -27,6 +27,7 @@ module Tarantool
27
27
  'max' => BORDERS,
28
28
  'len' => READ - %i[bucket_id],
29
29
  'storage_info' => SERVICE,
30
+ 'schema' => SERVICE,
30
31
  'stats' => %i[timeout],
31
32
  'truncate' => SERVICE,
32
33
  'insert' => TUPLE,
@@ -36,6 +36,7 @@ module Tarantool
36
36
  class MinMaxError < Error; end
37
37
  class LenError < Error; end
38
38
  class TruncateError < Error; end
39
+ class SchemaError < Error; end
39
40
 
40
41
  # One row of a *_many call failed; operation_data holds that row.
41
42
  class CallError < Error; end
@@ -71,6 +72,7 @@ module Tarantool
71
72
  'BorderError' => MinMaxError,
72
73
  'LenError' => LenError,
73
74
  'TruncateError' => TruncateError,
75
+ 'SchemaError' => SchemaError,
74
76
  'CallError' => CallError,
75
77
  'InsertManyError' => InsertManyError,
76
78
  'ReplaceManyError' => ReplaceManyError,
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tarantool
4
+ module Crud
5
+ # crud.schema output in the shape tarantool-schema declares and MemoryStorage accepts: Symbol names,
6
+ # String types, indexes as an Array in id order, parts named by field. exclude_null is dropped.
7
+ # @api private
8
+ module Schema
9
+ module_function
10
+
11
+ def all(raw) = raw.to_h { |name, space| [name.to_sym, space(space)] }
12
+
13
+ def space(raw)
14
+ format = Array(raw['format']).map { |field| field(field) }
15
+ indexes = Array(raw['indexes']&.values).sort_by { |index| index['id'] }
16
+
17
+ { format:, indexes: indexes.map { |index| index(index, format) } }
18
+ end
19
+
20
+ def field(raw)
21
+ { name: raw.fetch('name').to_sym, type: raw.fetch('type', 'any'), is_nullable: raw.fetch('is_nullable', false) }
22
+ end
23
+
24
+ def index(raw, format)
25
+ { name: raw.fetch('name').to_sym, type: raw.fetch('type').downcase, unique: raw.fetch('unique'),
26
+ parts: Array(raw['parts']).map { |part| part(part, format) } }
27
+ end
28
+
29
+ def part(raw, format)
30
+ fieldno = raw.fetch('fieldno')
31
+ field = format[fieldno - 1]&.fetch(:name) || :"##{fieldno}"
32
+ part = { field:, type: raw.fetch('type'), is_nullable: raw.fetch('is_nullable', false) }
33
+ part[:path] = raw['path'] if raw['path']
34
+
35
+ part
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Tarantool
4
4
  module Crud
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
@@ -10,5 +10,6 @@ require_relative 'crud/many_result'
10
10
  require_relative 'crud/defaults'
11
11
  require_relative 'crud/call'
12
12
  require_relative 'crud/scan'
13
+ require_relative 'crud/schema'
13
14
  require_relative 'crud/space'
14
15
  require_relative 'crud/client'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tarantool-crud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Starlexxx
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-16 00:00:00.000000000 Z
11
+ date: 2026-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tarantool-client
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.0
19
+ version: '0.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.0
26
+ version: '0.3'
27
27
  description: Per-space CRUD, conditions, pagination and batch operations over the
28
28
  tarantool/crud module for vshard clusters on Tarantool 2.11+ and 3.x, built on tarantool-client.
29
29
  email:
@@ -44,6 +44,7 @@ files:
44
44
  - lib/tarantool/crud/many_result.rb
45
45
  - lib/tarantool/crud/result.rb
46
46
  - lib/tarantool/crud/scan.rb
47
+ - lib/tarantool/crud/schema.rb
47
48
  - lib/tarantool/crud/space.rb
48
49
  - lib/tarantool/crud/version.rb
49
50
  homepage: https://github.com/Starlexxx/tarantool-ruby