flounder 0.17.0 → 0.18.0
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 +4 -4
- data/Gemfile.lock +1 -1
- data/HISTORY +3 -0
- data/flounder.gemspec +1 -1
- data/lib/flounder/helpers/entity.rb +12 -2
- data/lib/flounder/query/base.rb +12 -0
- data/lib/flounder/query/select.rb +27 -0
- data/lib/flounder/relation.rb +27 -8
- data/qed/joins.md +8 -2
- metadata +29 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 212f1134237b0adfe5f4f94d8f79d508a2997ce9
|
4
|
+
data.tar.gz: e093b402cf0cf81c9b01c178ac6b20847d4b9403
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8444a433354c815819d087c8c44d85bb56b3389d452d6f5ab554927e22a056763eda19383be7bd94cc4cf5c9d87b8452a61de254de30283acda9b33a881a60e7
|
7
|
+
data.tar.gz: 334f3c8a41c8b26ba4cf86f6ec8e36813106c4015daa2110d84a190d82854612097cb0dcbbefdf199114e72f5930d71c1798f4ae97aa86b5c221eaf317049e6a
|
data/Gemfile.lock
CHANGED
data/HISTORY
CHANGED
data/flounder.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "flounder"
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.18.0'
|
6
6
|
s.summary = "Flounder is a way to write SQL simply in Ruby. It deals with everything BUT object relational mapping. "
|
7
7
|
s.email = "kaspar.schiess@technologyastronauts.ch"
|
8
8
|
s.homepage = "https://bitbucket.org/technologyastronauts/oss_flounder"
|
@@ -1,15 +1,25 @@
|
|
1
1
|
module Flounder::Helpers
|
2
|
+
|
3
|
+
# Helper module that helps with entity resolution. To include this module in
|
4
|
+
# a class, you need to provide the following two methods:
|
5
|
+
#
|
6
|
+
# * has_entity?(sym) -> Boolean
|
7
|
+
# Decides if a given symbol can be converted into an entity
|
8
|
+
# * resolve_entity(sym) -> Entity
|
9
|
+
# Resolves an entity from a symbol name.
|
10
|
+
#
|
2
11
|
module Entity
|
3
12
|
def entity_like? something
|
4
13
|
something.kind_of?(Flounder::Entity) ||
|
5
|
-
something.kind_of?(
|
14
|
+
something.kind_of?(Flounder::EntityAlias) ||
|
15
|
+
something.kind_of?(Symbol) && has_entity?(something)
|
6
16
|
end
|
7
17
|
def convert_to_entity something
|
8
18
|
case something
|
9
19
|
when Flounder::Entity, Flounder::EntityAlias
|
10
20
|
return something
|
11
21
|
when Symbol
|
12
|
-
return
|
22
|
+
return resolve_entity(something)
|
13
23
|
else
|
14
24
|
fail "Not entity-like - yet! (#{something.inspect})"
|
15
25
|
end
|
data/lib/flounder/query/base.rb
CHANGED
@@ -139,6 +139,18 @@ module Flounder::Query
|
|
139
139
|
# should be overridden
|
140
140
|
end
|
141
141
|
|
142
|
+
# Checks if a given symbol can be an entity after resolution.
|
143
|
+
#
|
144
|
+
def has_entity? sym
|
145
|
+
domain.has_entity?(sym)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Resolves an entity through the domain.
|
149
|
+
#
|
150
|
+
def resolve_entity sym
|
151
|
+
domain[sym]
|
152
|
+
end
|
153
|
+
|
142
154
|
# Rewrites a statement that contains bind placeholders like '$1' to
|
143
155
|
# contain placeholders starting at offset+1. Also checks that no
|
144
156
|
# placeholder exceeds the limit.
|
@@ -40,11 +40,16 @@ module Flounder::Query
|
|
40
40
|
|
41
41
|
attr_reader :join_entity, :last_join
|
42
42
|
|
43
|
+
# maps relations that were included in this select to their entities.
|
44
|
+
attr_reader :relation_entity_map
|
45
|
+
|
43
46
|
def _join join_node, entity
|
44
47
|
entity = convert_to_entity(entity)
|
45
48
|
|
46
49
|
@last_join = entity
|
47
50
|
|
51
|
+
@relation_entity_map = {}
|
52
|
+
|
48
53
|
table = entity.table
|
49
54
|
manager.join(table, join_node)
|
50
55
|
add_fields_to_default(entity)
|
@@ -168,6 +173,24 @@ module Flounder::Query
|
|
168
173
|
end
|
169
174
|
|
170
175
|
private
|
176
|
+
# Checks if a symbol can be turned into an entity. Overwritten from base
|
177
|
+
# query because we want to allow entity names that are introduced through
|
178
|
+
# #connect as well.
|
179
|
+
#
|
180
|
+
def has_entity? sym
|
181
|
+
super || relation_entity_map.has_key?(sym)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Resolves an entity through the domain. Overwritten from base query because
|
185
|
+
# we want to allow entity names that are introduced through #connect as
|
186
|
+
# well.
|
187
|
+
#
|
188
|
+
def resolve_entity sym
|
189
|
+
return domain[sym] if domain.has_entity?(sym)
|
190
|
+
return relation_entity_map[sym] if relation_entity_map.has_key?(sym)
|
191
|
+
|
192
|
+
raise NoSuchEntity, "No such entity #{sym.inspect} either in this select statement or in the domain."
|
193
|
+
end
|
171
194
|
|
172
195
|
# Follows a given relationship spec. Does NOT change anchoring.
|
173
196
|
#
|
@@ -178,7 +201,10 @@ module Flounder::Query
|
|
178
201
|
when Symbol
|
179
202
|
relation = entity.relations[spec]
|
180
203
|
raise "No such relation #{spec.inspect} on entity #{entity}." unless relation
|
204
|
+
|
181
205
|
relation.apply(self)
|
206
|
+
relation_entity_map[spec] = relation.linked_entity
|
207
|
+
|
182
208
|
when Hash
|
183
209
|
spec.each do |k, v|
|
184
210
|
follow_relation_spec(join_entity, k)
|
@@ -186,6 +212,7 @@ module Flounder::Query
|
|
186
212
|
|
187
213
|
follow_relation_spec(join_entity, v)
|
188
214
|
end
|
215
|
+
|
189
216
|
when Array
|
190
217
|
spec.each do |v|
|
191
218
|
follow_relation_spec(join_entity, v)
|
data/lib/flounder/relation.rb
CHANGED
@@ -10,21 +10,40 @@ module Flounder
|
|
10
10
|
domain, type, name, entity_ref, join_conditions
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
13
|
+
def linked_entity
|
14
|
+
@linked_entity ||= begin
|
15
|
+
entity = convert_to_entity(entity_ref)
|
16
|
+
|
17
|
+
if name != entity_ref
|
18
|
+
# TODO maybe using name for both singular and plural is not a good
|
19
|
+
# idea. Maybe it is.
|
20
|
+
entity = entity.as(name, name)
|
21
|
+
end
|
15
22
|
|
16
|
-
|
17
|
-
# TODO maybe using name for both singular and plural is not a good idea.
|
18
|
-
# Maybe it is.
|
19
|
-
entity = entity.as(name, name)
|
23
|
+
entity
|
20
24
|
end
|
25
|
+
end
|
21
26
|
|
27
|
+
def apply query
|
22
28
|
query.
|
23
|
-
join(
|
29
|
+
join(linked_entity).
|
24
30
|
on(join_conditions)
|
25
|
-
end
|
31
|
+
end
|
26
32
|
|
27
33
|
private
|
34
|
+
# Checks if a given symbol can be an entity after resolution.
|
35
|
+
#
|
36
|
+
def has_entity? sym
|
37
|
+
domain.has_entity?(sym)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Resolves an entity through the domain.
|
41
|
+
#
|
42
|
+
def resolve_entity sym
|
43
|
+
domain[sym]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Now that the above two methods exist, we can use this helper:
|
28
47
|
include Flounder::Helpers::Entity
|
29
48
|
end
|
30
49
|
end
|
data/qed/joins.md
CHANGED
@@ -105,11 +105,17 @@ Or a more complicated example, using hashes and arrays in the join specification
|
|
105
105
|
|
106
106
|
~~~ruby
|
107
107
|
# Query for users, joining posts and joining comments from posts (anchor)
|
108
|
-
query = users.
|
108
|
+
query = users.
|
109
|
+
connect(:posts => [:comments, :approver]).
|
110
|
+
where(:approver, id: 1)
|
109
111
|
|
112
|
+
# This manual route is of course always available.
|
113
|
+
approver = users.as(:approver, :approver)
|
110
114
|
users.
|
111
115
|
join(:posts).on(:id => :author_id).anchor.
|
112
116
|
join(:comments).on(:id => :post_id).
|
113
|
-
join(
|
117
|
+
join(approver).on(:author_id => :id).
|
118
|
+
where(approver, id: 1).
|
119
|
+
to_sql.assert == query.to_sql
|
114
120
|
~~~
|
115
121
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flounder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kaspar Schiess
|
@@ -9,114 +9,114 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-11-
|
12
|
+
date: 2014-11-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: arel
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '5'
|
21
|
-
- -
|
21
|
+
- - '>'
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 5.0.1
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '5'
|
31
|
-
- -
|
31
|
+
- - '>'
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 5.0.1
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: pg
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.17'
|
41
41
|
type: :runtime
|
42
42
|
prerelease: false
|
43
43
|
version_requirements: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0.17'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: hashie
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3'
|
55
|
-
- -
|
55
|
+
- - '>='
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '3.2'
|
58
58
|
type: :runtime
|
59
59
|
prerelease: false
|
60
60
|
version_requirements: !ruby/object:Gem::Requirement
|
61
61
|
requirements:
|
62
|
-
- -
|
62
|
+
- - ~>
|
63
63
|
- !ruby/object:Gem::Version
|
64
64
|
version: '3'
|
65
|
-
- -
|
65
|
+
- - '>='
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: '3.2'
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
69
|
name: connection_pool
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- -
|
72
|
+
- - ~>
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '2'
|
75
75
|
type: :runtime
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- -
|
79
|
+
- - ~>
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '2'
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: pg-hstore
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
|
-
- -
|
86
|
+
- - ~>
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '1.2'
|
89
|
-
- -
|
89
|
+
- - '>='
|
90
90
|
- !ruby/object:Gem::Version
|
91
91
|
version: 1.2.0
|
92
92
|
type: :runtime
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
|
-
- -
|
96
|
+
- - ~>
|
97
97
|
- !ruby/object:Gem::Version
|
98
98
|
version: '1.2'
|
99
|
-
- -
|
99
|
+
- - '>='
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: 1.2.0
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: aggregate
|
104
104
|
requirement: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
|
-
- -
|
106
|
+
- - ~>
|
107
107
|
- !ruby/object:Gem::Version
|
108
108
|
version: '0.2'
|
109
|
-
- -
|
109
|
+
- - '>='
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: 0.2.2
|
112
112
|
type: :runtime
|
113
113
|
prerelease: false
|
114
114
|
version_requirements: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ~>
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0.2'
|
119
|
-
- -
|
119
|
+
- - '>='
|
120
120
|
- !ruby/object:Gem::Version
|
121
121
|
version: 0.2.2
|
122
122
|
description: " Flounder is the missing piece between the database and your Ruby
|
@@ -127,14 +127,11 @@ executables: []
|
|
127
127
|
extensions: []
|
128
128
|
extra_rdoc_files: []
|
129
129
|
files:
|
130
|
+
- flounder.gemspec
|
130
131
|
- Gemfile
|
131
132
|
- Gemfile.lock
|
132
133
|
- HACKING
|
133
134
|
- HISTORY
|
134
|
-
- LICENSE
|
135
|
-
- README
|
136
|
-
- flounder.gemspec
|
137
|
-
- lib/flounder.rb
|
138
135
|
- lib/flounder/connection.rb
|
139
136
|
- lib/flounder/connection_pool.rb
|
140
137
|
- lib/flounder/domain.rb
|
@@ -155,6 +152,8 @@ files:
|
|
155
152
|
- lib/flounder/query/update.rb
|
156
153
|
- lib/flounder/relation.rb
|
157
154
|
- lib/flounder/symbol_extensions.rb
|
155
|
+
- lib/flounder.rb
|
156
|
+
- LICENSE
|
158
157
|
- qed/applique/ae.rb
|
159
158
|
- qed/applique/flounder.rb
|
160
159
|
- qed/applique/setup_domain.rb
|
@@ -173,6 +172,7 @@ files:
|
|
173
172
|
- qed/projection.md
|
174
173
|
- qed/selects.md
|
175
174
|
- qed/updates.md
|
175
|
+
- README
|
176
176
|
homepage: https://bitbucket.org/technologyastronauts/oss_flounder
|
177
177
|
licenses:
|
178
178
|
- MIT
|
@@ -183,17 +183,17 @@ require_paths:
|
|
183
183
|
- lib
|
184
184
|
required_ruby_version: !ruby/object:Gem::Requirement
|
185
185
|
requirements:
|
186
|
-
- -
|
186
|
+
- - '>='
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: '0'
|
189
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
190
|
requirements:
|
191
|
-
- -
|
191
|
+
- - '>='
|
192
192
|
- !ruby/object:Gem::Version
|
193
193
|
version: '0'
|
194
194
|
requirements: []
|
195
195
|
rubyforge_project:
|
196
|
-
rubygems_version: 2.
|
196
|
+
rubygems_version: 2.0.14
|
197
197
|
signing_key:
|
198
198
|
specification_version: 4
|
199
199
|
summary: Flounder is a way to write SQL simply in Ruby. It deals with everything BUT
|
@@ -217,4 +217,3 @@ test_files:
|
|
217
217
|
- qed/projection.md
|
218
218
|
- qed/selects.md
|
219
219
|
- qed/updates.md
|
220
|
-
has_rdoc:
|