datomic-flare 1.0.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.
data/docs/api.md ADDED
@@ -0,0 +1,395 @@
1
+ ## Flare API
2
+
3
+ It provides methods that mirror [Datomic's APIs](https://docs.datomic.com/clojure/index.html). Most interactions use EDN, closely following [Datomic’s documentation](https://docs.datomic.com).
4
+
5
+ This approach should be familiar to those who know Datomic concepts and APIs.
6
+
7
+ Learn more about Clojure and Datomic:
8
+
9
+ - [Clojure Rationale](https://clojure.org/about/rationale)
10
+ - [Datomic Introduction](https://docs.datomic.com/datomic-overview.html)
11
+
12
+ ### Creating a Database
13
+
14
+ ```ruby
15
+ client.api.create_database!({ name: 'fireball' })['data']
16
+ ```
17
+
18
+ ```ruby
19
+ true
20
+ ```
21
+
22
+ ### Deleting a Database
23
+
24
+ ```ruby
25
+ client.api.delete_database!({ name: 'fireball' })['data']
26
+ ```
27
+
28
+ ```ruby
29
+ true
30
+ ```
31
+
32
+ ### Listing Databases
33
+
34
+ ```ruby
35
+ # Flare on Peer Mode
36
+ client.api.get_database_names['data']
37
+
38
+ # Flare on Client Mode
39
+ client.api.list_databases['data']
40
+ ```
41
+
42
+ ```ruby
43
+ ['my-datomic-database']
44
+ ```
45
+
46
+ ### Transacting Schema
47
+
48
+ ```ruby
49
+ client.api.transact!(
50
+ { data: <<~EDN
51
+ [{:db/ident :book/title
52
+ :db/valueType :db.type/string
53
+ :db/cardinality :db.cardinality/one
54
+ :db/doc "The title of the book."}
55
+
56
+ {:db/ident :book/genre
57
+ :db/valueType :db.type/string
58
+ :db/cardinality :db.cardinality/one
59
+ :db/doc "The genre of the book."}
60
+
61
+ {:db/ident :book/published_at_year
62
+ :db/valueType :db.type/long
63
+ :db/cardinality :db.cardinality/one
64
+ :db/doc "The year the book was first published."}]
65
+ EDN
66
+ }
67
+ )['data']
68
+ ```
69
+
70
+ ```ruby
71
+ {
72
+ 'db-before' => 'datomic.db.Db@3062d44c',
73
+ 'db-after' => 'datomic.db.Db@7802aade',
74
+ 'tx-data' =>
75
+ [[13194139534312, 50, '2024-09-29T13:52:52.435Z', 13194139534312, true],
76
+ [72, 10, ':book/title', 13194139534312, true],
77
+ [72, 40, 23, 13194139534312, true],
78
+ [72, 41, 35, 13194139534312, true],
79
+ [72, 62, 'The title of the book.', 13194139534312, true],
80
+ [73, 10, ':book/genre', 13194139534312, true],
81
+ [73, 40, 23, 13194139534312, true],
82
+ [73, 41, 35, 13194139534312, true],
83
+ [73, 62, 'The genre of the book.', 13194139534312, true],
84
+ [74, 10, ':book/published_at_year', 13194139534312, true],
85
+ [74, 40, 22, 13194139534312, true],
86
+ [74, 41, 35, 13194139534312, true],
87
+ [74, 62, 'The year the book was first published.', 13194139534312, true],
88
+ [0, 13, 72, 13194139534312, true],
89
+ [0, 13, 73, 13194139534312, true],
90
+ [0, 13, 74, 13194139534312, true]],
91
+ 'tempids' =>
92
+ {
93
+ '-9223300668110558618' => 72,
94
+ '-9223300668110558617' => 73,
95
+ '-9223300668110558616' => 74
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Checking Schema
101
+
102
+ ```ruby
103
+ client.api.q(
104
+ {
105
+ inputs: [{ database: { latest: true } }],
106
+ query: <<~EDN
107
+ [:find
108
+ ?e ?ident ?value_type ?cardinality ?doc
109
+ ?unique ?index ?no_history
110
+ :in $
111
+ :where
112
+ [?e :db/ident ?ident]
113
+
114
+ [?e :db/valueType ?value_type_id]
115
+ [?value_type_id :db/ident ?value_type]
116
+
117
+ [?e :db/cardinality ?cardinality_id]
118
+ [?cardinality_id :db/ident ?cardinality]
119
+
120
+ [(get-else $ ?e :db/doc "") ?doc]
121
+
122
+ [(get-else $ ?e :db/unique -1) ?unique_id]
123
+ [(get-else $ ?unique_id :db/ident false) ?unique]
124
+
125
+ [(get-else $ ?e :db/index false) ?index]
126
+ [(get-else $ ?e :db/noHistory false) ?no_history]]
127
+ EDN
128
+ }
129
+ )['data'].filter do |datom|
130
+ !%w[
131
+ db
132
+ db.alter db.attr db.bootstrap db.cardinality db.entity db.excise
133
+ db.fn db.install db.lang db.part db.sys db.type db.unique
134
+ fressian
135
+ ].include?(datom[1].split('/').first)
136
+ end
137
+ ```
138
+
139
+ ```ruby
140
+ [[74,
141
+ 'book/published_at_year',
142
+ 'db.type/long',
143
+ 'db.cardinality/one',
144
+ 'The year the book was first published.',
145
+ false,
146
+ false,
147
+ false],
148
+ [72,
149
+ 'book/title',
150
+ 'db.type/string',
151
+ 'db.cardinality/one',
152
+ 'The title of the book.',
153
+ false,
154
+ false,
155
+ false],
156
+ [73,
157
+ 'book/genre',
158
+ 'db.type/string',
159
+ 'db.cardinality/one',
160
+ 'The genre of the book.',
161
+ false,
162
+ false,
163
+ false]]
164
+ ```
165
+
166
+ ### Asserting Facts
167
+
168
+ ```ruby
169
+ client.api.transact!(
170
+ { data: <<~EDN
171
+ [{:db/id -1
172
+ :book/title "Pride and Prejudice"
173
+ :book/genre "Romance"
174
+ :book/published_at_year 1813}]
175
+ EDN
176
+ }
177
+ )['data']
178
+ ```
179
+
180
+ ```ruby
181
+ {
182
+ 'db-before' => 'datomic.db.Db@5342ef1a',
183
+ 'db-after' => 'datomic.db.Db@643ac781',
184
+ 'tx-data' =>
185
+ [[13194139534313, 50, '2024-09-29T13:52:52.546Z', 13194139534313, true],
186
+ [4611681620380877802, 72, 'Pride and Prejudice', 13194139534313, true],
187
+ [4611681620380877802, 73, 'Romance', 13194139534313, true],
188
+ [4611681620380877802, 74, 1813, 13194139534313, true]],
189
+ 'tempids' => { '-1' => 4611681620380877802 }
190
+ }
191
+ ```
192
+
193
+ ```ruby
194
+ client.api.transact!(
195
+ { data: <<~EDN
196
+ [{:db/id -1
197
+ :book/title "Near to the Wild Heart"
198
+ :book/genre "Novel"
199
+ :book/published_at_year 1943}
200
+ {:db/id -2
201
+ :book/title "A Study in Scarlet"
202
+ :book/genre "Detective"
203
+ :book/published_at_year 1887}
204
+ {:db/id -3
205
+ :book/title "The Tell-Tale Heart"
206
+ :book/genre "Horror"
207
+ :book/published_at_year 1843}]
208
+ EDN
209
+ }
210
+ )['data']
211
+ ```
212
+
213
+
214
+ ```ruby
215
+ {
216
+ 'db-before' => 'datomic.db.Db@6afd3576',
217
+ 'db-after' => 'datomic.db.Db@73000a74',
218
+ 'tx-data' =>
219
+ [[13194139534315, 50, '2024-09-29T13:52:52.599Z', 13194139534315, true],
220
+ [4611681620380877804, 72, 'Near to the Wild Heart', 13194139534315, true],
221
+ [4611681620380877804, 73, 'Novel', 13194139534315, true],
222
+ [4611681620380877804, 74, 1943, 13194139534315, true],
223
+ [4611681620380877805, 72, 'A Study in Scarlet', 13194139534315, true],
224
+ [4611681620380877805, 73, 'Detective', 13194139534315, true],
225
+ [4611681620380877805, 74, 1887, 13194139534315, true],
226
+ [4611681620380877806, 72, 'The Tell-Tale Heart', 13194139534315, true],
227
+ [4611681620380877806, 73, 'Horror', 13194139534315, true],
228
+ [4611681620380877806, 74, 1843, 13194139534315, true]],
229
+ 'tempids' =>
230
+ {
231
+ '-1' => 4611681620380877804,
232
+ '-2' => 4611681620380877805,
233
+ '-3' => 4611681620380877806
234
+ }
235
+ }
236
+ ```
237
+
238
+ ### Reading Data by Entity
239
+
240
+ ```ruby
241
+ client.api.entity(
242
+ {
243
+ database: { latest: true },
244
+ id: 4611681620380877804
245
+ }
246
+ )['data']
247
+ ```
248
+
249
+ ```ruby
250
+ {
251
+ ':book/title' => 'Near to the Wild Heart',
252
+ ':book/genre' => 'Novel',
253
+ ':book/published_at_year' => 1943,
254
+ ':db/id' => 4611681620380877804
255
+ }
256
+ ```
257
+
258
+ ### Reading Data by Querying
259
+
260
+ ```ruby
261
+ client.api.q(
262
+ {
263
+ inputs: [{ database: { latest: true } }],
264
+ query: <<~EDN
265
+ [:find ?e ?title ?genre ?year
266
+ :where [?e :book/title ?title]
267
+ [?e :book/genre ?genre]
268
+ [?e :book/published_at_year ?year]]
269
+ EDN
270
+ }
271
+ )['data']
272
+ ```
273
+
274
+ ```ruby
275
+ [[4611681620380877805, 'A Study in Scarlet', 'Detective', 1887],
276
+ [4611681620380877804, 'Near to the Wild Heart', 'Novel', 1943],
277
+ [4611681620380877806, 'The Tell-Tale Heart', 'Horror', 1843],
278
+ [4611681620380877802, 'Pride and Prejudice', 'Romance', 1813]]
279
+ ```
280
+
281
+ ```ruby
282
+ client.api.q(
283
+ {
284
+ inputs: [
285
+ { database: { latest: true } },
286
+ 'The Tell-Tale Heart'
287
+ ],
288
+ query: <<~EDN
289
+ [:find ?e ?title ?genre ?year
290
+ :in $ ?title
291
+ :where [?e :book/title ?title]
292
+ [?e :book/genre ?genre]
293
+ [?e :book/published_at_year ?year]]
294
+ EDN
295
+ }
296
+ )['data']
297
+ ```
298
+
299
+
300
+ ```ruby
301
+ [[4611681620380877806, 'The Tell-Tale Heart', 'Horror', 1843]]
302
+ ```
303
+
304
+ ### Accumulating Facts
305
+
306
+ ```ruby
307
+ client.api.transact!(
308
+ { data: <<~EDN
309
+ [{:db/id 4611681620380877806 :book/genre "Gothic"}]
310
+ EDN
311
+ }
312
+ )['data']
313
+ ```
314
+
315
+ ```ruby
316
+ {
317
+ 'db-before' => 'datomic.db.Db@55e660ec',
318
+ 'db-after' => 'datomic.db.Db@385f74d4',
319
+ 'tx-data' =>
320
+ [[13194139534319, 50, '2024-09-29T13:52:52.817Z', 13194139534319, true],
321
+ [4611681620380877806, 73, 'Gothic', 13194139534319, true],
322
+ [4611681620380877806, 73, 'Horror', 13194139534319, false]],
323
+ 'tempids' => {}
324
+ }
325
+ ```
326
+
327
+ ### Retracting Facts
328
+
329
+ Retract the value of an attribute:
330
+
331
+ ```ruby
332
+ client.api.transact!(
333
+ { data: <<~EDN
334
+ [[:db/retract 4611681620380877806 :book/genre "Gothic"]]
335
+ EDN
336
+ }
337
+ )['data']
338
+ ```
339
+
340
+ ```ruby
341
+ {
342
+ 'db-before' => 'datomic.db.Db@7c2176fa',
343
+ 'db-after' => 'datomic.db.Db@6ec2acf1',
344
+ 'tx-data' =>
345
+ [[13194139534320, 50, '2024-09-29T13:52:52.869Z', 13194139534320, true],
346
+ [4611681620380877806, 73, 'Gothic', 13194139534320, false]],
347
+ 'tempids' => {}
348
+ }
349
+ ```
350
+
351
+ Retract an attribute:
352
+
353
+ ```ruby
354
+ client.api.transact!(
355
+ { data: <<~EDN
356
+ [[:db/retract 4611681620380877804 :book/genre]]
357
+ EDN
358
+ }
359
+ )['data']
360
+ ```
361
+
362
+ ```ruby
363
+ {
364
+ 'db-before' => 'datomic.db.Db@f8180a0',
365
+ 'db-after' => 'datomic.db.Db@2bc03f4d',
366
+ 'tx-data' =>
367
+ [[13194139534321, 50, '2024-09-29T13:52:52.913Z', 13194139534321, true],
368
+ [4611681620380877804, 73, 'Novel', 13194139534321, false]],
369
+ 'tempids' => {}
370
+ }
371
+ ```
372
+
373
+ Retract an entity:
374
+
375
+ ```ruby
376
+ client.api.transact!(
377
+ { data: <<~EDN
378
+ [[:db/retractEntity 4611681620380877805]]
379
+ EDN
380
+ }
381
+ )['data']
382
+ ```
383
+
384
+ ```ruby
385
+ {
386
+ 'db-before' => 'datomic.db.Db@698670bc',
387
+ 'db-after' => 'datomic.db.Db@2abc508c',
388
+ 'tx-data' =>
389
+ [[13194139534322, 50, '2024-09-29T13:52:52.955Z', 13194139534322, true],
390
+ [4611681620380877805, 72, 'A Study in Scarlet', 13194139534322, false],
391
+ [4611681620380877805, 73, 'Detective', 13194139534322, false],
392
+ [4611681620380877805, 74, 1887, 13194139534322, false]],
393
+ 'tempids' => {}
394
+ }
395
+ ```
data/docs/dsl.md ADDED
@@ -0,0 +1,257 @@
1
+ ## Flare DSL
2
+
3
+ It provides a Ruby-familiar approach to working with Datomic. It brings Ruby’s conventions and idioms while preserving Datomic’s data-first principles and terminology.
4
+
5
+ This approach should be cozy to those who are familiar with Ruby.
6
+
7
+ Learn more about Ruby and The Rails Doctrine:
8
+
9
+ - [About Ruby](https://www.ruby-lang.org/en/about/)
10
+ - [The Rails Doctrine](https://rubyonrails.org/doctrine)
11
+
12
+ ### Creating a Database
13
+
14
+ ```ruby
15
+ client.dsl.create_database!('radioactive')
16
+ ```
17
+
18
+ ```ruby
19
+ true
20
+ ```
21
+
22
+ ### Deleting a Database
23
+
24
+ ```ruby
25
+ client.dsl.destroy_database!('radioactive')
26
+ ```
27
+
28
+ ```ruby
29
+ true
30
+ ```
31
+
32
+ ### Listing Databases
33
+
34
+ ```ruby
35
+ client.dsl.databases
36
+ ```
37
+
38
+ ```ruby
39
+ ['my-datomic-database']
40
+ ```
41
+
42
+ ### Transacting Schema
43
+
44
+ Like `CREATE TABLE` in SQL databases or defining document or record structures in other databases.
45
+
46
+ ```ruby
47
+ client.dsl.transact_schema!(
48
+ {
49
+ book: {
50
+ title: { type: :string, doc: 'The title of the book.' },
51
+ genre: { type: :string, doc: 'The genre of the book.' },
52
+ published_at_year: { type: :long, doc: 'The year the book was first published.' }
53
+ }
54
+ }
55
+ )
56
+ ```
57
+
58
+ ```ruby
59
+ true
60
+ ```
61
+
62
+ ### Checking Schema
63
+
64
+ Like `SHOW COLUMNS FROM` in SQL databases or checking document or record structures in other databases.
65
+
66
+ ```ruby
67
+ client.dsl.schema
68
+ ```
69
+
70
+ ```ruby
71
+ {
72
+ book: {
73
+ published_at_year: {
74
+ type: :long,
75
+ cardinality: :one,
76
+ doc: 'The year the book was first published.',
77
+ unique: false,
78
+ index: false,
79
+ history: true
80
+ },
81
+ title: {
82
+ type: :string,
83
+ cardinality: :one,
84
+ doc: 'The title of the book.',
85
+ unique: false,
86
+ index: false,
87
+ history: true
88
+ },
89
+ genre: {
90
+ type: :string,
91
+ cardinality: :one,
92
+ doc: 'The genre of the book.',
93
+ unique: false,
94
+ index: false,
95
+ history: true
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### Asserting Facts
102
+
103
+ Like `INSERT INTO` in SQL databases or creating a new document or record in other databases.
104
+
105
+ ```ruby
106
+ client.dsl.assert_into!(
107
+ :book,
108
+ {
109
+ title: 'Pride and Prejudice',
110
+ genre: 'Romance',
111
+ published_at_year: 1813
112
+ }
113
+ )
114
+ ```
115
+
116
+ ```ruby
117
+ 4611681620380877802
118
+ ```
119
+
120
+ ```ruby
121
+ client.dsl.assert_into!(
122
+ :book,
123
+ [{
124
+ title: 'Near to the Wild Heart',
125
+ genre: 'Novel',
126
+ published_at_year: 1943
127
+ },
128
+ {
129
+ title: 'A Study in Scarlet',
130
+ genre: 'Detective',
131
+ published_at_year: 1887
132
+ },
133
+ {
134
+ title: 'The Tell-Tale Heart',
135
+ genre: 'Horror',
136
+ published_at_year: 1843
137
+ }]
138
+ )
139
+ ```
140
+
141
+
142
+ ```ruby
143
+ [4611681620380877804, 4611681620380877805, 4611681620380877806]
144
+ ```
145
+
146
+ ### Reading Data by Entity
147
+
148
+ Like `SELECT` in SQL databases or querying documents or records in other databases.
149
+
150
+ ```ruby
151
+ client.dsl.find_by_entity_id(4611681620380877804)
152
+ ```
153
+
154
+ ```ruby
155
+ {
156
+ book: {
157
+ title: 'Near to the Wild Heart',
158
+ genre: 'Novel',
159
+ published_at_year: 1943,
160
+ _id: 4611681620380877804
161
+ }
162
+ }
163
+ ```
164
+
165
+ ### Reading Data by Querying
166
+
167
+ Like `SELECT` in SQL databases or querying documents or records in other databases.
168
+
169
+ ```ruby
170
+ client.dsl.query(
171
+ datalog: <<~EDN
172
+ [:find ?e ?title ?genre ?year
173
+ :where [?e :book/title ?title]
174
+ [?e :book/genre ?genre]
175
+ [?e :book/published_at_year ?year]]
176
+ EDN
177
+ )
178
+ ```
179
+
180
+ ```ruby
181
+ [[4611681620380877805, 'A Study in Scarlet', 'Detective', 1887],
182
+ [4611681620380877804, 'Near to the Wild Heart', 'Novel', 1943],
183
+ [4611681620380877806, 'The Tell-Tale Heart', 'Horror', 1843],
184
+ [4611681620380877802, 'Pride and Prejudice', 'Romance', 1813]]
185
+ ```
186
+
187
+ ```ruby
188
+ client.dsl.query(
189
+ params: ['The Tell-Tale Heart'],
190
+ datalog: <<~EDN
191
+ [:find ?e ?title ?genre ?year
192
+ :in $ ?title
193
+ :where [?e :book/title ?title]
194
+ [?e :book/genre ?genre]
195
+ [?e :book/published_at_year ?year]]
196
+ EDN
197
+ )
198
+ ```
199
+
200
+
201
+ ```ruby
202
+ [[4611681620380877806, 'The Tell-Tale Heart', 'Horror', 1843]]
203
+ ```
204
+
205
+ ### Accumulating Facts
206
+
207
+ Like `UPDATE` in SQL databases or updating documents or records in other databases. However, Datomic never updates data. It is an immutable database that only accumulates new facts or retracts past facts.
208
+
209
+ ```ruby
210
+ client.dsl.assert_into!(
211
+ :book, { _id: 4611681620380877806, genre: 'Gothic' }
212
+ )
213
+ ```
214
+
215
+ ```ruby
216
+ 4611681620380877806
217
+ ```
218
+
219
+ ### Retracting Facts
220
+
221
+ Like `DELETE` in SQL databases or deleting documents or records in other databases. However, Datomic never deletes data. It is an immutable database that only accumulates new facts or retracts past facts.
222
+
223
+ Retract the value of an attribute:
224
+
225
+ ```ruby
226
+ client.dsl.retract_from!(
227
+ :book, { _id: 4611681620380877806, genre: 'Gothic' }
228
+ )
229
+ ```
230
+
231
+ ```ruby
232
+ true
233
+ ```
234
+
235
+ Retract an attribute:
236
+
237
+ ```ruby
238
+ client.dsl.retract_from!(
239
+ :book, { _id: 4611681620380877804, genre: nil }
240
+ )
241
+ ```
242
+
243
+ ```ruby
244
+ true
245
+ ```
246
+
247
+ Retract an entity:
248
+
249
+ ```ruby
250
+ client.dsl.retract_from!(
251
+ :book, { _id: 4611681620380877805 }
252
+ )
253
+ ```
254
+
255
+ ```ruby
256
+ true
257
+ ```
@@ -0,0 +1,15 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1.0
3
+ NewCops: enable
4
+
5
+ Style/NumericLiterals:
6
+ Enabled: false
7
+
8
+ Layout/FirstHashElementLineBreak:
9
+ Enabled: true
10
+
11
+ Lint/UselessAssignment:
12
+ Enabled: false
13
+
14
+ Style/FrozenStringLiteralComment:
15
+ Enabled: false