Skip to content

Commit

Permalink
Merge pull request #4 from gabynaiman/nql_array_node
Browse files Browse the repository at this point in the history
Nql array node
  • Loading branch information
gabynaiman committed Dec 22, 2020
2 parents 2a1ee8f + 58d5692 commit 68bd4fe
Show file tree
Hide file tree
Showing 40 changed files with 951 additions and 70 deletions.
12 changes: 11 additions & 1 deletion lib/rasti/db.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
require 'hierarchical_graph'
require 'class_config'
require 'hash_ext'
require 'inflecto'
require 'multi_require'

module Rasti
module DB

extend MultiRequire
extend ClassConfig

require_relative 'db/query'
require_relative_pattern 'db/relations/*'
require_relative_pattern 'db/type_converters/postgres_types/*'
require_relative_pattern 'db/type_converters/sqlite_types/*'
require_relative 'db/nql/nodes/constants/base'
require_relative_pattern 'db/nql/filter_condition_strategies/types/*'
require_relative_pattern 'db/**/*'

attr_config :type_converters, []
attr_config :nql_filter_condition_strategy, nil

def self.to_db(db, collection_name, attribute_name, value)
type_converters.inject(value) do |result, type_converter|
Expand All @@ -33,5 +38,10 @@ def self.from_db(value)
end
end

def self.nql_filter_condition_for(comparison_name, identifier, argument)
raise 'Undefined Rasti::DB.nql_filter_condition_strategy' unless nql_filter_condition_strategy
nql_filter_condition_strategy.filter_condition_for comparison_name, identifier, argument
end

end
end
17 changes: 17 additions & 0 deletions lib/rasti/db/nql/filter_condition_strategies/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
class Base

def filter_condition_for(comparison_name, identifier, argument)
type = type_for argument
raise UnsupportedTypeComparison.new(type, comparison_name) unless type.respond_to?(comparison_name)
type.public_send comparison_name, identifier, argument.value
end

end
end
end
end
end
21 changes: 21 additions & 0 deletions lib/rasti/db/nql/filter_condition_strategies/postgres.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
class Postgres < Base

PG_TYPES = {
array: Types::PGArray
}

private

def type_for(argument)
PG_TYPES.fetch(argument.type, Types::Generic)
end

end
end
end
end
end
21 changes: 21 additions & 0 deletions lib/rasti/db/nql/filter_condition_strategies/sqlite.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
class SQLite < Base

SQLITE_TYPES = {
array: Types::SQLiteArray
}

private

def type_for(argument)
SQLITE_TYPES.fetch(argument.type, Types::Generic)
end

end
end
end
end
end
49 changes: 49 additions & 0 deletions lib/rasti/db/nql/filter_condition_strategies/types/generic.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
module Types
class Generic

def self.equal(identifier, value)
{identifier => value}
end

def self.not_equal(identifier, value)
Sequel.negate equal(identifier, value)
end

def self.greater_than(identifier, value)
identifier > value
end

def self.greater_than_or_equal(identifier, value)
identifier >= value
end

def self.less_than(identifier, value)
identifier < value
end

def self.less_than_or_equal(identifier, value)
identifier <= value
end

def self.like(identifier, value)
Sequel.ilike identifier, value
end

def self.include(identifier, value)
Sequel.ilike identifier, "%#{value}%"
end

def self.not_include(identifier, value)
~include(identifier, value)
end

end
end
end
end
end
end
32 changes: 32 additions & 0 deletions lib/rasti/db/nql/filter_condition_strategies/types/pg_array.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
module Types
class PGArray

def self.equal(identifier, values)
Sequel.&(
Sequel.pg_array(identifier).contains(Sequel.pg_array(values)),
Sequel.pg_array(identifier).contained_by(Sequel.pg_array(values))
)
end

def self.not_equal(identifier, values)
~equal(identifier, values)
end

def self.include(identifier, values)
Sequel.pg_array(identifier).overlaps Sequel.pg_array(values)
end

def self.not_include(identifier, values)
~include(identifier, values)
end

end
end
end
end
end
end
34 changes: 34 additions & 0 deletions lib/rasti/db/nql/filter_condition_strategies/types/sqlite_array.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
module Types
class SQLiteArray

def self.equal(identifier, values)
array = values.map { |value| "\"#{value}\"" }.join(',')
{identifier => "[#{array}]"}
end

def self.not_equal(identifier, values)
Sequel.|(*values.map { |value| ~Sequel.like(identifier, "%\"#{value}\"%") })
end

def self.like(identifier, values)
Sequel.|(*values.map { |value| Sequel.like(identifier, "%#{value}%") })
end

def self.include(identifier, values)
Sequel.|(*values.map { |value| Sequel.like(identifier, "%\"#{value}\"%") })
end

def self.not_include(identifier, values)
Sequel.&(*values.map { |value| ~Sequel.like(identifier, "%\"#{value}\"%") })
end

end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Rasti
module DB
module NQL
module FilterConditionStrategies
class UnsupportedTypeComparison < StandardError

attr_reader :argument_type, :comparison_name

def initialize(argument_type, comparison_name)
@argument_type = argument_type
@comparison_name = comparison_name
end

def message
"Unsupported comparison #{comparison_name} for #{argument_type}"
end

end
end
end
end
end
21 changes: 21 additions & 0 deletions lib/rasti/db/nql/nodes/array_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Rasti
module DB
module NQL
module Nodes
class ArrayContent < Treetop::Runtime::SyntaxNode

def values
[left.value] + right_value
end

private

def right_value
right.is_a?(self.class) ? right.values : [right.value]
end

end
end
end
end
end
10 changes: 10 additions & 0 deletions lib/rasti/db/nql/nodes/comparisons/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ def computed_attributes(collection_class)
attribute.computed_attributes(collection_class)
end

def filter_condition(collection_class)
DB.nql_filter_condition_for comparison_name, attribute.identifier(collection_class), argument
end

private

def comparison_name
Inflecto.underscore(Inflecto.demodulize(self.class)).to_sym
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/equal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class Equal < Base

def filter_condition(collection_class)
{ attribute.identifier(collection_class) => argument.value }
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/greater_than.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class GreaterThan < Base

def filter_condition(collection_class)
attribute.identifier(collection_class) > argument.value
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/greater_than_or_equal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class GreaterThanOrEqual < Base

def filter_condition(collection_class)
attribute.identifier(collection_class) >= argument.value
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/include.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class Include < Base

def filter_condition(collection_class)
Sequel.ilike(attribute.identifier(collection_class), "%#{argument.value}%")
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/less_than.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class LessThan < Base

def filter_condition(collection_class)
attribute.identifier(collection_class) < argument.value
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/less_than_or_equal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class LessThanOrEqual < Base

def filter_condition(collection_class)
attribute.identifier(collection_class) <= argument.value
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/like.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class Like < Base

def filter_condition(collection_class)
Sequel.ilike(attribute.identifier(collection_class), argument.value)
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/not_equal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class NotEqual < Base

def filter_condition(collection_class)
Sequel.negate(attribute.identifier(collection_class) => argument.value)
end

end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rasti/db/nql/nodes/comparisons/not_include.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ module Nodes
module Comparisons
class NotInclude < Base

def filter_condition(collection_class)
~ Sequel.ilike(attribute.identifier(collection_class), "%#{argument.value}%")
end

end
end
end
Expand Down
Loading

0 comments on commit 68bd4fe

Please sign in to comment.