flounder 0.15.1 → 0.16.0
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/HISTORY +2 -0
- data/README +7 -1
- data/flounder.gemspec +1 -1
- data/lib/flounder/entity.rb +43 -1
- data/lib/flounder/helpers/entity.rb +18 -0
- data/lib/flounder/query/base.rb +6 -14
- data/lib/flounder/query/select.rb +38 -0
- data/lib/flounder/relation.rb +30 -0
- data/qed/applique/setup_domain.rb +15 -3
- data/qed/expressions.md +1 -1
- data/qed/index.md +11 -0
- data/qed/joins.md +30 -0
- metadata +31 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1df582c917b24ed0beb74e4fdd6b15d0f7792ba
|
4
|
+
data.tar.gz: f5ef57ba73986e7ebb89e475289f177baf0c1602
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 964433279a3fcd0bb1035dc5062fb075560518ccf411462ad79af281264b1abc41f22b02019d753620cb39caf53583d2e3a56d67be3be39a5560c7f8056bdc1f
|
7
|
+
data.tar.gz: 08eded169bd82e3468af1e673fb199f14a0e59352707f068b76f7ed96d5d3af5ac5af7ccd673070bc3124eaf96e75c8713e0c48fcc42cbe02b6e4054beb4f982
|
data/Gemfile.lock
CHANGED
data/HISTORY
CHANGED
data/README
CHANGED
@@ -6,10 +6,16 @@ SYNOPSIS
|
|
6
6
|
|
7
7
|
require 'flounder'
|
8
8
|
d = Flounder.domain do |dom|
|
9
|
-
dom.entity(:users, 'users')
|
9
|
+
dom.entity(:users, :user, 'users') do |user|
|
10
|
+
user.has_many :giraffes, :id => :user_id
|
11
|
+
end
|
12
|
+
dom.entity(:giraffes, :giraffe, 'all_giraffes') do |giraffe|
|
13
|
+
giraffe.belongs_to :user, :user_id => :id
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
17
|
d[:users].where(:id.lt => 10).to_a
|
18
|
+
d[:users].connect(:giraffes)
|
13
19
|
|
14
20
|
STATUS
|
15
21
|
|
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.16.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/entity.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
|
+
require 'flounder/relation'
|
4
|
+
|
3
5
|
module Flounder
|
4
6
|
|
5
7
|
# An entity corresponds to a table in the database. On top of its table
|
@@ -28,6 +30,7 @@ module Flounder
|
|
28
30
|
@singular = singular
|
29
31
|
@table_name = table_name
|
30
32
|
@columns_hash = nil
|
33
|
+
@relations = {} # name -> relation
|
31
34
|
|
32
35
|
@table = Arel::Table.new(table_name)
|
33
36
|
end
|
@@ -49,6 +52,9 @@ module Flounder
|
|
49
52
|
# @return [String] Name of the table that underlies this entity.
|
50
53
|
attr_reader :table_name
|
51
54
|
|
55
|
+
# @return [Array] relations that this entity has to other entities
|
56
|
+
attr_accessor :relations
|
57
|
+
|
52
58
|
extend Forwardable
|
53
59
|
def_delegators :domain, :transaction, :with_connection
|
54
60
|
|
@@ -66,6 +72,42 @@ module Flounder
|
|
66
72
|
end
|
67
73
|
alias to_s inspect
|
68
74
|
|
75
|
+
# Relations to other entities
|
76
|
+
|
77
|
+
# Adds a relationship where many records on the other entity correspond to
|
78
|
+
# this one.
|
79
|
+
#
|
80
|
+
def has_many *a
|
81
|
+
add_relationship :has_many, *a
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adds a relationship where one record on the other entity corresponds to
|
85
|
+
# possibly many on our side.
|
86
|
+
#
|
87
|
+
# Example:
|
88
|
+
# domain.entity :foos, :foo, 'foo' do |foo|
|
89
|
+
# foo.belongs_to :bar, :bar_id => :id
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# You can also explicitly name the relationship instead of going through
|
93
|
+
# the singular name of the other entity:
|
94
|
+
#
|
95
|
+
# Example:
|
96
|
+
# domain.entity :foos, :foo, 'foo' do |foo|
|
97
|
+
# foo.belongs_to :bar_stuff, :bar, :bar_id => :id
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
def belongs_to *a
|
101
|
+
add_relationship :belongs_to, *a
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_relationship type, name, entity_ref=nil, **join_conditions
|
105
|
+
raise ArgumentError, "Must have join conditions." if join_conditions.empty?
|
106
|
+
|
107
|
+
relations[name] = Relation.new(
|
108
|
+
domain, type, name, entity_ref||name, join_conditions)
|
109
|
+
end
|
110
|
+
|
69
111
|
# Builds a condition part or a general SQL expression.
|
70
112
|
#
|
71
113
|
# entity.cond(a: 1)
|
@@ -123,7 +165,7 @@ module Flounder
|
|
123
165
|
# Query initiators
|
124
166
|
[:where, :join, :outer_join, :project,
|
125
167
|
:order_by, :group_by,
|
126
|
-
:limit, :offset].each do |name|
|
168
|
+
:limit, :offset, :connect].each do |name|
|
127
169
|
define_method name do |*args|
|
128
170
|
select { |q| q.send(name, *args) }
|
129
171
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Flounder::Helpers
|
2
|
+
module Entity
|
3
|
+
def entity_like? something
|
4
|
+
something.kind_of?(Flounder::Entity) ||
|
5
|
+
something.kind_of?(Symbol) && domain.has_entity?(something)
|
6
|
+
end
|
7
|
+
def convert_to_entity something
|
8
|
+
case something
|
9
|
+
when Flounder::Entity, Flounder::EntityAlias
|
10
|
+
return something
|
11
|
+
when Symbol
|
12
|
+
return domain[something]
|
13
|
+
else
|
14
|
+
fail "Not entity-like - yet! (#{something.inspect})"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/flounder/query/base.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
|
2
2
|
require 'pg_hstore'
|
3
3
|
require 'benchmark'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
require 'flounder/helpers/entity'
|
4
7
|
|
5
8
|
module Flounder::Query
|
6
9
|
class Base
|
@@ -211,6 +214,8 @@ module Flounder::Query
|
|
211
214
|
# covers: :field => (1..100)
|
212
215
|
when Range
|
213
216
|
arel_field.in(value)
|
217
|
+
when Set
|
218
|
+
arel_field.in(value.to_a)
|
214
219
|
else
|
215
220
|
arel_field.send(kind, value)
|
216
221
|
end
|
@@ -241,19 +246,6 @@ module Flounder::Query
|
|
241
246
|
end
|
242
247
|
end
|
243
248
|
|
244
|
-
|
245
|
-
something.kind_of?(Flounder::Entity) ||
|
246
|
-
something.kind_of?(Symbol) && domain.has_entity?(something)
|
247
|
-
end
|
248
|
-
def convert_to_entity something
|
249
|
-
case something
|
250
|
-
when Flounder::Entity, Flounder::EntityAlias
|
251
|
-
return something
|
252
|
-
when Symbol
|
253
|
-
return domain[something]
|
254
|
-
else
|
255
|
-
fail "Not entity-like - yet! (#{something.inspect})"
|
256
|
-
end
|
257
|
-
end
|
249
|
+
include Flounder::Helpers::Entity
|
258
250
|
end
|
259
251
|
end
|
@@ -153,8 +153,46 @@ module Flounder::Query
|
|
153
153
|
all.first.count
|
154
154
|
end
|
155
155
|
|
156
|
+
# Follows relationships on the currently anchored entity. This is like
|
157
|
+
# an explicit join, but allows to eliminate repetition.
|
158
|
+
#
|
159
|
+
def connect *connect_spec
|
160
|
+
connect_spec.each do |spec_part|
|
161
|
+
follow_relation_spec(join_entity, spec_part)
|
162
|
+
end
|
163
|
+
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
156
167
|
private
|
157
168
|
|
169
|
+
# Follows a given relationship spec. Does NOT change anchoring.
|
170
|
+
#
|
171
|
+
def follow_relation_spec entity, spec
|
172
|
+
old_join_entity = join_entity
|
173
|
+
|
174
|
+
case spec
|
175
|
+
when Symbol
|
176
|
+
relation = entity.relations[spec]
|
177
|
+
relation.apply(self)
|
178
|
+
when Hash
|
179
|
+
spec.each do |k, v|
|
180
|
+
follow_relation_spec(join_entity, k)
|
181
|
+
self.anchor
|
182
|
+
|
183
|
+
follow_relation_spec(join_entity, v)
|
184
|
+
end
|
185
|
+
when Array
|
186
|
+
spec.each do |v|
|
187
|
+
follow_relation_spec(join_entity, v)
|
188
|
+
end
|
189
|
+
else
|
190
|
+
raise ArgumentError, "#{spec.inspect} not allowed in #connect."
|
191
|
+
end
|
192
|
+
|
193
|
+
@join_entity = old_join_entity
|
194
|
+
end
|
195
|
+
|
158
196
|
def column_name_to_entity name
|
159
197
|
unless default_projection.empty?
|
160
198
|
extract_source_info_from_name(name)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'flounder/helpers/entity'
|
2
|
+
|
3
|
+
module Flounder
|
4
|
+
class Relation
|
5
|
+
attr_accessor :domain, :type
|
6
|
+
attr_accessor :name, :entity_ref, :join_conditions
|
7
|
+
|
8
|
+
def initialize domain, type, name, entity_ref, join_conditions
|
9
|
+
@domain, @type, @name, @entity_ref, @join_conditions =
|
10
|
+
domain, type, name, entity_ref, join_conditions
|
11
|
+
end
|
12
|
+
|
13
|
+
def apply query
|
14
|
+
entity = convert_to_entity(entity_ref)
|
15
|
+
|
16
|
+
if name != entity_ref
|
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)
|
20
|
+
end
|
21
|
+
|
22
|
+
query.
|
23
|
+
join(entity).
|
24
|
+
on(join_conditions)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
include Flounder::Helpers::Entity
|
29
|
+
end
|
30
|
+
end
|
@@ -4,9 +4,21 @@ def domain
|
|
4
4
|
@domain ||= begin
|
5
5
|
connection = Flounder.connect(dbname: 'flounder')
|
6
6
|
Flounder.domain(connection) do |dom|
|
7
|
-
dom.entity(:users, :user, 'users')
|
8
|
-
|
9
|
-
|
7
|
+
dom.entity(:users, :user, 'users') do |user|
|
8
|
+
user.has_many :posts, :id => :author_id
|
9
|
+
user.has_many :approved_posts, :posts, :id => :author_id
|
10
|
+
user.has_many :comments, :id => :author_id
|
11
|
+
end
|
12
|
+
dom.entity(:posts, :post, 'posts') do |post|
|
13
|
+
post.belongs_to :user, :author_id => :id
|
14
|
+
post.belongs_to :approver, :users, :author_id => :id
|
15
|
+
|
16
|
+
post.has_many :comments, :id => :post_id
|
17
|
+
end
|
18
|
+
dom.entity(:comments, :comment, 'comments') do |comment|
|
19
|
+
comment.belongs_to :post, :post_id => :id
|
20
|
+
comment.belongs_to :author, :author_id => :id
|
21
|
+
end
|
10
22
|
end
|
11
23
|
end
|
12
24
|
end
|
data/qed/expressions.md
CHANGED
data/qed/index.md
CHANGED
@@ -72,5 +72,16 @@ By default, symbols are interpreted as field names in the entity that you start
|
|
72
72
|
assert generates_sql("SELECT [fields] FROM \"users\" WHERE \"posts\".\"id\" = 1")
|
73
73
|
~~~
|
74
74
|
|
75
|
+
Sets are queried for using the `IN` operator.
|
76
|
+
|
77
|
+
~~~ruby
|
78
|
+
require 'set'
|
79
|
+
s = Set.new([1,2,3])
|
80
|
+
users.where(:posts, :id.in => s).
|
81
|
+
assert generates_sql("SELECT [fields] FROM \"users\" WHERE \"posts\".\"id\" IN (1, 2, 3)")
|
82
|
+
users.where(:posts, :id => s).
|
83
|
+
assert generates_sql("SELECT [fields] FROM \"users\" WHERE \"posts\".\"id\" IN (1, 2, 3)")
|
84
|
+
~~~
|
85
|
+
|
75
86
|
TODO links to other documentation
|
76
87
|
|
data/qed/joins.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
|
2
|
+
# Basic JOINs
|
2
3
|
Joins are correctly created.
|
3
4
|
|
4
5
|
~~~ruby
|
@@ -83,3 +84,32 @@ Results should also be correct:
|
|
83
84
|
row = query.first
|
84
85
|
row.other_comment.assert == row.comment
|
85
86
|
~~~
|
87
|
+
|
88
|
+
|
89
|
+
# Joining using `#connect`
|
90
|
+
|
91
|
+
You can also store joins in the entity definition (see `#belongs_to` and `#has_many` on the Entity) and then navigate through your models using those names.
|
92
|
+
|
93
|
+
A simple example for a connect:
|
94
|
+
|
95
|
+
~~~ruby
|
96
|
+
# Query for users, joining posts and joining comments from posts (anchor)
|
97
|
+
query = users.connect(:posts).where(id: 1)
|
98
|
+
|
99
|
+
users.
|
100
|
+
join(:posts).on(:id => :author_id).
|
101
|
+
where(id: 1).to_sql.assert == query.to_sql
|
102
|
+
~~~
|
103
|
+
|
104
|
+
Or a more complicated example, using hashes and arrays in the join specification.
|
105
|
+
|
106
|
+
~~~ruby
|
107
|
+
# Query for users, joining posts and joining comments from posts (anchor)
|
108
|
+
query = users.connect(:posts => [:comments, :approver])
|
109
|
+
|
110
|
+
users.
|
111
|
+
join(:posts).on(:id => :author_id).anchor.
|
112
|
+
join(:comments).on(:id => :post_id).
|
113
|
+
join(users.as(:approver, :approver)).on(:author_id => :id).to_sql.assert == query.to_sql
|
114
|
+
~~~
|
115
|
+
|
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.16.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-10-
|
12
|
+
date: 2014-10-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,11 +127,14 @@ executables: []
|
|
127
127
|
extensions: []
|
128
128
|
extra_rdoc_files: []
|
129
129
|
files:
|
130
|
-
- flounder.gemspec
|
131
130
|
- Gemfile
|
132
131
|
- Gemfile.lock
|
133
132
|
- HACKING
|
134
133
|
- HISTORY
|
134
|
+
- LICENSE
|
135
|
+
- README
|
136
|
+
- flounder.gemspec
|
137
|
+
- lib/flounder.rb
|
135
138
|
- lib/flounder/connection.rb
|
136
139
|
- lib/flounder/connection_pool.rb
|
137
140
|
- lib/flounder/domain.rb
|
@@ -141,6 +144,7 @@ files:
|
|
141
144
|
- lib/flounder/exceptions.rb
|
142
145
|
- lib/flounder/expression.rb
|
143
146
|
- lib/flounder/field.rb
|
147
|
+
- lib/flounder/helpers/entity.rb
|
144
148
|
- lib/flounder/immediate.rb
|
145
149
|
- lib/flounder/postgres_utils.rb
|
146
150
|
- lib/flounder/query/base.rb
|
@@ -149,9 +153,8 @@ files:
|
|
149
153
|
- lib/flounder/query/returning.rb
|
150
154
|
- lib/flounder/query/select.rb
|
151
155
|
- lib/flounder/query/update.rb
|
156
|
+
- lib/flounder/relation.rb
|
152
157
|
- lib/flounder/symbol_extensions.rb
|
153
|
-
- lib/flounder.rb
|
154
|
-
- LICENSE
|
155
158
|
- qed/applique/ae.rb
|
156
159
|
- qed/applique/flounder.rb
|
157
160
|
- qed/applique/setup_domain.rb
|
@@ -170,7 +173,6 @@ files:
|
|
170
173
|
- qed/projection.md
|
171
174
|
- qed/selects.md
|
172
175
|
- qed/updates.md
|
173
|
-
- README
|
174
176
|
homepage: https://bitbucket.org/technologyastronauts/oss_flounder
|
175
177
|
licenses:
|
176
178
|
- MIT
|
@@ -181,17 +183,17 @@ require_paths:
|
|
181
183
|
- lib
|
182
184
|
required_ruby_version: !ruby/object:Gem::Requirement
|
183
185
|
requirements:
|
184
|
-
- -
|
186
|
+
- - ">="
|
185
187
|
- !ruby/object:Gem::Version
|
186
188
|
version: '0'
|
187
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
190
|
requirements:
|
189
|
-
- -
|
191
|
+
- - ">="
|
190
192
|
- !ruby/object:Gem::Version
|
191
193
|
version: '0'
|
192
194
|
requirements: []
|
193
195
|
rubyforge_project:
|
194
|
-
rubygems_version: 2.
|
196
|
+
rubygems_version: 2.2.2
|
195
197
|
signing_key:
|
196
198
|
specification_version: 4
|
197
199
|
summary: Flounder is a way to write SQL simply in Ruby. It deals with everything BUT
|