rndb 0.1.1 → 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 +4 -4
- data/README.md +1 -0
- data/VERSION +1 -1
- data/lib/rndb/query.rb +5 -0
- data/lib/rndb/table.rb +111 -26
- data/rndb.gemspec +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 214e9ee89f6ee4b994baf74bea9a34f49fc89e09c99ce436960ceb2c92d3d670
|
4
|
+
data.tar.gz: 85840a5d5346fb2334d395fa820d5f6111e43df485cd0b3e6a636a80f1837c61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf56a0511606581fff82c10d25573c826daab12823cd02bf2e003f8abfb9912d8a58a641dfca3d8e1f611e6a307762a6ee4adb5df26f2ab44011521904cdf3e7
|
7
|
+
data.tar.gz: 8f63e7aa951fdf2b304985686bfd8f6ccc8ed5bfd672cddf4634e75e3efbd6e4446ff6942d28e270289357efbc95ff5aee1244fdae8dba2d93fcbde4e3835455
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
[](https://github.com/kranzky/rndb/actions/workflows/test.yml)
|
2
2
|
[](https://coveralls.io/github/kranzky/rndb?branch=main)
|
3
|
+
[](https://badge.fury.io/rb/rndb)
|
3
4
|
|
4
5
|
# RnDB
|
5
6
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/rndb/query.rb
CHANGED
data/lib/rndb/table.rb
CHANGED
@@ -31,17 +31,35 @@ module RnDB
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def _generate_all
|
34
|
-
_schema[:columns].
|
34
|
+
_schema[:columns].each do |name, column|
|
35
|
+
_generate_column_key(name) if column[:generator] && column[:distribution]
|
35
36
|
_generate_column(name)
|
36
37
|
end
|
38
|
+
_schema[:associations].each_key do |name|
|
39
|
+
_generate_association_id(name)
|
40
|
+
end
|
37
41
|
@_attributes
|
38
42
|
end
|
39
43
|
|
44
|
+
def _generate_column_key(name)
|
45
|
+
@_attributes ||= { id: @id }
|
46
|
+
@_attributes["#{name}_key".to_sym] ||= self.class.key(@id, name)
|
47
|
+
end
|
48
|
+
|
40
49
|
def _generate_column(name)
|
41
50
|
@_attributes ||= { id: @id }
|
42
51
|
@_attributes[name] ||= self.class.value(@id, name)
|
43
52
|
end
|
44
53
|
|
54
|
+
def _generate_association_id(name)
|
55
|
+
@_attributes ||= { id: @id }
|
56
|
+
@_attributes["#{name}_id".to_sym] ||= _generate_association(name)&.id
|
57
|
+
end
|
58
|
+
|
59
|
+
def _generate_association(name)
|
60
|
+
self.class.join(@id, name)
|
61
|
+
end
|
62
|
+
|
45
63
|
def _validate!
|
46
64
|
self.class.send(:_validate!)
|
47
65
|
end
|
@@ -67,15 +85,7 @@ module RnDB
|
|
67
85
|
# Return a Query that matches the supplied constraints
|
68
86
|
def where(constraints={})
|
69
87
|
_validate!
|
70
|
-
|
71
|
-
constraints.each do |attribute, values|
|
72
|
-
column = _schema[:columns][attribute]
|
73
|
-
other = Array(values).reduce(Thicket.new) do |thicket, value|
|
74
|
-
thicket | column[:mapping][value]
|
75
|
-
end
|
76
|
-
ids &= other
|
77
|
-
end
|
78
|
-
Query.new(self, ids)
|
88
|
+
Query.new(self, _query(constraints, _schema[:size]))
|
79
89
|
end
|
80
90
|
|
81
91
|
# Return all records.
|
@@ -110,41 +120,67 @@ module RnDB
|
|
110
120
|
|
111
121
|
# Add a new column to the Table model.
|
112
122
|
def column(attribute, *args)
|
123
|
+
column = _schema[:columns][attribute]
|
113
124
|
args.each do |arg|
|
114
125
|
index =
|
115
126
|
case arg
|
116
|
-
when Hash
|
127
|
+
when Hash, Array
|
117
128
|
:distribution
|
118
129
|
when Proc
|
119
130
|
:generator
|
120
131
|
else
|
121
132
|
raise "unsupported column parameter"
|
122
133
|
end
|
123
|
-
|
134
|
+
column[index] = arg
|
135
|
+
end
|
136
|
+
if column[:generator] && column[:distribution]
|
137
|
+
define_method("#{attribute}_key") do
|
138
|
+
_generate_column_key(attribute)
|
139
|
+
end
|
124
140
|
end
|
125
141
|
define_method(attribute) do
|
126
142
|
_generate_column(attribute)
|
127
143
|
end
|
128
144
|
end
|
129
145
|
|
146
|
+
# Add an association between two Table models.
|
147
|
+
def association(attribute, *args)
|
148
|
+
args.each do |arg|
|
149
|
+
_schema[:associations][attribute] = arg
|
150
|
+
end
|
151
|
+
define_method("#{attribute}_id".to_sym) do
|
152
|
+
_generate_association_id(attribute)
|
153
|
+
end
|
154
|
+
define_method(attribute) do
|
155
|
+
_generate_association(attribute)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
130
159
|
# Generate a random number, intended to be used in lambdas. The number
|
131
160
|
# will have been seeded appropriately to ensure determinism.
|
132
|
-
def rand(args)
|
161
|
+
def rand(*args)
|
133
162
|
_validate!
|
134
|
-
_db.prng.rand(args)
|
163
|
+
_db.prng.rand(*args)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Retrieve the key that can be queried on for generated attributes.
|
167
|
+
def key(id, attribute)
|
168
|
+
@current = id
|
169
|
+
_validate!
|
170
|
+
column = _schema[:columns][attribute]
|
171
|
+
return if column[:distribution].nil?
|
172
|
+
column[:mapping].find do |_, ids|
|
173
|
+
ids.include?(id)
|
174
|
+
end&.first
|
135
175
|
end
|
136
176
|
|
137
177
|
# Retrieve the value of the given attribute for the given ID.
|
138
178
|
def value(id, attribute)
|
179
|
+
@current = id
|
139
180
|
_validate!
|
140
181
|
return id if attribute == :id
|
141
182
|
column = _schema[:columns][attribute]
|
142
|
-
value =
|
143
|
-
unless column[:distribution].nil?
|
144
|
-
column[:mapping].find do |_, ids|
|
145
|
-
ids.include?(id)
|
146
|
-
end&.first
|
147
|
-
end
|
183
|
+
value = key(id, attribute)
|
148
184
|
unless column[:generator].nil?
|
149
185
|
_seed_prng(id, attribute)
|
150
186
|
value =
|
@@ -157,6 +193,27 @@ module RnDB
|
|
157
193
|
value
|
158
194
|
end
|
159
195
|
|
196
|
+
# Return the instance joined to the current ID.
|
197
|
+
def join(id, name)
|
198
|
+
@current = id
|
199
|
+
_schema[:associations][name].each do |context|
|
200
|
+
next unless (index = where(context[:where]).index(id))
|
201
|
+
return where(context[:joins])[index]
|
202
|
+
end
|
203
|
+
nil
|
204
|
+
end
|
205
|
+
|
206
|
+
def get(attribute)
|
207
|
+
raise unless @current
|
208
|
+
if _schema[:columns].key?(attribute)
|
209
|
+
value(@current, attribute)
|
210
|
+
elsif _schema[:associations].key?(attribute)
|
211
|
+
join(@current, attribute)
|
212
|
+
else
|
213
|
+
raise "no such attribute"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
160
217
|
private
|
161
218
|
|
162
219
|
def _db
|
@@ -174,24 +231,52 @@ module RnDB
|
|
174
231
|
mapping: {},
|
175
232
|
generator: nil
|
176
233
|
}
|
234
|
+
end,
|
235
|
+
associations: Hash.new do |associations, key|
|
236
|
+
associations[key] = nil
|
177
237
|
end
|
178
238
|
}
|
179
239
|
end
|
180
240
|
Thread.current[:rndb_tables][table_name]
|
181
241
|
end
|
182
242
|
|
243
|
+
def _query(constraints, size)
|
244
|
+
ids = Thicket.new(0...size)
|
245
|
+
constraints.each do |attribute, values|
|
246
|
+
column = _schema[:columns][attribute]
|
247
|
+
raise "no mapping for column" if column[:mapping].empty?
|
248
|
+
other = Array(values).reduce(Thicket.new) do |thicket, value|
|
249
|
+
thicket | column[:mapping][value]
|
250
|
+
end
|
251
|
+
ids &= other
|
252
|
+
end
|
253
|
+
ids
|
254
|
+
end
|
255
|
+
|
256
|
+
def _migrate_column(column, ids, distribution)
|
257
|
+
min = 0.0
|
258
|
+
distribution.each do |value, probability|
|
259
|
+
max = min + probability
|
260
|
+
column[:mapping][value] ||= Thicket.new
|
261
|
+
column[:mapping][value] |= ids * (min..max)
|
262
|
+
min = max
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
183
266
|
def _migrate(size)
|
184
267
|
raise "table already migrated" unless _schema[:class].nil?
|
185
268
|
ids = Thicket.new(0...size)
|
186
269
|
_schema[:columns].each_value do |column|
|
187
270
|
distribution = column[:distribution]
|
188
271
|
next if distribution.nil?
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
272
|
+
if distribution.is_a?(Array)
|
273
|
+
distribution.each do |context|
|
274
|
+
thicket = ids & _query(context[:where], size)
|
275
|
+
_migrate_column(column, thicket, context[:stats])
|
276
|
+
end
|
277
|
+
else
|
278
|
+
raise "distribution must sum to unity" unless distribution.values.sum == 1
|
279
|
+
_migrate_column(column, ids, distribution)
|
195
280
|
end
|
196
281
|
ids =
|
197
282
|
column[:mapping].values.reduce(Thicket.new) do |thicket, other|
|
data/rndb.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: rndb 0.
|
5
|
+
# stub: rndb 0.2.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "rndb".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.2.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Lloyd Kranzky".freeze]
|
14
|
-
s.date = "2021-02-
|
14
|
+
s.date = "2021-02-26"
|
15
15
|
s.description = "".freeze
|
16
16
|
s.email = "lloyd@kranzky.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rndb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lloyd Kranzky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|