postgres_with 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ca230790590213616e6fece28510b13c3b4d17f66f33f8913132ea26f41ed493
4
+ data.tar.gz: 146f38e6d41e10b20d42810d114183304fc327e2db0703fac2de54e0e3da4ba2
5
+ SHA512:
6
+ metadata.gz: d14d96e9e8f9667c9d703cf52aed70fdda8102924ea12006d21b2fd08ab15d1f7a200e64e3f35026886d31941961a9f954c820518036089661e0cf0a56ed3f40
7
+ data.tar.gz: cf84a1c1a64aba00f183badc893fbe0399f0f1d5ac832ff284c15a727e5f62f92be9f041605e73dfda71be0e9cf3e71799b2c0a8de33b63388d49f05a7e23c2f
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ .env
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ bin/
20
+ .rbenv-version*
21
+ .ruby-version
22
+ .ruby-gemset
23
+ gemfiles/*.lock
24
+
25
+ spec/dummy/config/database.yml
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # PostgresWith
2
+
3
+ Adds CTEs for Postgres
4
+
5
+ ## Usage
6
+
7
+ Just `require 'postgres_with'` and use ActiveRecord as you normally would! postgres\_ext extends
8
+ ActiveRecord's data type handling and query methods in both Arel and
9
+ ActiveRecord.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,35 @@
1
+ class CTEProxy
2
+ include ActiveRecord::Querying
3
+ include ActiveRecord::Sanitization::ClassMethods
4
+ include ActiveRecord::Reflection::ClassMethods
5
+
6
+ attr_accessor :reflections, :current_scope
7
+ attr_reader :connection, :arel_table
8
+
9
+ def initialize(name, model)
10
+ @name = name
11
+ @arel_table = Arel::Table.new(name)
12
+ @model = model
13
+ @connection = model.connection
14
+ @_reflections = {}
15
+ end
16
+
17
+ def name
18
+ @name
19
+ end
20
+
21
+ def table_name
22
+ name
23
+ end
24
+
25
+ delegate :column_names, :columns_hash, :model_name, :primary_key, :attribute_alias?,
26
+ :aggregate_reflections, :instantiate, :type_for_attribute, :relation_delegate_class, to: :@model
27
+
28
+ private
29
+
30
+ def reflections
31
+ @_reflections
32
+ end
33
+
34
+ alias _reflections reflections
35
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveRecord::Querying
2
+ delegate :with, to: :all
3
+
4
+ def from_cte(name, expression)
5
+ table = Arel::Table.new(name)
6
+
7
+ cte_proxy = CTEProxy.new(name, self)
8
+ relation = ActiveRecord::Relation.new cte_proxy, cte_proxy.arel_table
9
+ relation.with name => expression
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord
2
+ class Relation
3
+ class Merger # :nodoc:
4
+ def normal_values
5
+ NORMAL_VALUES + [:with]
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,98 @@
1
+ module ActiveRecord
2
+ module QueryMethods
3
+ # WithChain objects act as placeholder for queries in which #with does not have any parameter.
4
+ # In this case, #with must be chained with #recursive to return a new relation.
5
+ class WithChain
6
+ def initialize(scope)
7
+ @scope = scope
8
+ end
9
+
10
+ # Returns a new relation expressing WITH RECURSIVE
11
+ def recursive(*args)
12
+ @scope.with_values += args
13
+ @scope.recursive_value = true
14
+ @scope
15
+ end
16
+ end
17
+
18
+ [:with].each do |name|
19
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
20
+ def #{name}_values # def select_values
21
+ @values[:#{name}] || [] # @values[:select] || []
22
+ end # end
23
+ #
24
+ def #{name}_values=(values) # def select_values=(values)
25
+ raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded
26
+ @values[:#{name}] = values # @values[:select] = values
27
+ end # end
28
+ CODE
29
+ end
30
+
31
+ [:recursive].each do |name|
32
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
33
+ def #{name}_value=(value) # def readonly_value=(value)
34
+ raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded
35
+ @values[:#{name}] = value # @values[:readonly] = value
36
+ end # end
37
+
38
+ def #{name}_value # def readonly_value
39
+ @values[:#{name}] # @values[:readonly]
40
+ end # end
41
+ CODE
42
+ end
43
+
44
+ def with(opts = :chain, *rest)
45
+ if opts == :chain
46
+ WithChain.new(spawn)
47
+ elsif opts.blank?
48
+ self
49
+ else
50
+ spawn.with!(opts, *rest)
51
+ end
52
+ end
53
+
54
+ def with!(opts = :chain, *rest) # :nodoc:
55
+ if opts == :chain
56
+ WithChain.new(self)
57
+ else
58
+ self.with_values += [opts] + rest
59
+ self
60
+ end
61
+ end
62
+
63
+ def build_arel_with_extensions
64
+ arel = build_arel_without_extensions
65
+
66
+ with_statements = with_values.flat_map do |with_value|
67
+ case with_value
68
+ when String
69
+ with_value
70
+ when Hash
71
+ with_value.map do |name, expression|
72
+ case expression
73
+ when String
74
+ select = Arel::Nodes::SqlLiteral.new "(#{expression})"
75
+ when ActiveRecord::Relation, Arel::SelectManager
76
+ select = Arel::Nodes::SqlLiteral.new "(#{expression.to_sql})"
77
+ end
78
+ Arel::Nodes::As.new Arel::Nodes::SqlLiteral.new("\"#{name.to_s}\""), select
79
+ end
80
+ when Arel::Nodes::As
81
+ with_value
82
+ end
83
+ end
84
+ unless with_statements.empty?
85
+ if recursive_value
86
+ arel.with :recursive, with_statements
87
+ else
88
+ arel.with with_statements
89
+ end
90
+ end
91
+
92
+ arel
93
+ end
94
+
95
+ alias_method :build_arel_without_extensions, :build_arel
96
+ alias_method :build_arel, :build_arel_with_extensions
97
+ end
98
+ end
@@ -0,0 +1,2 @@
1
+ require 'postgres_with/active_record/relation/merger'
2
+ require 'postgres_with/active_record/relation/query_methods'
@@ -0,0 +1,4 @@
1
+ require 'active_record'
2
+ require 'postgres_with/active_record/relation'
3
+ require 'postgres_with/active_record/cte_proxy'
4
+ require 'postgres_with/active_record/querying'
@@ -0,0 +1,3 @@
1
+ module PostgresWith
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'postgres_with/version'
2
+ require 'postgres_with/active_record'
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/postgres_with/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Derrick Neier"]
6
+ gem.email = ["derrick.neier@gmail.com"]
7
+ gem.description = %q{Adds support for CTEs for PostgreSQL and ActiveRecord}
8
+ gem.summary = %q{Extends ActiveRecord to handle PostgreSQL CTEs}
9
+ gem.homepage = 'https://github.com/dneier/postgres_with'
10
+ gem.licenses = ['MIT']
11
+
12
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.name = "postgres_with"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = PostgresWith::VERSION
17
+
18
+ gem.add_dependency 'activerecord', '>= 4.0'
19
+ gem.add_dependency 'arel', '>= 4.0'
20
+
21
+ gem.add_development_dependency 'pg', '>= 0.13'
22
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postgres_with
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Derrick Neier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: arel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pg
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.13'
55
+ description: Adds support for CTEs for PostgreSQL and ActiveRecord
56
+ email:
57
+ - derrick.neier@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - README.md
65
+ - Rakefile
66
+ - lib/postgres_with.rb
67
+ - lib/postgres_with/active_record.rb
68
+ - lib/postgres_with/active_record/cte_proxy.rb
69
+ - lib/postgres_with/active_record/querying.rb
70
+ - lib/postgres_with/active_record/relation.rb
71
+ - lib/postgres_with/active_record/relation/merger.rb
72
+ - lib/postgres_with/active_record/relation/query_methods.rb
73
+ - lib/postgres_with/version.rb
74
+ - postgres_with.gemspec
75
+ homepage: https://github.com/dneier/postgres_with
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.7.6
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Extends ActiveRecord to handle PostgreSQL CTEs
99
+ test_files: []