rasti-db 1.1.1 → 1.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/README.md +8 -0
  4. data/lib/rasti/db.rb +9 -18
  5. data/lib/rasti/db/collection.rb +1 -1
  6. data/lib/rasti/db/nql/invalid_expression_error.rb +19 -0
  7. data/lib/rasti/db/nql/nodes/binary_node.rb +25 -0
  8. data/lib/rasti/db/nql/nodes/comparisons/base.rb +17 -0
  9. data/lib/rasti/db/nql/nodes/comparisons/equal.rb +17 -0
  10. data/lib/rasti/db/nql/nodes/comparisons/greater_than.rb +17 -0
  11. data/lib/rasti/db/nql/nodes/comparisons/greater_than_or_equal.rb +17 -0
  12. data/lib/rasti/db/nql/nodes/comparisons/include.rb +17 -0
  13. data/lib/rasti/db/nql/nodes/comparisons/less_than.rb +17 -0
  14. data/lib/rasti/db/nql/nodes/comparisons/less_than_or_equal.rb +17 -0
  15. data/lib/rasti/db/nql/nodes/comparisons/like.rb +17 -0
  16. data/lib/rasti/db/nql/nodes/comparisons/not_equal.rb +17 -0
  17. data/lib/rasti/db/nql/nodes/comparisons/not_include.rb +17 -0
  18. data/lib/rasti/db/nql/nodes/conjunction.rb +15 -0
  19. data/lib/rasti/db/nql/nodes/constants/false.rb +17 -0
  20. data/lib/rasti/db/nql/nodes/constants/float.rb +17 -0
  21. data/lib/rasti/db/nql/nodes/constants/integer.rb +17 -0
  22. data/lib/rasti/db/nql/nodes/constants/literal_string.rb +17 -0
  23. data/lib/rasti/db/nql/nodes/constants/string.rb +17 -0
  24. data/lib/rasti/db/nql/nodes/constants/time.rb +23 -0
  25. data/lib/rasti/db/nql/nodes/constants/true.rb +17 -0
  26. data/lib/rasti/db/nql/nodes/disjunction.rb +15 -0
  27. data/lib/rasti/db/nql/nodes/field.rb +23 -0
  28. data/lib/rasti/db/nql/nodes/parenthesis_sentence.rb +19 -0
  29. data/lib/rasti/db/nql/nodes/sentence.rb +19 -0
  30. data/lib/rasti/db/nql/syntax.rb +2266 -0
  31. data/lib/rasti/db/nql/syntax.treetop +168 -0
  32. data/lib/rasti/db/query.rb +15 -0
  33. data/lib/rasti/db/relations/graph_builder.rb +3 -3
  34. data/lib/rasti/db/version.rb +1 -1
  35. data/rasti-db.gemspec +3 -1
  36. data/spec/coverage_helper.rb +5 -1
  37. data/spec/nql/dependency_tables_spec.rb +35 -0
  38. data/spec/nql/filter_condition_spec.rb +146 -0
  39. data/spec/nql/syntax_parser_spec.rb +209 -0
  40. data/spec/query_spec.rb +53 -0
  41. metadata +68 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59398cc3e6f63febe047699d750790d24b276ee3
4
- data.tar.gz: 6aead8231e6f12a2827f7a5227f4f9ce9dfe8084
3
+ metadata.gz: 8d134f095bd5c09bb827c9a1b51b2a1a10dc333b
4
+ data.tar.gz: 9e70fd2c3b67c5039530ce14f391f6fd572c26fa
5
5
  SHA512:
6
- metadata.gz: cb1c73d96614154a238f944504d48d3d533662c5adab2aad2d050a18c8cbf971ab71be59cdad9e893646d7c68c3bd6487184d456feba0933e20fcc6cf61f7c25
7
- data.tar.gz: b5595081dc1fbe8d0ee1ab465baa1231fa5cbf60f04c53a4d71a30379669f1349725821aac7db6ef248ac41c80e3b946dd4e9f740718ba9f0c6b969de1b235dd
6
+ metadata.gz: 68982576814409051789fef84204e31acebb4c21c2a1b52e9c3de30870cb738eaa70e5f03c7661ea46994a73ff2f9303da956c5bf693bde82f028592ee2fc3d3
7
+ data.tar.gz: 9dd4ac963e7cfaed91684a26981484941f25f06dba345c656dda600bc95254f75dbe248f43e571f4309ce6b810580493cc2e496ab6a771251abd4981bd21cc5a
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.3.0
1
+ ruby-2.4.5
data/README.md CHANGED
@@ -175,6 +175,14 @@ posts.where(id: [1,2]).pluck(:id, :title) # => [[1, ...], [2, ...]]
175
175
  posts.join(:user).where(name: 'User 4') # => [Post, ...]
176
176
  ```
177
177
 
178
+ ## Development
179
+
180
+ Rasti::DB uses treetop to perform queries using natural language. To recompile the syntax, simply run the following command in `lib/rasti/db/nql`:
181
+
182
+ ```
183
+ tt syntax.treetop -o syntax.rb
184
+ ```
185
+
178
186
  ## Contributing
179
187
 
180
188
  Bug reports and pull requests are welcome on GitHub at https://github.com/gabynaiman/rasti-db.
data/lib/rasti/db.rb CHANGED
@@ -2,31 +2,22 @@ require 'sequel'
2
2
  require 'consty'
3
3
  require 'time'
4
4
  require 'timing'
5
+ require 'treetop'
5
6
  require 'class_config'
6
-
7
- require_relative 'db/version'
8
- require_relative 'db/helpers'
9
- require_relative 'db/query'
10
- require_relative 'db/relations/graph_builder'
11
- require_relative 'db/relations/base'
12
- require_relative 'db/relations/one_to_many'
13
- require_relative 'db/relations/one_to_one'
14
- require_relative 'db/relations/many_to_one'
15
- require_relative 'db/relations/many_to_many'
16
- require_relative 'db/collection'
17
- require_relative 'db/model'
18
- require_relative 'db/type_converters/time_in_zone'
19
- require_relative 'db/type_converters/postgres_types/array'
20
- require_relative 'db/type_converters/postgres_types/hstore'
21
- require_relative 'db/type_converters/postgres_types/json'
22
- require_relative 'db/type_converters/postgres_types/jsonb'
23
- require_relative 'db/type_converters/postgres'
7
+ require 'multi_require'
24
8
 
25
9
  module Rasti
26
10
  module DB
27
11
 
12
+ extend MultiRequire
28
13
  extend ClassConfig
29
14
 
15
+ require_relative 'db/helpers'
16
+ require_relative 'db/query'
17
+ require_relative_pattern 'db/relations/*'
18
+ require_relative_pattern 'db/type_converters/postgres_types/*'
19
+ require_relative_pattern 'db/**/*'
20
+
30
21
  attr_config :type_converters, []
31
22
 
32
23
  def self.to_db(db, collection_name, attribute_name, value)
@@ -2,7 +2,7 @@ module Rasti
2
2
  module DB
3
3
  class Collection
4
4
 
5
- QUERY_METHODS = (Query::DATASET_CHAINED_METHODS + [:graph, :join, :count, :all, :each, :first, :pluck, :primary_keys, :any?, :empty?, :raw]).freeze
5
+ QUERY_METHODS = (Query::DATASET_CHAINED_METHODS + [:graph, :join, :count, :all, :each, :first, :pluck, :primary_keys, :any?, :empty?, :raw, :nql]).freeze
6
6
 
7
7
  include Enumerable
8
8
  include Helpers::WithSchema
@@ -0,0 +1,19 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ class InvalidExpressionError < StandardError
5
+
6
+ attr_reader :expression
7
+
8
+ def initialize(expression)
9
+ @expression = expression
10
+ end
11
+
12
+ def message
13
+ "Invalid filter expression: #{expression}"
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ class BinaryNode < Treetop::Runtime::SyntaxNode
6
+
7
+ def dependency_tables
8
+ values.flat_map(&:dependency_tables)
9
+ end
10
+
11
+ def values
12
+ @values ||= values_for(left) + values_for(right)
13
+ end
14
+
15
+ private
16
+
17
+ def values_for(node)
18
+ node.class == self.class ? node.values : [node]
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class Base < Treetop::Runtime::SyntaxNode
7
+
8
+ def dependency_tables
9
+ field.tables.empty? ? [] : [field.tables.join('.')]
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class Equal < Base
7
+
8
+ def filter_condition
9
+ { field.identifier => argument.value }
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class GreaterThan < Base
7
+
8
+ def filter_condition
9
+ field.identifier > argument.value
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class GreaterThanOrEqual < Base
7
+
8
+ def filter_condition
9
+ field.identifier >= argument.value
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class Include < Base
7
+
8
+ def filter_condition
9
+ Sequel.ilike(field.identifier, "%#{argument.value}%")
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class LessThan < Base
7
+
8
+ def filter_condition
9
+ field.identifier < argument.value
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class LessThanOrEqual < Base
7
+
8
+ def filter_condition
9
+ field.identifier <= argument.value
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class Like < Base
7
+
8
+ def filter_condition
9
+ Sequel.ilike(field.identifier, argument.value)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class NotEqual < Base
7
+
8
+ def filter_condition
9
+ Sequel.negate(field.identifier => argument.value)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Comparisons
6
+ class NotInclude < Base
7
+
8
+ def filter_condition
9
+ ~ Sequel.ilike(field.identifier, "%#{argument.value}%")
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ class Conjunction < BinaryNode
6
+
7
+ def filter_condition
8
+ Sequel.&(*values.map(&:filter_condition))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Constants
6
+ class False < Treetop::Runtime::SyntaxNode
7
+
8
+ def value
9
+ false
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Constants
6
+ class Float < Treetop::Runtime::SyntaxNode
7
+
8
+ def value
9
+ text_value.to_f
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Constants
6
+ class Integer < Treetop::Runtime::SyntaxNode
7
+
8
+ def value
9
+ text_value.to_i
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Constants
6
+ class LiteralString < Treetop::Runtime::SyntaxNode
7
+
8
+ def value
9
+ string.text_value
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Constants
6
+ class String < Treetop::Runtime::SyntaxNode
7
+
8
+ def value
9
+ text_value.strip
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module Rasti
2
+ module DB
3
+ module NQL
4
+ module Nodes
5
+ module Constants
6
+ class Time < Treetop::Runtime::SyntaxNode
7
+
8
+ def value
9
+ time.to_s
10
+ end
11
+
12
+ private
13
+
14
+ def time
15
+ @time ||= Timing::TimeInZone.parse text_value
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end