-
-
Save dskecse/07fed1bec56d8c68a9a2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/config/initializers/postgres_ext.rb b/config/initializers/postgres_ext.rb | |
new file mode 100644 | |
index 0000000..8b49f77 | |
--- /dev/null | |
+++ b/config/initializers/postgres_ext.rb | |
@@ -0,0 +1 @@ | |
+require './lib/postgres_ext/postgres_ext' | |
diff --git a/lib/postgres_ext/postgres_ext.rb b/lib/postgres_ext/postgres_ext.rb | |
new file mode 100644 | |
index 0000000..c4957a6 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext.rb | |
@@ -0,0 +1,7 @@ | |
+require_relative 'postgres_ext/active_record' | |
+require_relative 'postgres_ext/arel' | |
diff --git a/lib/postgres_ext/postgres_ext/active_record.rb b/lib/postgres_ext/postgres_ext/active_record.rb | |
new file mode 100644 | |
index 0000000..5d0c2f2 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/active_record.rb | |
@@ -0,0 +1,7 @@ | |
+require 'active_record' | |
+require_relative 'active_record/relation' | |
diff --git a/lib/postgres_ext/postgres_ext/active_record/relation.rb b/lib/postgres_ext/postgres_ext/active_record/relation.rb | |
new file mode 100644 | |
index 0000000..3bef1d5 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/active_record/relation.rb | |
@@ -0,0 +1,6 @@ | |
+require_relative 'relation/query_methods' | |
diff --git a/lib/postgres_ext/postgres_ext/active_record/relation/query_methods.rb b/lib/postgres_ext/postgres_ext/active_record/relation/query_methods.rb | |
new file mode 100644 | |
index 0000000..818f943 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/active_record/relation/query_methods.rb | |
@@ -0,0 +1,32 @@ | |
+module ActiveRecord | |
+ module QueryMethods | |
+ class WhereChain | |
+ def overlap(opts, *rest) | |
+ substitute_comparisons(opts, rest, Arel::Nodes::Overlap, 'overlap') | |
+ end | |
+ | |
+ private | |
+ | |
+ def build_where_chain(opts, rest, &block) | |
+ where_value = @scope.send(:build_where, opts, rest).map(&block) | |
+ @scope.where_values += where_value | |
+ @scope | |
+ end | |
+ | |
+ def substitute_comparisons(opts, rest, arel_node_class, method) | |
+ build_where_chain(opts, rest) do |rel| | |
+ case rel | |
+ when Arel::Nodes::In, Arel::Nodes::Equality | |
+ arel_node_class.new(rel.left, rel.right) | |
+ else | |
+ raise ArgumentError, "Invalid argument for .where.#{method}(), got #{rel.class}" | |
+ end | |
+ end | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/lib/postgres_ext/postgres_ext/arel.rb b/lib/postgres_ext/postgres_ext/arel.rb | |
new file mode 100644 | |
index 0000000..1e57b3e | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/arel.rb | |
@@ -0,0 +1,8 @@ | |
+require_relative 'arel/nodes' | |
+require_relative 'arel/predications' | |
+require_relative 'arel/visitors' | |
diff --git a/lib/postgres_ext/postgres_ext/arel/nodes.rb b/lib/postgres_ext/postgres_ext/arel/nodes.rb | |
new file mode 100644 | |
index 0000000..afd3540 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/arel/nodes.rb | |
@@ -0,0 +1,6 @@ | |
+require_relative 'nodes/array_nodes' | |
diff --git a/lib/postgres_ext/postgres_ext/arel/nodes/array_nodes.rb b/lib/postgres_ext/postgres_ext/arel/nodes/array_nodes.rb | |
new file mode 100644 | |
index 0000000..70cf563 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/arel/nodes/array_nodes.rb | |
@@ -0,0 +1,14 @@ | |
+require 'arel/nodes/binary' | |
+ | |
+module Arel | |
+ module Nodes | |
+ class Overlap < Arel::Nodes::Binary | |
+ def operator; '&&' end | |
+ end | |
+ end | |
+end | |
diff --git a/lib/postgres_ext/postgres_ext/arel/predications.rb b/lib/postgres_ext/postgres_ext/arel/predications.rb | |
new file mode 100644 | |
index 0000000..c93df32 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/arel/predications.rb | |
@@ -0,0 +1,14 @@ | |
+require 'arel/predications' | |
+ | |
+module Arel | |
+ module Predications | |
+ def overlap(other) | |
+ Nodes::Overlap.new self, other | |
+ end | |
+ end | |
+end | |
diff --git a/lib/postgres_ext/postgres_ext/arel/visitors.rb b/lib/postgres_ext/postgres_ext/arel/visitors.rb | |
new file mode 100644 | |
index 0000000..6ec0e79 | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/arel/visitors.rb | |
@@ -0,0 +1,6 @@ | |
+require_relative 'visitors/postgresql' | |
diff --git a/lib/postgres_ext/postgres_ext/arel/visitors/postgresql.rb b/lib/postgres_ext/postgres_ext/arel/visitors/postgresql.rb | |
new file mode 100644 | |
index 0000000..a39de8e | |
--- /dev/null | |
+++ b/lib/postgres_ext/postgres_ext/arel/visitors/postgresql.rb | |
@@ -0,0 +1,27 @@ | |
+require 'arel/visitors/postgresql' | |
+ | |
+module Arel | |
+ module Visitors | |
+ class PostgreSQL | |
+ private | |
+ | |
+ def visit_Array o, a | |
+ column = a.relation.engine.connection.schema_cache.columns(a.relation.name).find { |col| col.name == a.name.to_s } if a | |
+ if column && column.respond_to?(:array) && column.array | |
+ quoted o, a | |
+ else | |
+ o.empty? ? 'NULL' : o.map { |x| visit x }.join(', ') | |
+ end | |
+ end | |
+ | |
+ def visit_Arel_Nodes_Overlap o, a = nil | |
+ "#{visit o.left, a} && #{visit o.right, o.left}" | |
+ end | |
+ end | |
+ end | |
+end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment