datomic-flare 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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