diff --git a/lib/rasti/db/collection.rb b/lib/rasti/db/collection.rb index 3397614..e2474ce 100644 --- a/lib/rasti/db/collection.rb +++ b/lib/rasti/db/collection.rb @@ -2,7 +2,7 @@ module Rasti module DB class Collection - QUERY_METHODS = (Query::DATASET_CHAINED_METHODS + [:graph, :join, :count, :all, :each, :first, :pluck, :primary_keys, :any?, :empty?, :raw]).freeze + QUERY_METHODS = (Query::DATASET_CHAINED_METHODS + [:graph, :join, :count, :all, :each, :first, :pluck, :primary_keys, :any?, :empty?, :raw, :nql]).freeze include Enumerable include Helpers::WithSchema diff --git a/lib/rasti/db/query.rb b/lib/rasti/db/query.rb index 9649485..1ea6f19 100644 --- a/lib/rasti/db/query.rb +++ b/lib/rasti/db/query.rb @@ -92,6 +92,15 @@ def to_s end alias_method :inspect, :to_s + def nql(filter_expression) + sentence = nql_parser.parse filter_expression + + dependency_tables = sentence.dependency_tables + query = dependency_tables.empty? ? self : join(*dependency_tables) + + query.where sentence.filter_condition + end + private def chainable(&block) @@ -122,6 +131,10 @@ def respond_to_missing?(method, include_private=false) collection_class.queries.key?(method) || super end + def nql_parser + NQL::SyntaxParser.new + end + attr_reader :collection_class, :dataset, :relations, :schema end diff --git a/spec/query_spec.rb b/spec/query_spec.rb index c58e959..fd2468b 100644 --- a/spec/query_spec.rb +++ b/spec/query_spec.rb @@ -177,4 +177,52 @@ end + describe 'NQL' do + + before do + 1.upto(10) do |i| + db[:people].insert user_id: i, + document_number: i, + first_name: "Name #{i}", + last_name: "Last Name #{i}", + birth_date: Time.now + end + + 1.upto(3) { |i| db[:categories].insert name: "Category #{i}" } + + db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 1' + db[:comments].insert post_id: 1, user_id: 7, text: 'Comment 2' + db[:comments].insert post_id: 2, user_id: 2, text: 'Comment 3' + + db[:categories_posts].insert post_id: 1, category_id: 1 + db[:categories_posts].insert post_id: 1, category_id: 2 + db[:categories_posts].insert post_id: 2, category_id: 2 + db[:categories_posts].insert post_id: 2, category_id: 3 + db[:categories_posts].insert post_id: 3, category_id: 3 + end + + it 'Filter to self table' do + people_query = Rasti::DB::Query.new People, db[:people] + + people_query.nql('user_id > 7') + .map(&:user_id) + .sort + .must_equal [8, 9, 10] + end + + it 'Filter to join table' do + posts_query.nql('categories.name = Category 2') + .map(&:id) + .sort + .must_equal [1, 2] + end + + it 'Filter to 2nd order relation' do + posts_query.nql('comments.user.person.document_number = 7') + .map(&:id) + .must_equal [1] + end + + end + end \ No newline at end of file