flounder 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/flounder.gemspec +1 -1
- data/lib/flounder/connection.rb +6 -1
- data/lib/flounder/query.rb +34 -11
- data/lib/flounder/symbol_extensions.rb +3 -3
- data/qed/index.md +1 -1
- data/qed/ordering.md +57 -0
- data/qed/projection.md +19 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fa808fa17085d2e8f7c70a808ec4aa6c3b3ffe7
|
4
|
+
data.tar.gz: 47ab3d8800befc2e6864cb077cf715fbe1c20621
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c7fdedda33c494affe87c3392049e901caa969c1a1cea7592ca3b0aad20fe1da296bb8157bcf6915a1ab626b994ced623fe952ecacab955271f25bb3385ebce
|
7
|
+
data.tar.gz: e2e96f3d0a887444b56212e3cef71434bbb9929b257be45c75b09089113708565890356b54a071cc7244cf68b3af5f190127aab6281c078800650ae5a70f42cc
|
data/Gemfile.lock
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.4.
|
5
|
+
s.version = '0.4.1'
|
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/laboratory_flounder"
|
data/lib/flounder/connection.rb
CHANGED
@@ -79,7 +79,12 @@ module Flounder
|
|
79
79
|
|entity, name, value, type_oid, binary, idx|
|
80
80
|
# TODO remove entity resolution from each_field?
|
81
81
|
|
82
|
-
|
82
|
+
# TODO This is currently here to cover the special case of a query.
|
83
|
+
# Certainly needs refactoring.
|
84
|
+
#
|
85
|
+
processed_entity, processed_name = yield name if block_given?
|
86
|
+
entity = processed_entity || entity
|
87
|
+
name = processed_name || name
|
83
88
|
|
84
89
|
typecast_value = typecast(type_oid, value)
|
85
90
|
|
data/lib/flounder/query.rb
CHANGED
@@ -39,7 +39,7 @@ module Flounder
|
|
39
39
|
|
40
40
|
def where conditions={}
|
41
41
|
conditions.each do |k, v|
|
42
|
-
manager.where(
|
42
|
+
manager.where(transform_hash(k, v))
|
43
43
|
end
|
44
44
|
self
|
45
45
|
end
|
@@ -79,7 +79,7 @@ module Flounder
|
|
79
79
|
def on join_conditions
|
80
80
|
join_conditions.each do |k, v|
|
81
81
|
manager.on(
|
82
|
-
|
82
|
+
transform_hash(k, join_field(v)))
|
83
83
|
end
|
84
84
|
self
|
85
85
|
end
|
@@ -109,8 +109,8 @@ module Flounder
|
|
109
109
|
#
|
110
110
|
def order_by *field_list
|
111
111
|
field_list.each do |field|
|
112
|
-
field =
|
113
|
-
manager.order field
|
112
|
+
field = transform field
|
113
|
+
manager.order field
|
114
114
|
end
|
115
115
|
self
|
116
116
|
end
|
@@ -225,22 +225,45 @@ module Flounder
|
|
225
225
|
manager.project *default_projection
|
226
226
|
end
|
227
227
|
end
|
228
|
+
|
229
|
+
# Called on a value for a
|
230
|
+
# * order by
|
231
|
+
# clause, this returns a field that can be passed to Arel
|
232
|
+
# * #where
|
233
|
+
# * #on
|
234
|
+
#
|
235
|
+
def transform field
|
236
|
+
case field
|
237
|
+
when String
|
238
|
+
Immediate.new(field).to_arel_field
|
239
|
+
when Flounder::Field
|
240
|
+
field.fully_qualified_name
|
241
|
+
when Flounder::SymbolExtensions::Modifier
|
242
|
+
field.to_arel_field(from_entity).send field.kind
|
243
|
+
else
|
244
|
+
from_entity[field].arel_field
|
245
|
+
end
|
246
|
+
end
|
228
247
|
|
229
|
-
# Called on each key/value pair of a
|
230
|
-
# condition
|
248
|
+
# Called on each key/value pair of a
|
249
|
+
# * condition
|
250
|
+
# * join
|
251
|
+
# clause, this returns a field that can be passed to Arel
|
252
|
+
# * #where
|
253
|
+
# * #on
|
231
254
|
#
|
232
|
-
def
|
255
|
+
def transform_hash field, value
|
233
256
|
if value.kind_of? Field
|
234
257
|
value = value.arel_field
|
235
258
|
end
|
236
259
|
|
237
260
|
case field
|
238
261
|
when Symbol
|
239
|
-
|
262
|
+
join_and_condition_part(from_entity[field].arel_field, value)
|
240
263
|
when Flounder::Field
|
241
|
-
|
264
|
+
join_and_condition_part(field.arel_field, value)
|
242
265
|
when Flounder::SymbolExtensions::Modifier
|
243
|
-
|
266
|
+
join_and_condition_part(
|
244
267
|
field.to_arel_field(from_entity),
|
245
268
|
value,
|
246
269
|
field.kind)
|
@@ -248,7 +271,7 @@ module Flounder
|
|
248
271
|
fail "Could not transform condition part. (#{field.inspect}, #{value.inspect})"
|
249
272
|
end
|
250
273
|
end
|
251
|
-
def
|
274
|
+
def join_and_condition_part arel_field, value, kind=:eq
|
252
275
|
case value
|
253
276
|
when Symbol
|
254
277
|
value_field = from_entity[value].arel_field
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Flounder
|
2
2
|
module SymbolExtensions
|
3
3
|
class Modifier < Struct.new(:sym, :kind)
|
4
|
-
def to_arel_field
|
4
|
+
def to_arel_field entity
|
5
5
|
af = case sym
|
6
6
|
when Symbol
|
7
|
-
|
7
|
+
entity[sym].arel_field
|
8
8
|
when Flounder::Field
|
9
9
|
sym.arel_field
|
10
10
|
else
|
@@ -13,7 +13,7 @@ module Flounder
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
[:not_eq, :lt, :gt, :gteq, :lteq, :matches].each do |kind|
|
16
|
+
[:not_eq, :lt, :gt, :gteq, :lteq, :matches, :asc, :desc].each do |kind|
|
17
17
|
define_method kind do
|
18
18
|
Modifier.new(self, kind)
|
19
19
|
end
|
data/qed/index.md
CHANGED
@@ -96,7 +96,7 @@ The call to `#anchor` anchors all further joins at that point.
|
|
96
96
|
domain[:users].where(id: 2013).order_by(domain[:users][:id]).
|
97
97
|
assert generates_sql(%Q(SELECT [fields] FROM "users" WHERE "users"."id" = 2013 ORDER BY "users"."id"))
|
98
98
|
|
99
|
-
domain[:users].order_by(
|
99
|
+
domain[:users].order_by(:id).
|
100
100
|
assert generates_sql(%Q(SELECT [fields] FROM "users" ORDER BY "users"."id"))
|
101
101
|
~~~
|
102
102
|
|
data/qed/ordering.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
Results can be ordered.
|
2
|
+
|
3
|
+
~~~ruby
|
4
|
+
sql = domain[:posts].order_by(:title).to_sql
|
5
|
+
|
6
|
+
sql.assert == 'SELECT "posts"."id" AS _posts_id, "posts"."title" AS _posts_title, "posts"."text" AS _posts_text, "posts"."user_id" AS _posts_user_id, "posts"."approver_id" AS _posts_approver_id FROM "posts" ORDER BY "posts"."title"'
|
7
|
+
~~~
|
8
|
+
|
9
|
+
They can be ordered ASC.
|
10
|
+
|
11
|
+
~~~ruby
|
12
|
+
sql = domain[:posts].order_by(:title.asc).to_sql
|
13
|
+
|
14
|
+
sql.assert == 'SELECT "posts"."id" AS _posts_id, "posts"."title" AS _posts_title, "posts"."text" AS _posts_text, "posts"."user_id" AS _posts_user_id, "posts"."approver_id" AS _posts_approver_id FROM "posts" ORDER BY "posts"."title" ASC'
|
15
|
+
~~~
|
16
|
+
|
17
|
+
They can also be ordered DESC.
|
18
|
+
|
19
|
+
~~~ruby
|
20
|
+
sql = domain[:posts].order_by(:title.desc).to_sql
|
21
|
+
|
22
|
+
sql.assert == 'SELECT "posts"."id" AS _posts_id, "posts"."title" AS _posts_title, "posts"."text" AS _posts_text, "posts"."user_id" AS _posts_user_id, "posts"."approver_id" AS _posts_approver_id FROM "posts" ORDER BY "posts"."title" DESC'
|
23
|
+
~~~
|
24
|
+
|
25
|
+
Multiple fields can be used.
|
26
|
+
|
27
|
+
~~~ruby
|
28
|
+
sql = domain[:posts].order_by(:title, :text).to_sql
|
29
|
+
|
30
|
+
sql.assert == 'SELECT "posts"."id" AS _posts_id, "posts"."title" AS _posts_title, "posts"."text" AS _posts_text, "posts"."user_id" AS _posts_user_id, "posts"."approver_id" AS _posts_approver_id FROM "posts" ORDER BY "posts"."title", "posts"."text"'
|
31
|
+
~~~
|
32
|
+
|
33
|
+
Multiple fields can be used with ASC, DESC.
|
34
|
+
|
35
|
+
~~~ruby
|
36
|
+
sql = domain[:posts].order_by(:title.asc, :text.desc).to_sql
|
37
|
+
|
38
|
+
sql.assert == 'SELECT "posts"."id" AS _posts_id, "posts"."title" AS _posts_title, "posts"."text" AS _posts_text, "posts"."user_id" AS _posts_user_id, "posts"."approver_id" AS _posts_approver_id FROM "posts" ORDER BY "posts"."title" ASC, "posts"."text" DESC'
|
39
|
+
~~~
|
40
|
+
|
41
|
+
Ordering can be defined in many ways.
|
42
|
+
|
43
|
+
~~~ruby
|
44
|
+
user = users.first
|
45
|
+
|
46
|
+
inserted = posts.insert(:title => 'ABC', :text => 'Alphabet', :user_id => user.id).returning '*'
|
47
|
+
|
48
|
+
domain[:posts].order_by(:title).map(&:title).assert == ['ABC', 'First Light']
|
49
|
+
domain[:posts].order_by(:title.asc).map(&:title).assert == ['ABC', 'First Light']
|
50
|
+
domain[:posts].order_by(:title.desc).map(&:title).assert == ['First Light', 'ABC']
|
51
|
+
domain[:posts].order_by('title').map(&:title).assert == ['ABC', 'First Light']
|
52
|
+
domain[:posts].order_by('title ASC').map(&:title).assert == ['ABC', 'First Light']
|
53
|
+
domain[:posts].order_by('title DESC').map(&:title).assert == ['First Light', 'ABC']
|
54
|
+
domain[:posts].order_by(posts[:title]).map(&:title).assert == ['ABC', 'First Light']
|
55
|
+
domain[:posts].order_by(posts[:title].asc).map(&:title).assert == ['ABC', 'First Light']
|
56
|
+
domain[:posts].order_by(posts[:title].desc).map(&:title).assert == ['First Light', 'ABC']
|
57
|
+
~~~
|
data/qed/projection.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Without projection, result objects will be packaged in a subhash.
|
2
|
+
|
3
|
+
~~~ruby
|
4
|
+
user = posts.join(users).on(:user_id => :id).
|
5
|
+
first.user
|
6
|
+
|
7
|
+
user.id.assert != nil
|
8
|
+
user.name.assert == 'John Snow'
|
9
|
+
~~~
|
10
|
+
|
11
|
+
When projecting, all result data will be toplevel and only the projected data is loaded.
|
12
|
+
|
13
|
+
~~~ruby
|
14
|
+
result = posts.join(users).on(:user_id => :id).
|
15
|
+
project(users[:name]).first
|
16
|
+
|
17
|
+
result.id.assert == nil # Not loaded.
|
18
|
+
result.name.assert == 'John Snow'
|
19
|
+
~~~
|
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.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kaspar Schiess
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-08-
|
12
|
+
date: 2014-08-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: arel
|
@@ -113,6 +113,8 @@ files:
|
|
113
113
|
- qed/flounder.sql
|
114
114
|
- qed/index.md
|
115
115
|
- qed/inserts.md
|
116
|
+
- qed/ordering.md
|
117
|
+
- qed/projection.md
|
116
118
|
- qed/results.md
|
117
119
|
- qed/selects.md
|
118
120
|
- qed/updates.md
|
@@ -148,6 +150,8 @@ test_files:
|
|
148
150
|
- qed/flounder.sql
|
149
151
|
- qed/index.md
|
150
152
|
- qed/inserts.md
|
153
|
+
- qed/ordering.md
|
154
|
+
- qed/projection.md
|
151
155
|
- qed/results.md
|
152
156
|
- qed/selects.md
|
153
157
|
- qed/updates.md
|