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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2968c89f9c0019f1984b53b34a1d5c4520e82bede4f56020a7ef490c76897fe
4
- data.tar.gz: 6de69f1590be6a8bddd69f60bed379e8e59e75dcd2a9a00c5696ef5160b211a5
3
+ metadata.gz: 21ec75f430aa5b3ea423b52de62b4d578b4eb0b1e6722e9201c012cd444c616b
4
+ data.tar.gz: ec46772137b69e14dfe364d383fa9042ec8edd798bd22ed5c2dd4a47f895f1a4
5
5
  SHA512:
6
- metadata.gz: 1b7be573999c72a9a5bb1a5b140388644702430c51a07a315d163c8a6f7db89058416ebcc252351498fd5d3b5e86d2cafeea06653e396bc6ddcf3d4bfaf6e6d3
7
- data.tar.gz: 8693eb5c4472d634b62ad3be13e57e1c54172374aef7f8792807b107de068457bef293106437521b9200977db95122b524e2182438441fee780e72c15f129f1f
6
+ metadata.gz: 044e5ba04d8097a354be1a6feb07c2ddd06c6e28355a07b41586936a4e572e028f1aefd35bb587dff46f2d1bbad513332d915e7aec01c00df26b09f6a3ffb357
7
+ data.tar.gz: 30ae3849bb6d769beb08db3ea8c676a0270a1037eb854c5ba7f4df2c3467906ad06055c7409ef8f2cf5284712f668c7153055b77470d0fa902e2d808591eedc4
data/example/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- groovy (0.1.0)
4
+ groovy (0.1.1)
5
5
  rroonga (~> 7.1)
6
6
 
7
7
  GEM
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.column :name, String
11
- t.column :price, Integer
10
+ t.string :name
11
+ t.integer :price
12
12
  t.timestamps
13
13
  end
14
14
  end
15
15
 
16
- 50_000.times do |i|
17
- puts "Creating product #{i}" if i % 1000 == 0
18
- Product.create!(name: "A product with index #{i}", price: 10000 + i)
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
- puts Product.count
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
@@ -1,4 +1,4 @@
1
- require './models'
1
+ require './relations'
2
2
  require 'groovy/middleware'
3
3
 
4
4
  Place.delete_all
@@ -15,4 +15,4 @@ app = Proc.new do |env|
15
15
  end
16
16
 
17
17
  use Groovy::MemoryPoolMiddleware
18
- run app
18
+ run app
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.column :name, String
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.column :name, String
34
- t.column :description, String, index: true
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.column :coords, String
44
+ t.string :coords
45
45
  t.timestamps
46
46
  end
47
47
  end
data/groovy.gemspec CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path("../lib/groovy", __FILE__)
2
+ require File.expand_path("../lib/groovy/version", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "groovy"
data/lib/groovy.rb CHANGED
@@ -2,7 +2,6 @@ require 'groonga'
2
2
  require File.expand_path(File.dirname(__FILE__)) + '/groovy/model'
3
3
 
4
4
  module Groovy
5
- VERSION = '0.1.1'.freeze
6
5
 
7
6
  class << self
8
7
 
data/lib/groovy/model.rb CHANGED
@@ -107,12 +107,24 @@ module Groovy
107
107
  Query.new(self, table)
108
108
  end
109
109
 
110
- def_instance_delegators :all, :first, :last
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
- private
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 = (attributes || {}).symbolize_keys.slice(*self.class.attribute_names)
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 { |col| set_ref(col, record.public_send(col)) }
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.each { |k,v| self[k] = v }
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
- raise "Not a full-text search column: #{col}" unless model.search_columns.include?(col)
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 { |r| model.new(r.attributes['_value']['_key'], r) }
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, 'Time')
62
- column(:updated_at, 'Time')
79
+ column(:created_at, 'time')
80
+ column(:updated_at, 'time')
63
81
  end
64
82
 
65
83
  def sync(db_context = nil)
@@ -0,0 +1,3 @@
1
+ module Groovy
2
+ VERSION = '0.1.2'.freeze
3
+ end
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.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-04-18 00:00:00.000000000 Z
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: []