okdoki_sql_ladder 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9f9f154b080374d2a8fcda3f31a6c505c6c4213d
4
+ data.tar.gz: 576a457f919d024389f688543d3f11a5e57f313d
5
+ SHA512:
6
+ metadata.gz: ed22dfc15b02c2b55e4266406cf8978e0b2abc1f8bacdeabd9fb005d63af48a2d42e74f5b4ae31e3b2805a783b275ddc52c196883796b14c6bf1923bb6eeb38d
7
+ data.tar.gz: 3a1caef46d421b7cc37bd6ed43c7b5dd1b49feb5cafd7520afc52203ca890636e22e630ae9de7436de3af97c40d311c93f15ec8a46cef42a97260f4dd0f1a428
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in okdoki_sql_ladder.gemspec
4
+ gemspec
@@ -0,0 +1,23 @@
1
+
2
+ Copyright (c) 2014 da99
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+
2
+ # okdoki\_sql\_ladder
3
+
4
+ A Ruby gem to generate SQL dealing with parent-child-grandchild records.
5
+
6
+ This gem is targeted at [Okdoki](https://github.com/da99/okdoki).
7
+
8
+ *NOTE:* It won't be much use to you.
9
+
10
+ ## Alternatives
11
+
12
+ * Polymorphic Finder [http://robots.thoughtbot.com/code-show-and-tell-polymorphic-finder?utm_source=rubyweekly&utm_medium=email](http://robots.thoughtbot.com/code-show-and-tell-polymorphic-finder?utm_source=rubyweekly&utm_medium=email)
13
+
14
+ ## Installation
15
+
16
+ gem 'okdoki_sql_ladder'
17
+
18
+ ## Usage
19
+
20
+ No coming any time soon.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # -*- bash -*-
3
+ #
4
+ #
5
+ set -u -e -o pipefail
6
+
7
+ files="$(find specs/ -maxdepth 1 -type f -iname "*.rb" -and -not -iname "helpers.rb")"
8
+ if [[ -z "$files" ]]; then
9
+ colorize yellow "No tests found." 1>&2
10
+ exit 0
11
+ else
12
+ if [[ ( ! -z "$@" ) && ( -f "$1" ) ]]; then
13
+ bundle exec bacon specs/helpers.rb "$@"
14
+ else
15
+ bundle exec bacon specs/helpers.rb $files "$@"
16
+ fi
17
+ fi
@@ -0,0 +1,81 @@
1
+
2
+ require "about_pos"
3
+
4
+ module Okdoki_Sql_Ladder
5
+
6
+ Curr = Struct.new(:cte)
7
+ Prev = Struct.new(:cte)
8
+
9
+ end # === module Okdoki_Sql_Ladder ===
10
+
11
+ def Okdoki_Sql_Ladder o
12
+ tag = "#{o.class.to_s.downcase} ladder tag"
13
+
14
+ # === Get parents array:
15
+ sqls = o.parent_sql
16
+ i_dig_sql = I_Dig_Sql.new
17
+
18
+ # === Turn parent array into sql array:
19
+ About_Pos.Back(sqls) { |v, i, meta|
20
+ cte_table_name = meta[:cte_table_name] = "#{o.class.to_s.downcase}_ladder_#{i}"
21
+
22
+ with_sql = case v
23
+
24
+ when Proc
25
+ v
26
+ .call(Okdoki_Sql_Ladder::Curr.new(cte_table_name), Okdoki_Sql_Ladder::Prev.new(meta.prev? ? meta.prev[:cte_table_name] : nil))
27
+ .AS(cte_table_name)
28
+
29
+ when Array
30
+ klass = if meta.bottom?
31
+ v.first.class
32
+ else
33
+ v.first
34
+ end
35
+ fkey = v[1] || 'parent_id'
36
+
37
+ if meta.top? # TOP
38
+ I_Dig_Sql.new("SELECT ? as class_id, id, NULL as parent_id
39
+ FROM #{klass.table_name}
40
+ WHERE id in ( SELECT parent_id FROM #{meta.prev[:cte_table_name]} )", klass.class_id)
41
+ .AS(cte_table_name)
42
+
43
+ elsif meta.middle? # MIDDLE
44
+ I_Dig_Sql.new("SELECT ? AS class_id, id, ? AS parent_id
45
+ FROM #{klass.table_name}
46
+ WHERE id IN ( SELECT parent_id FROM #{meta.prev[:cte_table_name]} )", klass.class_id, fkey)
47
+ .AS(cte_table_name)
48
+
49
+ else meta.bottom? # BOTTOM
50
+ I_Dig_Sql.new("SELECT ? AS class_id, id, ? AS parent_id
51
+ FROM #{klass.table_name}
52
+ WHERE id = ?", klass.class_id, fkey, o.id)
53
+ .AS(cte_table_name)
54
+ end
55
+ else
56
+ raise "Unknown type for sql: #{v.inspect}"
57
+ end
58
+
59
+ i_dig_sql.WITH(with_sql).tag_as(tag)
60
+ }
61
+ # ---------------------------------------------------
62
+
63
+ i_dig_sql.WITH(
64
+ I_Dig_Sql.new(
65
+ i_dig_sql
66
+ .find_tagged(tag)
67
+ .map { |s| "SELECT * FROM #{s.AS}" }
68
+ .join("\nUNION\n")
69
+ )
70
+ .AS("#{o.class.to_s.downcase}_ladder_sql")
71
+ )
72
+
73
+ i_dig_sql
74
+ end
75
+
76
+
77
+
78
+
79
+
80
+
81
+
@@ -0,0 +1,15 @@
1
+
2
+ unless Object.const_defined?(:I_Dig_Sql)
3
+ require 'i_dig_sql'
4
+ end
5
+
6
+
7
+ module Okdoki_Sql_Ladder_Because_I_Dig_Sql
8
+ def ladder
9
+ @ladder ||= Okdoki_Sql_Ladder.new(self)
10
+ end
11
+ end # === module Okdoki_Sql_Ladder_Because_I_Dig_Sql ===
12
+
13
+ class I_Dig_Sql
14
+ include Okdoki_Sql_Ladder_Because_I_Dig_Sql
15
+ end # === class I_Dig_Sql ===
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "okdoki_sql_ladder"
7
+ spec.version = `cat VERSION`
8
+ spec.authors = ["da99"]
9
+ spec.email = ["i-hate-spam-1234567@mailinator.com"]
10
+ spec.summary = %q{A Ruby gem to generate SQL dealing with parent-child-grandchild records.}
11
+ spec.description = %q{
12
+ A gem that uses the i_dig_sql gem to generate SQL
13
+ strings. You can it an instance and it generates the
14
+ SQL to find its ancestors:
15
+ Example: page -> chapter -> book -> library
16
+ }
17
+ spec.homepage = "https://github.com/da99/okdoki_sql_ladder"
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency "about_pos", "~> 0.1"
26
+ spec.add_dependency "i_dig_sql", "~> 0.1"
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.5"
29
+ spec.add_development_dependency "rake"
30
+ spec.add_development_dependency "bacon"
31
+ spec.add_development_dependency "Bacon_Colored"
32
+ spec.add_development_dependency "pry"
33
+ spec.add_development_dependency "diffy"
34
+ end
@@ -0,0 +1,90 @@
1
+
2
+ describe ".ladder_sql with Array params" do
3
+
4
+ before do
5
+
6
+ class A
7
+
8
+ class << self
9
+ def class_id; 1; end
10
+ def table_name; "a"; end
11
+ def parent_sql child
12
+ [[self, nil]]
13
+ end
14
+ end # === class self ===
15
+
16
+ end
17
+
18
+ class B
19
+
20
+ class << self
21
+ def class_id; 2; end
22
+ def table_name; "b"; end
23
+ def parent_sql child
24
+ A.parent_sql(self).push [self, "a_id"]
25
+ end
26
+ end # === class self ===
27
+
28
+ end
29
+
30
+ class C
31
+
32
+ class << self
33
+ def class_id; 3; end
34
+ def table_name; "c"; end
35
+ end # === class self ===
36
+
37
+ def id; 3; end
38
+
39
+ def parent_sql
40
+ B.parent_sql(self).push [self, 'b_id']
41
+ end
42
+
43
+ end
44
+ end # === before
45
+
46
+ it "turns an array of class/fkeys into an i_dig_sql" do
47
+
48
+ sql = Okdoki_Sql_Ladder(C.new)
49
+
50
+ common(sql).should == common(%~
51
+ WITH c_ladder_2 AS (
52
+ SELECT ? AS class_id, id, ? AS parent_id
53
+ FROM c
54
+ WHERE id = ?
55
+ )
56
+ ,
57
+ c_ladder_1 AS (
58
+ SELECT ? AS class_id, id, ? AS parent_id
59
+ FROM b
60
+ WHERE id IN ( SELECT parent_id FROM c_ladder_2 )
61
+ )
62
+ ,
63
+ c_ladder_0 AS (
64
+ SELECT ? as class_id, id, NULL as parent_id
65
+ FROM a
66
+ WHERE id in ( SELECT parent_id FROM c_ladder_1 )
67
+ )
68
+ ,
69
+ c_ladder_sql AS (
70
+ SELECT * FROM c_ladder_2
71
+ UNION
72
+ SELECT * FROM c_ladder_1
73
+ UNION
74
+ SELECT * FROM c_ladder_0
75
+ )
76
+ ~)
77
+ end
78
+
79
+ it "passes all args to final i_dig_sql return value" do
80
+ sql = Okdoki_Sql_Ladder(C.new)
81
+ args(sql).should == [
82
+ C.class_id, "b_id", C.new.id,
83
+ B.class_id, "a_id",
84
+ A.class_id
85
+ ]
86
+ end
87
+
88
+ end # === describe .ladder with Array params ===
89
+
90
+
@@ -0,0 +1,106 @@
1
+ require "i_dig_sql"
2
+
3
+ describe ".ladder with lambda params" do
4
+
5
+ before do
6
+ class A
7
+ class << self
8
+ def class_id; 1; end
9
+ def table_name; "a"; end
10
+ def parent_sql child
11
+ [ ->(curr, prev) {
12
+ I_Dig_Sql.new("SELECT ? AS class_id, id, NULL AS parent_id
13
+ FROM #{table_name}
14
+ WHERE id IN ( SELECT parent_id FROM #{prev.cte} )", class_id)
15
+ } ]
16
+ end
17
+ end # === class self ===
18
+ end
19
+
20
+ class B
21
+ class << self
22
+ def class_id; 2; end
23
+ def table_name; "b"; end
24
+ def parent_sql child
25
+ A.parent_sql(self).push ->(curr, prev) {
26
+ I_Dig_Sql.new(
27
+ %$
28
+ SELECT ? AS class_id, id, ? AS parent_id
29
+ FROM #{table_name}
30
+ WHERE id IN ( SELECT parent_id FROM #{prev.cte} )
31
+ $, class_id, "a_id"
32
+ )
33
+ }
34
+ end
35
+ end # === class self ===
36
+
37
+ end
38
+
39
+ class C
40
+ class << self
41
+ def class_id; 3; end
42
+ def table_name; "c"; end
43
+ end # === class self ===
44
+
45
+ def id; 3; end
46
+
47
+ def parent_sql
48
+ me = self
49
+ B.parent_sql(self).push ->(curr, prev) {
50
+ I_Dig_Sql.new(%$
51
+ SELECT ? AS class_id, id, ? AS parent_id
52
+ FROM #{self.class.table_name}
53
+ WHERE id = ?
54
+ $, me.class.class_id, "b_id", id)
55
+ }
56
+ end
57
+ end
58
+ end # === before
59
+
60
+ it "turns an array of lambdas into an i_dig_sql" do
61
+
62
+ sql = Okdoki_Sql_Ladder(C.new)
63
+
64
+ common(sql).should == common(%~
65
+ WITH c_ladder_2 AS (
66
+
67
+ SELECT ? AS class_id, id, ? AS parent_id
68
+ FROM c
69
+ WHERE id = ?
70
+
71
+ )
72
+ ,
73
+ c_ladder_1 AS (
74
+
75
+ SELECT ? AS class_id, id, ? AS parent_id
76
+ FROM b
77
+ WHERE id IN ( SELECT parent_id FROM c_ladder_2 )
78
+
79
+ )
80
+ ,
81
+ c_ladder_0 AS (
82
+ SELECT ? AS class_id, id, NULL AS parent_id
83
+ FROM a
84
+ WHERE id IN ( SELECT parent_id FROM c_ladder_1 )
85
+ )
86
+ ,
87
+ c_ladder_sql AS (
88
+ SELECT * FROM c_ladder_2
89
+ UNION
90
+ SELECT * FROM c_ladder_1
91
+ UNION
92
+ SELECT * FROM c_ladder_0
93
+ )
94
+ ~)
95
+ end
96
+
97
+ it "passes the proper args to the final i_dig_sql value" do
98
+ sql = Okdoki_Sql_Ladder(C.new)
99
+ args(sql).should == [
100
+ C.class_id, "b_id", C.new.id,
101
+ B.class_id, "a_id",
102
+ A.class_id
103
+ ]
104
+ end
105
+
106
+ end # === describe .ladder with lambda params ===
@@ -0,0 +1,26 @@
1
+
2
+ require 'Bacon_Colored'
3
+ require 'okdoki_sql_ladder'
4
+ require 'pry'
5
+ require "diffy"
6
+
7
+ require "i_dig_sql"
8
+
9
+ Diffy::Diff.default_format = :color
10
+
11
+ def diff actual, target
12
+ Diffy::Diff.new(actual, target)
13
+ end
14
+
15
+ def args o
16
+ o.to_sql[:args]
17
+ end
18
+
19
+ def common o
20
+ case o
21
+ when I_Dig_Sql
22
+ common(o.to_sql[:sql])
23
+ else
24
+ o.strip.split.join(" ").upcase
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: okdoki_sql_ladder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - da99
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: about_pos
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: i_dig_sql
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bacon
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: Bacon_Colored
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: diffy
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: "\n A gem that uses the i_dig_sql gem to generate SQL\n strings.
126
+ You can it an instance and it generates the\n SQL to find its ancestors:\n Example:
127
+ page -> chapter -> book -> library\n "
128
+ email:
129
+ - i-hate-spam-1234567@mailinator.com
130
+ executables:
131
+ - test
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".gitignore"
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - VERSION
140
+ - bin/test
141
+ - lib/okdoki_sql_ladder.rb
142
+ - lib/okdoki_sql_ladder/i_dig_sql.rb
143
+ - okdoki_sql_ladder.gemspec
144
+ - specs/as_array.rb
145
+ - specs/as_lambda.rb
146
+ - specs/helpers.rb
147
+ homepage: https://github.com/da99/okdoki_sql_ladder
148
+ licenses:
149
+ - MIT
150
+ metadata: {}
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 2.2.2
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: A Ruby gem to generate SQL dealing with parent-child-grandchild records.
171
+ test_files: []