dbee 2.1.0.pre.alpha → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +71 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +6 -17
- data/.tool-versions +1 -0
- data/CHANGELOG.md +21 -1
- data/README.md +154 -62
- data/dbee.gemspec +6 -10
- data/lib/dbee/base.rb +7 -49
- data/lib/dbee/dsl_schema_builder.rb +86 -0
- data/lib/dbee/key_chain.rb +11 -0
- data/lib/dbee/model/relationships/basic.rb +47 -0
- data/lib/dbee/model/relationships.rb +24 -0
- data/lib/dbee/model.rb +50 -38
- data/lib/dbee/query/field.rb +5 -6
- data/lib/dbee/query.rb +32 -20
- data/lib/dbee/schema.rb +66 -0
- data/lib/dbee/schema_creator.rb +107 -0
- data/lib/dbee/schema_from_tree_based_model.rb +47 -0
- data/lib/dbee/util/make_keyed_by.rb +50 -0
- data/lib/dbee/version.rb +1 -1
- data/lib/dbee.rb +9 -10
- data/spec/dbee/base_spec.rb +9 -72
- data/spec/dbee/constant_resolver_spec.rb +17 -12
- data/spec/dbee/dsl_schema_builder_spec.rb +106 -0
- data/spec/dbee/key_chain_spec.rb +24 -0
- data/spec/dbee/model/constraints_spec.rb +6 -7
- data/spec/dbee/model_spec.rb +62 -59
- data/spec/dbee/query/filters_spec.rb +16 -17
- data/spec/dbee/query_spec.rb +56 -62
- data/spec/dbee/schema_creator_spec.rb +163 -0
- data/spec/dbee/schema_from_tree_based_model_spec.rb +31 -0
- data/spec/dbee/schema_spec.rb +62 -0
- data/spec/dbee_spec.rb +17 -37
- data/spec/fixtures/models.yaml +254 -56
- data/spec/spec_helper.rb +7 -0
- metadata +86 -19
- data/.travis.yml +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 234c40439102547cc3c8b78cbde5bc3755fcf49d8515c81eed7c7942f1c6a526
|
4
|
+
data.tar.gz: b9bb06a2e773786bb7e19b541f1dd6f104909baeea93148bbde78f9c5965ced8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3484318a258c8788fa7b08533cb3b27679fc52903e70f2914d4ab8ddd36921fcf628d3f934dbc0704fbf38f1d49c03c087a3c656121d0266083c3c98e41cde75
|
7
|
+
data.tar.gz: 53c8425f56c659f222d729c71855d4c1ecaaa3dd90d21ced647152d49c00bdc5ed2bc550bae7c307f098835a13d165c423685033df6ffee62e3867bfc32c0224
|
@@ -0,0 +1,71 @@
|
|
1
|
+
version: 2.1
|
2
|
+
|
3
|
+
orbs:
|
4
|
+
status_to_ms_teams: bluemarblepayroll/status_to_ms_teams_pure_bash@1.0.0
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
build:
|
8
|
+
parameters:
|
9
|
+
use-bundler-cache:
|
10
|
+
type: boolean
|
11
|
+
default: true
|
12
|
+
|
13
|
+
docker:
|
14
|
+
- image: circleci/ruby:2.6.6-buster
|
15
|
+
environment:
|
16
|
+
FORBID_FOCUSED_SPECS: 1
|
17
|
+
working_directory: ~/dbee
|
18
|
+
steps:
|
19
|
+
- checkout
|
20
|
+
|
21
|
+
# TODO: wrap bundler caching logic into an Orb:
|
22
|
+
- when:
|
23
|
+
condition: << parameters.use-bundler-cache >>
|
24
|
+
steps:
|
25
|
+
- restore_cache:
|
26
|
+
key: v1.0.0-build-ruby-dependency-cache-{{ checksum "dbee.gemspec" }}-{{ checksum "Gemfile" }}-{{ checksum ".ruby-version" }}
|
27
|
+
|
28
|
+
- run: bundle install --path vendor/bundle
|
29
|
+
|
30
|
+
- when:
|
31
|
+
condition: << parameters.use-bundler-cache >>
|
32
|
+
steps:
|
33
|
+
- save_cache:
|
34
|
+
key: v1.0.0-build-ruby-dependency-cache-{{ checksum "dbee.gemspec" }}-{{ checksum "Gemfile" }}-{{ checksum ".ruby-version" }}
|
35
|
+
paths:
|
36
|
+
- vendor/bundle
|
37
|
+
|
38
|
+
- store_artifacts:
|
39
|
+
path: Gemfile.lock
|
40
|
+
|
41
|
+
- run: bundle exec rubocop
|
42
|
+
|
43
|
+
- run: COVERAGE=true bundle exec rspec -r rspec_junit_formatter --format progress --format RspecJunitFormatter -o test-results/rspec/results.xml
|
44
|
+
|
45
|
+
- store_test_results:
|
46
|
+
path: test-results
|
47
|
+
|
48
|
+
- store_artifacts:
|
49
|
+
path: coverage
|
50
|
+
|
51
|
+
- status_to_ms_teams/report:
|
52
|
+
webhook_url: $MS_TEAMS_WEBHOOK_URL
|
53
|
+
|
54
|
+
workflows:
|
55
|
+
version: 2.1
|
56
|
+
build:
|
57
|
+
jobs:
|
58
|
+
- build:
|
59
|
+
context: org-global
|
60
|
+
monthly-gem-dependency-refresh-check:
|
61
|
+
triggers:
|
62
|
+
- schedule:
|
63
|
+
cron: '0 0 1 * *'
|
64
|
+
filters:
|
65
|
+
branches:
|
66
|
+
only:
|
67
|
+
- master
|
68
|
+
jobs:
|
69
|
+
- build:
|
70
|
+
context: org-global
|
71
|
+
use-bundler-cache: false
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,20 +1,15 @@
|
|
1
1
|
AllCops:
|
2
2
|
TargetRubyVersion: 2.5
|
3
|
+
NewCops: enable
|
3
4
|
|
4
5
|
Layout/LineLength:
|
5
6
|
Max: 100
|
6
7
|
|
7
|
-
Lint/RaiseException:
|
8
|
-
Enabled: True
|
9
|
-
|
10
|
-
Lint/StructNewOverride:
|
11
|
-
Enabled: True
|
12
|
-
|
13
8
|
Metrics/AbcSize:
|
14
|
-
Max:
|
9
|
+
Max: 20
|
15
10
|
|
16
11
|
Metrics/BlockLength:
|
17
|
-
|
12
|
+
IgnoredMethods:
|
18
13
|
- let
|
19
14
|
- it
|
20
15
|
- describe
|
@@ -22,17 +17,11 @@ Metrics/BlockLength:
|
|
22
17
|
- specify
|
23
18
|
- define
|
24
19
|
|
20
|
+
Metrics/ParameterLists:
|
21
|
+
CountKeywordArgs: false
|
22
|
+
|
25
23
|
Metrics/ClassLength:
|
26
24
|
Max: 125
|
27
25
|
|
28
26
|
Metrics/MethodLength:
|
29
27
|
Max: 25
|
30
|
-
|
31
|
-
Style/HashEachMethods:
|
32
|
-
Enabled: True
|
33
|
-
|
34
|
-
Style/HashTransformKeys:
|
35
|
-
Enabled: True
|
36
|
-
|
37
|
-
Style/HashTransformValues:
|
38
|
-
Enabled: True
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 2.6.6
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# 3.1.0 (October 4th, 2021)
|
2
|
+
|
3
|
+
Additions
|
4
|
+
|
5
|
+
* Added Query#offset to help with callers needing paging support.
|
6
|
+
# 3.0.0 (March 11th, 2021)
|
7
|
+
|
8
|
+
### Additions
|
9
|
+
|
10
|
+
* Support for graph based models. This paves the way for representing more advanced features, such as sub-queries in a more clear way. Since graph based models are similar to DSL models, the hope is that they will be easier to work with and understand.
|
11
|
+
|
12
|
+
### Breaking Changes
|
13
|
+
|
14
|
+
* The `to_model` method on `Dbee::Base` objects has been removed. Use `to_schema` instead.
|
15
|
+
* The `ancestors!` method on `Dbee::Model` has been removed. Use `Dbee::Schema#expand_query_path` instead.
|
16
|
+
|
17
|
+
# 2.1.1 (July 14th, 2020)
|
18
|
+
|
19
|
+
* Removed guard that ensured a query has at least one field to establish a more rational base-case.
|
20
|
+
|
21
|
+
# 2.1.0 (July 13th, 2020)
|
2
22
|
|
3
23
|
### Additions:
|
4
24
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Dbee
|
2
2
|
|
3
|
-
[![
|
3
|
+
[![CircleCI](https://circleci.com/bb/bluemarble-ondemand/dbee/tree/master.svg?style=svg&circle-token=7f7afbea94912b2b75a889cae3e2c46a3a869d21)](https://circleci.com/bb/bluemarble-ondemand/dbee/tree/master)
|
4
4
|
|
5
5
|
Dbee arose out of a need for an ad-hoc reporting solution that included:
|
6
6
|
|
@@ -20,12 +20,12 @@ Both of these solutions ended up closely coupling our domain data layer to ad-ho
|
|
20
20
|
|
21
21
|
## Installation
|
22
22
|
|
23
|
-
This specific library is the core modeling component of the Dbee framework, but by itself, it not completely usable. You will need to provide a SQL generator which understands how to convert the data and query modeling to actual SQL. This library comes with a stub: Dbee::Providers::NullProvider, while the main reference implementation is split out into its own library: [dbee-active_record](https://github.com/bluemarblepayroll/dbee-active_record). Together these two libraries comprise a complete solution. Refer to the other library for more information on installation.
|
23
|
+
This specific library is the core modeling component of the Dbee framework, but by itself, it is not completely usable. You will need to provide a SQL generator which understands how to convert the data and query modeling to actual SQL. This library comes with a stub: Dbee::Providers::NullProvider, while the main reference implementation is split out into its own library: [dbee-active_record](https://github.com/bluemarblepayroll/dbee-active_record). Together these two libraries comprise a complete solution. Refer to the other library for more information on installation.
|
24
24
|
|
25
25
|
To install through Rubygems:
|
26
26
|
|
27
27
|
````
|
28
|
-
gem install
|
28
|
+
gem install dbee
|
29
29
|
````
|
30
30
|
|
31
31
|
You can also add this to your Gemfile:
|
@@ -189,49 +189,58 @@ The two code-first examples above should be technically equivalent.
|
|
189
189
|
You can choose to alternatively describe your data model using configuration. The YAML below is equivalent to the Ruby sub-classes above:
|
190
190
|
|
191
191
|
````yaml
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
192
|
+
practice:
|
193
|
+
table: practices
|
194
|
+
relationships:
|
195
|
+
patients:
|
196
|
+
model: patient
|
197
|
+
constraints:
|
198
|
+
- type: reference
|
199
|
+
name: practice_id
|
200
|
+
parent: id
|
201
|
+
patient:
|
202
|
+
table: patients
|
203
|
+
relationships:
|
204
|
+
notes:
|
205
|
+
model: note
|
206
|
+
constraints:
|
207
|
+
- type: reference
|
208
|
+
name: patient_id
|
209
|
+
parent: id
|
210
|
+
work_phone_number:
|
211
|
+
model: phone_number
|
212
|
+
constraints:
|
213
|
+
- type: reference
|
214
|
+
name: patient_id
|
215
|
+
parent: id
|
216
|
+
- type: static
|
217
|
+
name: phone_number_type
|
218
|
+
value: work
|
219
|
+
cell_phone_number:
|
220
|
+
model: phone_number
|
221
|
+
constraints:
|
222
|
+
- type: reference
|
223
|
+
name: patient_id
|
224
|
+
parent: id
|
225
|
+
- type: static
|
226
|
+
name: phone_number_type
|
227
|
+
value: cell
|
228
|
+
fax_phone_number:
|
229
|
+
model: phone_number
|
230
|
+
constraints:
|
231
|
+
- type: reference
|
232
|
+
name: patient_id
|
233
|
+
parent: id
|
234
|
+
- type: static
|
235
|
+
name: phone_number_type
|
236
|
+
value: fax
|
237
|
+
note:
|
238
|
+
table: notes
|
239
|
+
phone_number:
|
240
|
+
table: phones
|
232
241
|
````
|
233
242
|
|
234
|
-
It is up to you to determine which modeling technique to use as both are equivalent. Technically speaking, the code-first DSL is nothing more than syntactic sugar on top of Dbee::Model.
|
243
|
+
It is up to you to determine which modeling technique to use as both are equivalent. Technically speaking, the code-first DSL is nothing more than syntactic sugar on top of `Dbee::Schema` and `Dbee::Model`. Also note that prior to version three of this project, a more hierarchical tree based model configuration was used. See [Tree Based Model Backward Compatibility](#tree-based-model-backward-compatibility) below for more information on this.
|
235
244
|
|
236
245
|
#### Table Partitioning
|
237
246
|
|
@@ -275,6 +284,7 @@ Cats:
|
|
275
284
|
The Query API (Dbee::Query) is a simplified and abstract way to model an SQL query. A Query has the following components:
|
276
285
|
|
277
286
|
* fields (SELECT)
|
287
|
+
* from (FROM)
|
278
288
|
* filters (WHERE)
|
279
289
|
* sorters (ORDER BY)
|
280
290
|
* limit (LIMIT/TAKE)
|
@@ -291,6 +301,7 @@ Get all practices:
|
|
291
301
|
|
292
302
|
````ruby
|
293
303
|
query = {
|
304
|
+
from: 'practice',
|
294
305
|
fields: [
|
295
306
|
{ key_path: 'id' },
|
296
307
|
{ key_path: 'active' },
|
@@ -299,10 +310,11 @@ query = {
|
|
299
310
|
}
|
300
311
|
````
|
301
312
|
|
302
|
-
Get all practices, limit to
|
313
|
+
Get all practices, limit to 2, offset by 3, and sort by name (descending) then id (ascending):
|
303
314
|
|
304
315
|
````ruby
|
305
316
|
query = {
|
317
|
+
from: 'practice',
|
306
318
|
fields: [
|
307
319
|
{ key_path: 'id' },
|
308
320
|
{ key_path: 'active' },
|
@@ -312,7 +324,8 @@ query = {
|
|
312
324
|
{ key_path: 'name', direction: :descending },
|
313
325
|
{ key_path: 'id' }
|
314
326
|
],
|
315
|
-
limit:
|
327
|
+
limit: 2,
|
328
|
+
offset: 3
|
316
329
|
}
|
317
330
|
````
|
318
331
|
|
@@ -320,6 +333,7 @@ Get top 5 active practices and patient whose name start with 'Sm':
|
|
320
333
|
|
321
334
|
````ruby
|
322
335
|
query = {
|
336
|
+
from: 'practice',
|
323
337
|
fields: [
|
324
338
|
{ key_path: 'name', display: 'Practice Name' },
|
325
339
|
{ key_path: 'patients.first', display: 'Patient First Name' },
|
@@ -338,6 +352,7 @@ Get practice IDs, patient IDs, names, and cell phone numbers that starts with '5
|
|
338
352
|
|
339
353
|
````ruby
|
340
354
|
query = {
|
355
|
+
from: 'practice',
|
341
356
|
fields: [
|
342
357
|
{ key_path: 'id', display: 'Practice ID #' },
|
343
358
|
{ key_path: 'patients.id', display: 'Patient ID #' },
|
@@ -363,6 +378,22 @@ You execute a Query against a Data Model, using a Provider. The sample provider
|
|
363
378
|
|
364
379
|
Here are some sample executions based off the preceding examples:
|
365
380
|
|
381
|
+
##### Base Case
|
382
|
+
|
383
|
+
If a query has no fields then it is implied you would like all fields on the root table. For example:
|
384
|
+
|
385
|
+
````ruby
|
386
|
+
require 'dbee/providers/active_record_provider'
|
387
|
+
|
388
|
+
class Practice < Dbee::Base; end
|
389
|
+
|
390
|
+
provider = Dbee::Providers::ActiveRecordProvider.new
|
391
|
+
query = { from: 'practice' }
|
392
|
+
sql = Dbee.sql(Practice, query, provider)
|
393
|
+
````
|
394
|
+
|
395
|
+
It equivalent to saying: `SELECT practices.* FROM practices`. This helps to establish a deterministic base-case: it returns the same implicit columns that is independent of sql joins (sorters and/or filters may require sql joins.)
|
396
|
+
|
366
397
|
##### Code-First Execution
|
367
398
|
|
368
399
|
````ruby
|
@@ -373,6 +404,7 @@ class Practice < Dbee::Base; end
|
|
373
404
|
provider = Dbee::Providers::ActiveRecordProvider.new
|
374
405
|
|
375
406
|
query = {
|
407
|
+
from: 'practice',
|
376
408
|
fields: [
|
377
409
|
{ key_path: 'id' },
|
378
410
|
{ key_path: 'active' },
|
@@ -391,10 +423,11 @@ require 'dbee/providers/active_record_provider'
|
|
391
423
|
provider = Dbee::Providers::ActiveRecordProvider.new
|
392
424
|
|
393
425
|
model = {
|
394
|
-
|
426
|
+
practice: { table: 'practices' }
|
395
427
|
}
|
396
428
|
|
397
429
|
query = {
|
430
|
+
from: 'practice',
|
398
431
|
fields: [
|
399
432
|
{ key_path: 'id' },
|
400
433
|
{ key_path: 'active' },
|
@@ -414,19 +447,24 @@ Fields can be configured to use aggregation by setting its `aggregator` attribut
|
|
414
447
|
**Data Model**:
|
415
448
|
|
416
449
|
````yaml
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
450
|
+
practice:
|
451
|
+
table: practices
|
452
|
+
relationships:
|
453
|
+
patients:
|
454
|
+
model: patient
|
455
|
+
constraints:
|
456
|
+
- type: reference
|
457
|
+
name: practice_id
|
458
|
+
parent: id
|
459
|
+
patient:
|
460
|
+
table: patients
|
424
461
|
````
|
425
462
|
|
426
463
|
**Query**:
|
427
464
|
|
428
465
|
````ruby
|
429
466
|
query = {
|
467
|
+
from: 'practice',
|
430
468
|
fields: [
|
431
469
|
{
|
432
470
|
key_path: 'id',
|
@@ -476,19 +514,21 @@ id | patient_id | key | value
|
|
476
514
|
**Model Configuration**:
|
477
515
|
|
478
516
|
````yaml
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
517
|
+
patients:
|
518
|
+
relationships:
|
519
|
+
- patient_fields:
|
520
|
+
constraints:
|
521
|
+
- type: reference
|
522
|
+
parent: id
|
523
|
+
name: patient_id
|
524
|
+
patient_fields:
|
486
525
|
````
|
487
526
|
|
488
527
|
**Query**:
|
489
528
|
|
490
529
|
````ruby
|
491
530
|
query = {
|
531
|
+
from: 'patients',
|
492
532
|
fields: [
|
493
533
|
{
|
494
534
|
key_path: 'id',
|
@@ -530,7 +570,59 @@ ID # | First Name | Date of Birth | Drivers License #
|
|
530
570
|
-- | ---------- | ------------- | -----------------
|
531
571
|
1 | frank | 1900-01-01 | ABC123
|
532
572
|
|
573
|
+
## Tree Based Model Backward Compatibility
|
574
|
+
|
575
|
+
In version three of this gem, the representation of configuration based models was changed to be more of a graph structure than the previous tree structure. For backwards compatibility, it is still possible to pass this older tree based structure as the first argument `Dbee.sql`. The practices example would be represented this way in the old structure:
|
576
|
+
|
577
|
+
````yaml
|
578
|
+
# Deprecated tree based model configuration:
|
579
|
+
name: practice
|
580
|
+
table: practices
|
581
|
+
models:
|
582
|
+
- name: patients
|
583
|
+
constraints:
|
584
|
+
- type: reference
|
585
|
+
name: practice_id
|
586
|
+
parent: id
|
587
|
+
models:
|
588
|
+
- name: notes
|
589
|
+
constraints:
|
590
|
+
- type: reference
|
591
|
+
name: patient_id
|
592
|
+
parent: id
|
593
|
+
- name: work_phone_number
|
594
|
+
table: phones
|
595
|
+
constraints:
|
596
|
+
- type: reference
|
597
|
+
name: patient_id
|
598
|
+
parent: id
|
599
|
+
- type: static
|
600
|
+
name: phone_number_type
|
601
|
+
value: work
|
602
|
+
- name: cell_phone_number
|
603
|
+
table: phones
|
604
|
+
constraints:
|
605
|
+
- type: reference
|
606
|
+
name: patient_id
|
607
|
+
parent: id
|
608
|
+
- type: static
|
609
|
+
name: phone_number_type
|
610
|
+
value: cell
|
611
|
+
- name: fax_phone_number
|
612
|
+
table: phones
|
613
|
+
constraints:
|
614
|
+
- type: reference
|
615
|
+
name: patient_id
|
616
|
+
parent: id
|
617
|
+
- type: static
|
618
|
+
name: phone_number_type
|
619
|
+
value: fax
|
620
|
+
````
|
533
621
|
|
622
|
+
Also note to further maintain backwards compatibility, queries issued against
|
623
|
+
tree based models do not need the "from" attribute to be defined. This is
|
624
|
+
because the from/starting point of the query can be inferred as the model at
|
625
|
+
the root of the tree.
|
534
626
|
## Contributing
|
535
627
|
|
536
628
|
### Development Environment Configuration
|
@@ -570,7 +662,7 @@ Note: ensure you have proper authorization before trying to publish new versions
|
|
570
662
|
After code changes have successfully gone through the Pull Request review process then the following steps should be followed for publishing new versions:
|
571
663
|
|
572
664
|
1. Merge Pull Request into master
|
573
|
-
2. Update `
|
665
|
+
2. Update `version.rb` using [semantic versioning](https://semver.org/)
|
574
666
|
3. Install dependencies: `bundle`
|
575
667
|
4. Update `CHANGELOG.md` with release notes
|
576
668
|
5. Commit & push master to remote and ensure CI builds master successfully
|
data/dbee.gemspec
CHANGED
@@ -17,15 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
s.bindir = 'exe'
|
19
19
|
s.executables = []
|
20
|
-
s.homepage = 'https://github.com/bluemarblepayroll/dbee'
|
21
20
|
s.license = 'MIT'
|
22
|
-
s.metadata = {
|
23
|
-
'bug_tracker_uri' => 'https://github.com/bluemarblepayroll/dbee/issues',
|
24
|
-
'changelog_uri' => 'https://github.com/bluemarblepayroll/dbee/blob/master/CHANGELOG.md',
|
25
|
-
'documentation_uri' => 'https://www.rubydoc.info/gems/dbee',
|
26
|
-
'homepage_uri' => s.homepage,
|
27
|
-
'source_code_uri' => s.homepage
|
28
|
-
}
|
29
21
|
|
30
22
|
s.required_ruby_version = '>= 2.5'
|
31
23
|
|
@@ -34,9 +26,13 @@ Gem::Specification.new do |s|
|
|
34
26
|
|
35
27
|
s.add_development_dependency('guard-rspec', '~>4.7')
|
36
28
|
s.add_development_dependency('pry', '~>0')
|
29
|
+
s.add_development_dependency('pry-byebug')
|
37
30
|
s.add_development_dependency('rake', '~> 13')
|
38
31
|
s.add_development_dependency('rspec')
|
39
|
-
s.add_development_dependency('
|
40
|
-
s.add_development_dependency('
|
32
|
+
s.add_development_dependency('rspec_junit_formatter')
|
33
|
+
s.add_development_dependency('rubocop', '~> 1')
|
34
|
+
s.add_development_dependency('rubocop-rake')
|
35
|
+
s.add_development_dependency('rubocop-rspec')
|
36
|
+
s.add_development_dependency('simplecov', '~>0.19.0')
|
41
37
|
s.add_development_dependency('simplecov-console', '~>0.7.0')
|
42
38
|
end
|
data/lib/dbee/base.rb
CHANGED
@@ -7,8 +7,8 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
-
require_relative 'dsl/association'
|
11
10
|
require_relative 'dsl/association_builder'
|
11
|
+
require_relative 'dsl/association'
|
12
12
|
require_relative 'dsl/methods'
|
13
13
|
require_relative 'dsl/reflectable'
|
14
14
|
|
@@ -22,23 +22,9 @@ module Dbee
|
|
22
22
|
BASE_CLASS_CONSTANT = Dbee::Base
|
23
23
|
|
24
24
|
class << self
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
# of a Query. This is not true for configuration-first Model definitions because, in that
|
29
|
-
# case, cycles do not exist since the nature of the configuration is flat.
|
30
|
-
def to_model(key_chain, name = nil, constraints = [], path_parts = [])
|
31
|
-
derived_name = name.to_s.empty? ? inflected_class_name(self.name) : name.to_s
|
32
|
-
key = [key_chain, derived_name, constraints, path_parts]
|
33
|
-
|
34
|
-
to_models[key] ||= Model.make(
|
35
|
-
model_config(
|
36
|
-
key_chain,
|
37
|
-
derived_name,
|
38
|
-
constraints,
|
39
|
-
path_parts + [name]
|
40
|
-
)
|
41
|
-
)
|
25
|
+
# Returns the smallest needed Dbee::Schema for the provided key_chain.
|
26
|
+
def to_schema(key_chain)
|
27
|
+
DslSchemaBuilder.new(self, key_chain).to_schema
|
42
28
|
end
|
43
29
|
|
44
30
|
def inherited_table_name
|
@@ -58,43 +44,15 @@ module Dbee
|
|
58
44
|
end
|
59
45
|
end
|
60
46
|
|
61
|
-
|
62
|
-
|
63
|
-
def model_config(key_chain, name, constraints, path_parts)
|
64
|
-
{
|
65
|
-
constraints: constraints,
|
66
|
-
models: associations(key_chain, path_parts),
|
67
|
-
name: name,
|
68
|
-
partitioners: inherited_partitioners,
|
69
|
-
table: inherited_table_name
|
70
|
-
}
|
71
|
-
end
|
72
|
-
|
73
|
-
def associations(key_chain, path_parts)
|
74
|
-
inherited_associations.select { |c| key_chain.ancestor_path?(path_parts, c.name) }
|
75
|
-
.map do |association|
|
76
|
-
model_constant = association.model_constant
|
77
|
-
|
78
|
-
model_constant.to_model(
|
79
|
-
key_chain,
|
80
|
-
association.name,
|
81
|
-
association.constraints,
|
82
|
-
path_parts
|
83
|
-
)
|
84
|
-
end
|
47
|
+
def inflected_class_name
|
48
|
+
inflector.underscore(inflector.demodulize(name))
|
85
49
|
end
|
86
50
|
|
87
|
-
|
88
|
-
@to_models ||= {}
|
89
|
-
end
|
51
|
+
private
|
90
52
|
|
91
53
|
def inflected_table_name(name)
|
92
54
|
inflector.pluralize(inflector.underscore(inflector.demodulize(name)))
|
93
55
|
end
|
94
|
-
|
95
|
-
def inflected_class_name(name)
|
96
|
-
inflector.underscore(inflector.demodulize(name))
|
97
|
-
end
|
98
56
|
end
|
99
57
|
end
|
100
58
|
end
|