rasti-db 1.1.1 → 1.2.0

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