flounder 0.12.1 → 0.13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e69174de167de70dbf0357305fa02c71164c8bea
4
- data.tar.gz: 278919200dee79e529c0ed56aa4dce90db7aed69
3
+ metadata.gz: 04d1106f4e95ce3826634ec72900b5ccd131a216
4
+ data.tar.gz: 2fab08b9cfbe86039810223e9756eb121a7d7e92
5
5
  SHA512:
6
- metadata.gz: f64f07a05f24cc5bc2f2460285f495300ea2e4e6a0474d4b7e3d896ccca6e1852b252b3c4f710fa2ff7f9a1d1ce71b06bb72c68dde6b6e2b2bcad6b158375d57
7
- data.tar.gz: 5076c7c51a2e30eb9a19c69f9139ab56c4db7b0cfcfa27acdccd8b3ddc591947a69bdf7adc90efed1ef7b72cebf66bfce6e5432193cd4297b323c5c20356b850
6
+ metadata.gz: b172e8b4b323d12ae34950b98fb596c8b624b53aa0e4f9c9799f2b4d6a2aceca1e277f04c064e21e33aecc944e57d0239b7a2dff8b3d1ebab15a331666675c46
7
+ data.tar.gz: 03f98c7833cee422c3fe81a2d4dc2b6fa3f59033b99a7cff3387342a24258ce90ee4f85e3574de030f2fb6775f37bc596e1c593abd428eea8532483b9282ea56
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flounder (0.12.0)
4
+ flounder (0.12.1)
5
5
  aggregate (~> 0.2, >= 0.2.2)
6
6
  arel (~> 5, > 5.0.1)
7
7
  connection_pool (~> 2)
data/HISTORY CHANGED
@@ -1,3 +1,7 @@
1
+
2
+ # 0.13
3
+ + Expression generator (Domain#expr).
4
+
1
5
  # 0.12
2
6
  + domain#stats keeps a histogram of execution times.
3
7
  + entity#fields without argument returns all fields.
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.12.1'
5
+ s.version = '0.13.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"
@@ -49,6 +49,12 @@ module Flounder
49
49
  end
50
50
  end
51
51
 
52
+ # Builds an SQL expression.
53
+ #
54
+ def expr context=self, &block
55
+ Expression::Builder.new(self, context).call(&block)
56
+ end
57
+
52
58
  # Returns an aggregate of all query wall clock times. Please see
53
59
  # https://github.com/josephruscio/aggregate for more information on this
54
60
  # object.
@@ -0,0 +1,107 @@
1
+
2
+ module Flounder::Expression
3
+ class Expr
4
+ def initialize domain
5
+ @domain = domain
6
+ end
7
+
8
+ def as name
9
+ Named.new(@domain, name, self)
10
+ end
11
+ def cast type
12
+ Cast.new(@domain, type, self)
13
+ end
14
+
15
+ def eval argument
16
+ case argument
17
+ when String, Symbol
18
+ db_quote(argument.to_s)
19
+ when Fixnum
20
+ argument
21
+ when Expr
22
+ argument.to_sql
23
+ when Flounder::Field
24
+ argument.fully_qualified_name
25
+ else
26
+ db_quote(argument)
27
+ end
28
+ end
29
+
30
+ def db_quote something
31
+ @domain.with_connection do |conn|
32
+ conn.quote(something)
33
+ end
34
+ end
35
+
36
+ def to_sql
37
+ raise NotImplementedError
38
+ end
39
+ def to_immediate
40
+ Flounder::Immediate.new(to_sql)
41
+ end
42
+
43
+ include Flounder::SymbolExtensions
44
+ end
45
+
46
+ class Cast < Expr
47
+ def initialize domain, type, expr
48
+ super(domain)
49
+
50
+ @type = type
51
+ @expr = expr
52
+ end
53
+
54
+ def to_sql
55
+ @expr.to_sql << '::' << @type.to_s
56
+ end
57
+ end
58
+
59
+ class Named < Expr
60
+ def initialize domain, name, expr
61
+ super(domain)
62
+
63
+ @name = name
64
+ @expr = expr
65
+ end
66
+
67
+ def to_sql
68
+ @expr.to_sql << ' AS ' << @name.to_s
69
+ end
70
+ end
71
+
72
+ class FunCall < Expr
73
+ def initialize domain, name, arguments
74
+ super(domain)
75
+
76
+ @name = name
77
+ @arguments = arguments
78
+ end
79
+
80
+ def to_sql
81
+ @name.to_s << '(' <<
82
+ @arguments.map { |arg| eval(arg) }.join(', ') << ')'
83
+ end
84
+ end
85
+
86
+ class Builder
87
+ def initialize domain, context
88
+ @domain = domain
89
+ @context = context
90
+ end
91
+
92
+ attr_accessor :domain, :context
93
+
94
+ def call &block
95
+ instance_eval(&block)
96
+ end
97
+
98
+ def respond_to? sym, include_all=false
99
+ true
100
+ end
101
+ def method_missing sym, *args, &block
102
+ raise ArgumentError, "No blocks in sql execution context." if block
103
+
104
+ FunCall.new(domain, sym, args)
105
+ end
106
+ end
107
+ end
@@ -1,5 +1,5 @@
1
1
 
2
- module Flounder::Query
2
+ module Flounder
3
3
  # An immmediate string that needs to be passed around and _not_ quoted or
4
4
  # escaped when going to the database.
5
5
  #
@@ -12,7 +12,7 @@ module Flounder::Query
12
12
  attr_reader :string
13
13
 
14
14
  def to_arel_field
15
- string
15
+ Arel::SqlLiteral.new(string)
16
16
  end
17
17
  end
18
18
  end
@@ -189,9 +189,11 @@ module Flounder::Query
189
189
  when Symbol
190
190
  entity[field_ref]
191
191
  when String
192
- Immediate.new(field_ref)
192
+ Flounder::Immediate.new(field_ref)
193
193
  when Flounder::Field
194
194
  field_ref
195
+ when Flounder::Expression::Expr
196
+ field_ref.to_immediate
195
197
  else
196
198
  fail Flounder::InvalidFieldReference,
197
199
  "Cannot resolve #{field_ref.inspect} to a field."
@@ -243,7 +245,7 @@ module Flounder::Query
243
245
 
244
246
  case field
245
247
  when String
246
- Immediate.new(field).to_arel_field
248
+ Flounder::Immediate.new(field).to_arel_field
247
249
  when Flounder::Field
248
250
  field.fully_qualified_name
249
251
  when Flounder::SymbolExtensions::Modifier
@@ -7,6 +7,8 @@ module Flounder
7
7
  entity[sym].arel_field
8
8
  when Flounder::Field
9
9
  sym.arel_field
10
+ when Flounder::Expression::Expr
11
+ sym.to_immediate.to_arel_field
10
12
  else
11
13
  fail "ASSERTION FAILURE: Unknown type in field.sym: #{field.sym.inspect}."
12
14
  end
data/lib/flounder.rb CHANGED
@@ -12,8 +12,7 @@ require 'flounder/engine'
12
12
  require 'flounder/entity'
13
13
  require 'flounder/entity_alias'
14
14
  require 'flounder/field'
15
-
16
- require 'flounder/query/immediate'
15
+ require 'flounder/immediate'
17
16
 
18
17
  require 'flounder/query/select'
19
18
  require 'flounder/query/insert'
@@ -22,6 +21,8 @@ require 'flounder/query/delete'
22
21
 
23
22
  require 'flounder/exceptions'
24
23
 
24
+ require 'flounder/expression'
25
+
25
26
  module Flounder
26
27
  module_function
27
28
  def connect opts={}
@@ -0,0 +1,11 @@
1
+
2
+ # Flounder.expr
3
+
4
+ Flounder also helps with the writing of complex SQL expressions.
5
+
6
+ ~~~ruby
7
+ users = domain[:users]
8
+ domain.expr { a(b(c(1, ' ', users[:id]))) }.cast('int').as(:foo).
9
+ assert generates_sql("a(b(c(1, ' ', \"users\".\"id\")))::int AS foo")
10
+ ~~~
11
+
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.12.1
4
+ version: 0.13.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-09-19 00:00:00.000000000 Z
12
+ date: 2014-09-26 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
@@ -142,16 +139,19 @@ files:
142
139
  - lib/flounder/entity.rb
143
140
  - lib/flounder/entity_alias.rb
144
141
  - lib/flounder/exceptions.rb
142
+ - lib/flounder/expression.rb
145
143
  - lib/flounder/field.rb
144
+ - lib/flounder/immediate.rb
146
145
  - lib/flounder/postgres_utils.rb
147
146
  - lib/flounder/query/base.rb
148
147
  - lib/flounder/query/delete.rb
149
- - lib/flounder/query/immediate.rb
150
148
  - lib/flounder/query/insert.rb
151
149
  - lib/flounder/query/returning.rb
152
150
  - lib/flounder/query/select.rb
153
151
  - lib/flounder/query/update.rb
154
152
  - lib/flounder/symbol_extensions.rb
153
+ - lib/flounder.rb
154
+ - LICENSE
155
155
  - qed/applique/ae.rb
156
156
  - qed/applique/flounder.rb
157
157
  - qed/applique/setup_domain.rb
@@ -161,6 +161,7 @@ files:
161
161
  - qed/delete.md
162
162
  - qed/entities.md
163
163
  - qed/exceptions.md
164
+ - qed/expressions.md
164
165
  - qed/flounder.sql
165
166
  - qed/index.md
166
167
  - qed/inserts.md
@@ -169,6 +170,7 @@ files:
169
170
  - qed/projection.md
170
171
  - qed/selects.md
171
172
  - qed/updates.md
173
+ - README
172
174
  homepage: https://bitbucket.org/technologyastronauts/oss_flounder
173
175
  licenses:
174
176
  - MIT
@@ -179,17 +181,17 @@ require_paths:
179
181
  - lib
180
182
  required_ruby_version: !ruby/object:Gem::Requirement
181
183
  requirements:
182
- - - ">="
184
+ - - '>='
183
185
  - !ruby/object:Gem::Version
184
186
  version: '0'
185
187
  required_rubygems_version: !ruby/object:Gem::Requirement
186
188
  requirements:
187
- - - ">="
189
+ - - '>='
188
190
  - !ruby/object:Gem::Version
189
191
  version: '0'
190
192
  requirements: []
191
193
  rubyforge_project:
192
- rubygems_version: 2.2.2
194
+ rubygems_version: 2.0.14
193
195
  signing_key:
194
196
  specification_version: 4
195
197
  summary: Flounder is a way to write SQL simply in Ruby. It deals with everything BUT
@@ -204,6 +206,7 @@ test_files:
204
206
  - qed/delete.md
205
207
  - qed/entities.md
206
208
  - qed/exceptions.md
209
+ - qed/expressions.md
207
210
  - qed/flounder.sql
208
211
  - qed/index.md
209
212
  - qed/inserts.md
@@ -212,4 +215,3 @@ test_files:
212
215
  - qed/projection.md
213
216
  - qed/selects.md
214
217
  - qed/updates.md
215
- has_rdoc: