flounder 0.14.0 → 0.15.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/HISTORY +3 -0
- data/flounder.gemspec +1 -1
- data/lib/flounder/domain.rb +5 -2
- data/lib/flounder/entity.rb +9 -0
- data/lib/flounder/expression.rb +61 -3
- data/lib/flounder/query/base.rb +8 -8
- data/qed/expressions.md +9 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f4ec6bd3fa4f14eccf7efa8d3aed4e81a3d8e08
|
4
|
+
data.tar.gz: cba009f5dc2b519b4636b643b7ac1d02bd9a493c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81a859be8701dc7aa497f17949ed8bb8db93cb22daaba9c24796d5d225ef4cfd936174f132648bde9755d67b4aa15c92db2c09e404fec28280e4db62d3fa302b
|
7
|
+
data.tar.gz: 85f24647fe87ddd7a788df1f0722811fd828d4e0c5c570c6ac295e40d9ef6d4e5fb3ead5526a20bf35566f2132638c7b355ba0e1291697e79c20f8c63a6d9c38
|
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.15.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"
|
data/lib/flounder/domain.rb
CHANGED
@@ -50,9 +50,12 @@ module Flounder
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# Builds an SQL expression.
|
53
|
+
#
|
54
|
+
# domain.expr { concat('1', '2') }
|
53
55
|
#
|
54
|
-
def expr
|
55
|
-
Expression::Builder.new(self
|
56
|
+
def expr &block
|
57
|
+
builder = Expression::Builder.new(self)
|
58
|
+
builder.call(&block)
|
56
59
|
end
|
57
60
|
|
58
61
|
# Returns an aggregate of all query wall clock times. Please see
|
data/lib/flounder/entity.rb
CHANGED
@@ -66,6 +66,15 @@ module Flounder
|
|
66
66
|
end
|
67
67
|
alias to_s inspect
|
68
68
|
|
69
|
+
# Builds a condition part or a general SQL expression.
|
70
|
+
#
|
71
|
+
# entity.cond(a: 1)
|
72
|
+
#
|
73
|
+
def cond *conditions
|
74
|
+
builder = Expression::Builder.new(domain)
|
75
|
+
builder.interpret_conditions(self, conditions)
|
76
|
+
end
|
77
|
+
|
69
78
|
# Starts a new select query and yields it to the block. Note that you don't
|
70
79
|
# need to call this method to obtain a select query - any of the methods
|
71
80
|
# on Query::Select should work on the entity and return a new query object.
|
data/lib/flounder/expression.rb
CHANGED
@@ -11,6 +11,12 @@ module Flounder::Expression
|
|
11
11
|
def cast type
|
12
12
|
Cast.new(@domain, type, self)
|
13
13
|
end
|
14
|
+
def | expr
|
15
|
+
BinaryOp.new(@domain, 'OR', self, expr)
|
16
|
+
end
|
17
|
+
def & expr
|
18
|
+
BinaryOp.new(@domain, 'AND', self, expr)
|
19
|
+
end
|
14
20
|
|
15
21
|
def eval argument
|
16
22
|
case argument
|
@@ -83,18 +89,70 @@ module Flounder::Expression
|
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
92
|
+
class ConditionBit < Expr
|
93
|
+
def initialize domain, engine, bit
|
94
|
+
super(domain)
|
95
|
+
@engine = engine
|
96
|
+
@bit = bit
|
97
|
+
end
|
98
|
+
|
99
|
+
attr_accessor :bit, :engine
|
100
|
+
|
101
|
+
def to_sql
|
102
|
+
bit.to_sql(engine)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class BinaryOp < Expr
|
107
|
+
def initialize domain, op_string, *terms
|
108
|
+
super(domain)
|
109
|
+
|
110
|
+
@op_string = op_string
|
111
|
+
@terms = terms
|
112
|
+
end
|
113
|
+
|
114
|
+
attr_accessor :op_string
|
115
|
+
|
116
|
+
def concat term
|
117
|
+
@terms << term
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_sql
|
121
|
+
"(" +
|
122
|
+
@terms.
|
123
|
+
map { |t| eval(t) }.
|
124
|
+
join(" #{op_string} ") +
|
125
|
+
")"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
86
129
|
class Builder
|
87
|
-
def initialize domain
|
130
|
+
def initialize domain
|
88
131
|
@domain = domain
|
89
|
-
@context = context
|
90
132
|
end
|
91
133
|
|
92
|
-
attr_accessor :domain
|
134
|
+
attr_accessor :domain
|
93
135
|
|
94
136
|
def call &block
|
95
137
|
instance_eval(&block)
|
96
138
|
end
|
97
139
|
|
140
|
+
# Conditions are interpreted relative to an entity.
|
141
|
+
def interpret_conditions entity, conditions
|
142
|
+
# The method we need is in there...
|
143
|
+
query = Flounder::Query::Select.new(domain, entity)
|
144
|
+
engine = Flounder::Engine.new(domain.connection_pool)
|
145
|
+
|
146
|
+
and_expr = BinaryOp.new(domain, 'AND')
|
147
|
+
|
148
|
+
# TODO parse_conditions and its call tree is not really something that
|
149
|
+
# belongs into the query object - we should create a new abstraction here.
|
150
|
+
query.parse_conditions(*conditions) { |bit|
|
151
|
+
and_expr.concat(ConditionBit.new(domain, engine, bit)) }
|
152
|
+
|
153
|
+
and_expr
|
154
|
+
end
|
155
|
+
|
98
156
|
def respond_to? sym, include_all=false
|
99
157
|
true
|
100
158
|
end
|
data/lib/flounder/query/base.rb
CHANGED
@@ -81,14 +81,6 @@ module Flounder::Query
|
|
81
81
|
domain.log_bm measure
|
82
82
|
end
|
83
83
|
|
84
|
-
private
|
85
|
-
# Prepares a kick - meaning an execution on the database or a transform
|
86
|
-
# to an sql string. Ready Set...
|
87
|
-
#
|
88
|
-
def prepare_kick
|
89
|
-
# should be overridden
|
90
|
-
end
|
91
|
-
|
92
84
|
# Parses a conditions array like it is found with #where and #having and
|
93
85
|
# calls the block for each condition bit. Returns self.
|
94
86
|
#
|
@@ -126,6 +118,14 @@ module Flounder::Query
|
|
126
118
|
end
|
127
119
|
return self
|
128
120
|
end
|
121
|
+
|
122
|
+
private
|
123
|
+
# Prepares a kick - meaning an execution on the database or a transform
|
124
|
+
# to an sql string. Ready Set...
|
125
|
+
#
|
126
|
+
def prepare_kick
|
127
|
+
# should be overridden
|
128
|
+
end
|
129
129
|
|
130
130
|
# Rewrites a statement that contains bind placeholders like '$1' to
|
131
131
|
# contain placeholders starting at offset+1. Also checks that no
|
data/qed/expressions.md
CHANGED
@@ -4,8 +4,14 @@
|
|
4
4
|
Flounder also helps with the writing of complex SQL expressions.
|
5
5
|
|
6
6
|
~~~ruby
|
7
|
-
|
8
|
-
|
9
|
-
|
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
10
|
~~~
|
11
11
|
|
12
|
+
You can also pass a condition-like hash to expr directly, it will return a Ruby object that allows for chaining.
|
13
|
+
|
14
|
+
~~~ruby
|
15
|
+
(users.cond(:posts, a: 1) | users.cond(a: 2)).
|
16
|
+
assert generates_sql("((\"posts\".\"a\" = 1) OR (\"users\".\"a\" = 2))")
|
17
|
+
~~~
|
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.15.0
|
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-10-
|
12
|
+
date: 2014-10-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: arel
|