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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9860bdc14eff074ea0e340f278593cc4e489599b
4
- data.tar.gz: 830bccfe9f8204a93e9eacb9c72b3b53191f82fb
3
+ metadata.gz: 9fa808fa17085d2e8f7c70a808ec4aa6c3b3ffe7
4
+ data.tar.gz: 47ab3d8800befc2e6864cb077cf715fbe1c20621
5
5
  SHA512:
6
- metadata.gz: 2c93426c7de1ac2a10368dcf8f85cdd269a20d00f71229706bbd2a42ff928d2415bf157217d52167c7d2e308a6dd59cb50ad505cacf04f4425eb7210e5380d94
7
- data.tar.gz: 4799ae63203ad83d6059c87efcb5c86619a054628591594e5c5cae93a10d3d1156136481b4387b4ddffb6defb0715d66d9ef31c3d01146435ecd6829973e16d0
6
+ metadata.gz: 2c7fdedda33c494affe87c3392049e901caa969c1a1cea7592ca3b0aad20fe1da296bb8157bcf6915a1ab626b994ced623fe952ecacab955271f25bb3385ebce
7
+ data.tar.gz: e2e96f3d0a887444b56212e3cef71434bbb9929b257be45c75b09089113708565890356b54a071cc7244cf68b3af5f190127aab6281c078800650ae5a70f42cc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flounder (0.2.0)
4
+ flounder (0.4.0)
5
5
  arel (~> 5, > 5.0.1)
6
6
  connection_pool (~> 2)
7
7
  hashie (~> 3, >= 3.2)
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.0'
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"
@@ -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
- entity, name = yield name if block_given?
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
 
@@ -39,7 +39,7 @@ module Flounder
39
39
 
40
40
  def where conditions={}
41
41
  conditions.each do |k, v|
42
- manager.where(transform_hash_condition(k, v))
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
- transform_hash_condition(k, join_field(v)))
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 = from_entity[field] unless field.kind_of?(Field)
113
- manager.order field.fully_qualified_name
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 condition clause, this returns a
230
- # condition that can be passed to Arel #where.
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 transform_hash_condition field, value
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
- condition_part(from_entity[field].arel_field, value)
262
+ join_and_condition_part(from_entity[field].arel_field, value)
240
263
  when Flounder::Field
241
- condition_part(field.arel_field, value)
264
+ join_and_condition_part(field.arel_field, value)
242
265
  when Flounder::SymbolExtensions::Modifier
243
- condition_part(
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 condition_part arel_field, value, kind=:eq
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 from_entity
4
+ def to_arel_field entity
5
5
  af = case sym
6
6
  when Symbol
7
- from_entity[sym].arel_field
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('id').
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.0
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-01 00:00:00.000000000 Z
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