groovy 0.1.1 → 0.1.2
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/example/Gemfile.lock +1 -1
- data/example/basic.rb +8 -6
- data/example/config.ru +2 -2
- data/example/relations.rb +4 -4
- data/groovy.gemspec +1 -1
- data/lib/groovy.rb +0 -1
- data/lib/groovy/model.rb +37 -12
- data/lib/groovy/query.rb +31 -4
- data/lib/groovy/schema.rb +22 -4
- data/lib/groovy/version.rb +3 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21ec75f430aa5b3ea423b52de62b4d578b4eb0b1e6722e9201c012cd444c616b
|
4
|
+
data.tar.gz: ec46772137b69e14dfe364d383fa9042ec8edd798bd22ed5c2dd4a47f895f1a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 044e5ba04d8097a354be1a6feb07c2ddd06c6e28355a07b41586936a4e572e028f1aefd35bb587dff46f2d1bbad513332d915e7aec01c00df26b09f6a3ffb357
|
7
|
+
data.tar.gz: 30ae3849bb6d769beb08db3ea8c676a0270a1037eb854c5ba7f4df2c3467906ad06055c7409ef8f2cf5284712f668c7153055b77470d0fa902e2d808591eedc4
|
data/example/Gemfile.lock
CHANGED
data/example/basic.rb
CHANGED
@@ -7,18 +7,20 @@ class Product
|
|
7
7
|
include Groovy::Model
|
8
8
|
|
9
9
|
schema do |t|
|
10
|
-
t.
|
11
|
-
t.
|
10
|
+
t.string :name
|
11
|
+
t.integer :price
|
12
12
|
t.timestamps
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def populate
|
17
|
+
5_000.times do |i|
|
18
|
+
puts "Creating product #{i}" if i % 1000 == 0
|
19
|
+
Product.create!(name: "A product with index #{i}", price: 10000 + i)
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
|
-
|
23
|
+
populate if Product.count == 0
|
22
24
|
|
23
25
|
# 50_000 products: 50M
|
24
26
|
# 100_000 products: 50M
|
data/example/config.ru
CHANGED
data/example/relations.rb
CHANGED
@@ -20,7 +20,7 @@ class Category
|
|
20
20
|
include Groovy::Model
|
21
21
|
|
22
22
|
schema do |t|
|
23
|
-
t.
|
23
|
+
t.string :name
|
24
24
|
t.timestamps
|
25
25
|
end
|
26
26
|
end
|
@@ -30,8 +30,8 @@ class Place
|
|
30
30
|
|
31
31
|
schema do |t|
|
32
32
|
t.reference :categories, "Categories", type: :vector
|
33
|
-
t.
|
34
|
-
t.
|
33
|
+
t.string :name
|
34
|
+
t.string :description, index: true
|
35
35
|
t.timestamps
|
36
36
|
end
|
37
37
|
end
|
@@ -41,7 +41,7 @@ class Location
|
|
41
41
|
|
42
42
|
schema do |t|
|
43
43
|
t.reference :place, "Places"
|
44
|
-
t.
|
44
|
+
t.string :coords
|
45
45
|
t.timestamps
|
46
46
|
end
|
47
47
|
end
|
data/groovy.gemspec
CHANGED
data/lib/groovy.rb
CHANGED
data/lib/groovy/model.rb
CHANGED
@@ -107,12 +107,24 @@ module Groovy
|
|
107
107
|
Query.new(self, table)
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
def first(count = 1)
|
111
|
+
arr = limit(count)
|
112
|
+
count == 1 && arr.first || arr
|
113
|
+
end
|
114
|
+
|
115
|
+
def last(count = 1)
|
116
|
+
arr = limit(count).to_a.reverse
|
117
|
+
count == 1 && arr.first || arr
|
118
|
+
end
|
111
119
|
|
112
120
|
def find_by(params)
|
113
121
|
where(params).limit(1).first
|
114
122
|
end
|
115
123
|
|
124
|
+
def in_batches(of: 1000, from: nil, &block)
|
125
|
+
all.in_batches(of: of, from: from, &block)
|
126
|
+
end
|
127
|
+
|
116
128
|
[:search, :where, :not, :sort_by, :limit, :offset].each do |scope_method|
|
117
129
|
define_method scope_method do |*args|
|
118
130
|
Query.new(self, table).tap do |q|
|
@@ -129,12 +141,7 @@ module Groovy
|
|
129
141
|
|
130
142
|
def_instance_delegators :table, :count, :size
|
131
143
|
|
132
|
-
|
133
|
-
|
134
|
-
def db_context
|
135
|
-
Groovy.contexts[context_name] or raise "Context not defined: #{context_name}"
|
136
|
-
end
|
137
|
-
|
144
|
+
# called from instance too, so must by public
|
138
145
|
def insert(key, attributes = nil)
|
139
146
|
if table.support_key?
|
140
147
|
table.add(key, attributes)
|
@@ -149,6 +156,12 @@ module Groovy
|
|
149
156
|
obj[key_name] = Time.now if attribute_names.include?(key_name.to_sym)
|
150
157
|
end
|
151
158
|
|
159
|
+
private
|
160
|
+
|
161
|
+
def db_context
|
162
|
+
Groovy.contexts[context_name] or raise "Context not defined: #{context_name}"
|
163
|
+
end
|
164
|
+
|
152
165
|
def add_attr_accessors(col)
|
153
166
|
define_method(col) { self[col] }
|
154
167
|
define_method("#{col}=") { |val| self[col] = val }
|
@@ -176,20 +189,27 @@ module Groovy
|
|
176
189
|
end
|
177
190
|
end
|
178
191
|
|
179
|
-
attr_reader :attributes, :refs, :record, :changes
|
192
|
+
attr_reader :id, :attributes, :refs, :record, :changes
|
180
193
|
|
181
194
|
def initialize(attributes = nil, record = nil)
|
182
|
-
@attributes =
|
183
|
-
@refs, @vectors = {}, {}
|
195
|
+
@attributes, @refs, @vectors = {}, {}, {}
|
184
196
|
|
185
197
|
if @record = record
|
198
|
+
@id = attributes.delete('_id')
|
186
199
|
# TODO: lazy load this
|
187
|
-
self.class.schema.singular_references.each
|
200
|
+
# self.class.schema.singular_references.each do |col|
|
201
|
+
# set_ref(col, record.public_send(col))
|
202
|
+
# end
|
188
203
|
end
|
189
204
|
|
205
|
+
set_attributes(attributes)
|
190
206
|
@changes = {}
|
191
207
|
end
|
192
208
|
|
209
|
+
def new_record?
|
210
|
+
id.nil?
|
211
|
+
end
|
212
|
+
|
193
213
|
def key
|
194
214
|
return unless record
|
195
215
|
record.respond_to?(:_key) ? record._key : record.id
|
@@ -218,8 +238,13 @@ module Groovy
|
|
218
238
|
changes.any?
|
219
239
|
end
|
220
240
|
|
241
|
+
def set_attributes(obj = {})
|
242
|
+
# we call the method instead of []= to allow overriding setters
|
243
|
+
obj.each { |k,v| public_send("#{k}=", v) }
|
244
|
+
end
|
245
|
+
|
221
246
|
def update_attributes(obj)
|
222
|
-
obj
|
247
|
+
set_attributes(obj)
|
223
248
|
update
|
224
249
|
end
|
225
250
|
|
data/lib/groovy/query.rb
CHANGED
@@ -4,6 +4,7 @@ module Groovy
|
|
4
4
|
include Enumerable
|
5
5
|
AND = '+'.freeze
|
6
6
|
NOT = '-'.freeze
|
7
|
+
PER_PAGE = 50.freeze
|
7
8
|
|
8
9
|
attr_reader :parameters, :sorting
|
9
10
|
|
@@ -23,7 +24,9 @@ module Groovy
|
|
23
24
|
|
24
25
|
def search(obj)
|
25
26
|
obj.each do |col, q|
|
26
|
-
|
27
|
+
unless model.index_columns.include?(col)
|
28
|
+
raise "Not an index column, so cannot do fulltext search: #{col}"
|
29
|
+
end
|
27
30
|
parameters.push(AND + "(#{col}:@#{q})")
|
28
31
|
end
|
29
32
|
end
|
@@ -79,15 +82,21 @@ module Groovy
|
|
79
82
|
end
|
80
83
|
|
81
84
|
def limit(num)
|
82
|
-
@limit = num
|
85
|
+
@sorting[:limit] = num
|
83
86
|
self
|
84
87
|
end
|
85
88
|
|
86
89
|
def offset(num)
|
87
|
-
@offset = num
|
90
|
+
@sorting[:offset] = num
|
88
91
|
self
|
89
92
|
end
|
90
93
|
|
94
|
+
def paginate(page)
|
95
|
+
page = 1 if page.to_i < 1
|
96
|
+
offset = ((page.to_i)-1) * PER_PAGE
|
97
|
+
offset(offset).limit(PER_PAGE)
|
98
|
+
end
|
99
|
+
|
91
100
|
# sort_by(title: :asc)
|
92
101
|
def sort_by(hash)
|
93
102
|
sorting[:by] = hash.keys.map do |key|
|
@@ -97,7 +106,9 @@ module Groovy
|
|
97
106
|
end
|
98
107
|
|
99
108
|
def all
|
100
|
-
@all ||= results.map
|
109
|
+
@all ||= results.map do |r|
|
110
|
+
model.new(r.attributes['_value']['_key'], r)
|
111
|
+
end
|
101
112
|
end
|
102
113
|
|
103
114
|
def size
|
@@ -122,11 +133,26 @@ module Groovy
|
|
122
133
|
all[size-1]
|
123
134
|
end
|
124
135
|
|
136
|
+
def in_batches(of: 1000, from: nil)
|
137
|
+
@sorting[:limit] = of
|
138
|
+
@sorting[:offset] = from || 0
|
139
|
+
|
140
|
+
while results.any?
|
141
|
+
yield all
|
142
|
+
|
143
|
+
@sorting[:offset] += of
|
144
|
+
@all = @results = nil # reset
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
125
148
|
private
|
126
149
|
attr_reader :model, :table, :options
|
127
150
|
|
128
151
|
def results
|
129
152
|
@results ||= execute
|
153
|
+
rescue Groonga::TooLargeOffset
|
154
|
+
# puts "Offset is higher than table size!"
|
155
|
+
[]
|
130
156
|
end
|
131
157
|
|
132
158
|
def execute
|
@@ -138,6 +164,7 @@ module Groovy
|
|
138
164
|
table.select(options)
|
139
165
|
end
|
140
166
|
|
167
|
+
puts "Sorting with #{sort_key_and_order}, #{sorting.inspect}" if ENV['DEBUG']
|
141
168
|
set.sort(sort_key_and_order, {
|
142
169
|
limit: sorting[:limit],
|
143
170
|
offset: sorting[:offset]
|
data/lib/groovy/schema.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)) + '/types'
|
1
|
+
# require File.expand_path(File.dirname(__FILE__)) + '/types'
|
2
2
|
|
3
3
|
module Groovy
|
4
4
|
class Schema
|
@@ -8,6 +8,17 @@ module Groovy
|
|
8
8
|
compress: :zstandard
|
9
9
|
}.freeze
|
10
10
|
|
11
|
+
TYPES = {
|
12
|
+
'string' => 'short_text',
|
13
|
+
'text' => 'text',
|
14
|
+
'float' => 'float',
|
15
|
+
# 'Bool' => 'boolean',
|
16
|
+
'boolean' => 'boolean',
|
17
|
+
'integer' => 'int32',
|
18
|
+
'big_integer' => 'int64',
|
19
|
+
'time' => 'time'
|
20
|
+
}.freeze
|
21
|
+
|
11
22
|
attr_reader :index_columns
|
12
23
|
|
13
24
|
def initialize(context, table_name, opts = {})
|
@@ -47,19 +58,26 @@ module Groovy
|
|
47
58
|
end
|
48
59
|
|
49
60
|
def column(name, type, options = {})
|
50
|
-
groonga_type = Types.map(type)
|
61
|
+
# groonga_type = Types.map(type)
|
62
|
+
groonga_type = type
|
51
63
|
@index_columns.push(name) if options.delete(:index)
|
52
64
|
@spec[name.to_sym] = { type: groonga_type, args: [COLUMN_DEFAULTS.merge(options)] }
|
53
65
|
end
|
54
66
|
|
67
|
+
TYPES.each do |from_type, to_type|
|
68
|
+
define_method(from_type) do |*args|
|
69
|
+
column(args.shift, to_type, (args.shift || {}))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
55
73
|
def reference(name, table_name = nil, options = {})
|
56
74
|
table_name = "#{name}s" if table_name.nil?
|
57
75
|
@spec[name.to_sym] = { type: :reference, args: [table_name, options] }
|
58
76
|
end
|
59
77
|
|
60
78
|
def timestamps(opts = {})
|
61
|
-
column(:created_at, '
|
62
|
-
column(:updated_at, '
|
79
|
+
column(:created_at, 'time')
|
80
|
+
column(:updated_at, 'time')
|
63
81
|
end
|
64
82
|
|
65
83
|
def sync(db_context = nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groovy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomás Pollak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/groovy/schema.rb
|
62
62
|
- lib/groovy/types.rb
|
63
63
|
- lib/groovy/vector.rb
|
64
|
+
- lib/groovy/version.rb
|
64
65
|
- spec/groovy_spec.rb
|
65
66
|
homepage: https://github.com/tomas/groovy
|
66
67
|
licenses: []
|