look_up_table 0.0.3 → 0.1.0.rc0
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.
- data/lib/look_up_table/version.rb +1 -1
- data/lib/look_up_table.rb +192 -84
- data/test/dummy/app/models/foobar.rb +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20111024130333_create_foobars.rb +10 -0
- data/test/dummy/db/schema.rb +23 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +11 -0
- data/test/dummy/log/test.log +11 -0
- data/test/dummy/test/fixtures/foobars.yml +9 -0
- data/test/dummy/test/unit/foobar_test.rb +7 -0
- data/test/dummy/tmp/cache/203/1B0/bar%2F0 +0 -0
- data/test/dummy/tmp/cache/212/7C0/foo%2F0 +0 -0
- data/test/dummy/tmp/cache/213/7D0/foo%2F1 +0 -0
- metadata +34 -13
data/lib/look_up_table.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# TODO
|
2
2
|
# * add: lut_reset(:name)
|
3
|
+
# * move Methods to different modules
|
4
|
+
# * add private/protected
|
3
5
|
module LookUpTable
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
@@ -7,127 +9,233 @@ module LookUpTable
|
|
7
9
|
module ClassMethods
|
8
10
|
# Defining a LookUpTable
|
9
11
|
# TODO: Usage
|
10
|
-
def look_up_table(lut_name, options={})
|
12
|
+
def look_up_table(lut_name, options={}, &block)
|
11
13
|
options = {
|
12
14
|
:batch_size => 10000,
|
13
|
-
:read_on_init =>
|
14
|
-
:skip_memcached => false,
|
15
|
-
:sql_mode => true
|
16
|
-
:write_on_init => true
|
15
|
+
:read_on_init => false,
|
16
|
+
:skip_memcached => false,
|
17
|
+
:sql_mode => true
|
17
18
|
}.merge(options)
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
lut_write_to_cache(options[:batch_size], lut_name, options[:sql_mode]) if options[:write_on_init]
|
23
|
-
end
|
20
|
+
self.lut_proc[lut_name.to_sym] = block
|
21
|
+
self.lut_options[lut_name.to_sym] = options
|
24
22
|
|
25
23
|
self.lut(lut_name) if options[:read_on_init]
|
26
24
|
end
|
27
25
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
# Call to a LookUpTable.
|
27
|
+
# * Example: Tag.lut(:name, "Berlin")
|
28
|
+
# * Returns: nil or stored objects
|
29
|
+
def lut(name, search_by=nil)
|
30
|
+
@@lut ||= {}
|
31
|
+
@@lut[name.to_sym] ||= lut_read(name) || {}
|
32
|
+
|
33
|
+
search_by ? @@lut[name.to_sym][search_by] : @@lut[name.to_sym]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Reset complete lut if name is omitted, resets given lut otherwise.
|
37
|
+
# HACK
|
38
|
+
def lut_reset(name=nil)
|
39
|
+
if name
|
40
|
+
@@lut[name.to_sym] = nil
|
41
|
+
lut_write_cache_item(name, 0, nil) unless lut_options[:skip_memcached]
|
37
42
|
else
|
38
|
-
|
39
|
-
|
43
|
+
@@lut.keys.each { |k| lut_reset(k) }
|
44
|
+
@@lut = {}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
#private
|
51
|
+
|
52
|
+
# lut_set_proc(lut_name, block) / lut_proc(lut_name)
|
53
|
+
def lut_set_proc(name, block)
|
54
|
+
lut_proc[name.to_sym] = block
|
55
|
+
end
|
56
|
+
|
57
|
+
def lut_proc(name = nil)
|
58
|
+
@@lut_proc ||= {}
|
59
|
+
(name) ? @@lut_proc[name.to_sym] : @@lut_proc
|
60
|
+
end
|
61
|
+
|
62
|
+
# lut_set_options(lut_name, options) / lut_options(lut_name)
|
63
|
+
def lut_set_options(name, options)
|
64
|
+
lut_options[name.to_sym] = options
|
65
|
+
end
|
66
|
+
|
67
|
+
def lut_options(name = nil)#, option=nil)
|
68
|
+
@@lut_options ||= {}
|
69
|
+
(name) ? @@lut_options[name.to_sym] : @@lut_options
|
70
|
+
end
|
71
|
+
|
72
|
+
# Reads a single lut
|
73
|
+
# HACK
|
74
|
+
def lut_read(name)
|
75
|
+
return nil unless options = lut_options(name)
|
76
|
+
|
77
|
+
if options[:skip_memcached]
|
78
|
+
return lut_read_without_cache(name)
|
40
79
|
else
|
41
|
-
|
80
|
+
return lut_read_from_cache(name)
|
42
81
|
end
|
43
82
|
end
|
44
|
-
end
|
45
83
|
|
46
84
|
|
47
|
-
def lut_write_to_cache_sql_mode(batch_size, lut_name)
|
48
|
-
batch_count = 0
|
49
85
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
86
|
+
################
|
87
|
+
### NO-CACHE ###
|
88
|
+
################
|
89
|
+
|
90
|
+
# Reads a complete from given block or generic version
|
91
|
+
# HACK: some duplicated methods from Class.lut_write_to_cache
|
92
|
+
def lut_read_without_cache(name)
|
93
|
+
if lut_options(name)[:sql_mode]
|
94
|
+
return lut_read_without_cache_sql_mode(name)
|
95
|
+
else
|
96
|
+
return lut_read_without_cache_no_sql_mode(name)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# HACK: somehow long method
|
101
|
+
def lut_read_without_cache_sql_mode(name)
|
102
|
+
lut = {}
|
103
|
+
block = lut_proc(name)
|
104
|
+
|
105
|
+
self.find_in_batches(:batch_size => lut_options(name)[:batch_size]) do |items|
|
106
|
+
items.each do |item|
|
107
|
+
if block
|
108
|
+
block.call(lut, item)
|
109
|
+
else
|
110
|
+
lut[item.send(name)] = item.id
|
111
|
+
end
|
57
112
|
end
|
58
113
|
end
|
59
114
|
|
60
|
-
|
61
|
-
batch_count += 1
|
115
|
+
return lut
|
62
116
|
end
|
63
|
-
end
|
64
117
|
|
118
|
+
# HACK: ugly method_name
|
119
|
+
def lut_read_without_cache_no_sql_mode(name)
|
120
|
+
lut = {}
|
65
121
|
|
66
|
-
|
67
|
-
|
68
|
-
|
122
|
+
block = lut_proc(name)
|
123
|
+
block.call(lut)
|
124
|
+
|
125
|
+
return lut
|
126
|
+
end
|
69
127
|
|
70
|
-
yield(lut)
|
71
|
-
keys = lut.keys
|
72
128
|
|
73
|
-
while
|
74
|
-
key_block = keys.slice!(0,batch_size)
|
75
|
-
break if key_block.empty?
|
76
129
|
|
77
|
-
|
78
|
-
|
130
|
+
#############
|
131
|
+
### CACHE ###
|
132
|
+
#############
|
79
133
|
|
80
|
-
|
81
|
-
|
134
|
+
# Cache entry for given LUT exists?
|
135
|
+
# TODO: just check if given key exists
|
136
|
+
def lut_cache_exists?(name)
|
137
|
+
!lut_read_cache_item(name, 0).nil?
|
82
138
|
end
|
83
|
-
end
|
84
139
|
|
140
|
+
# Reads a complete lut from cache
|
141
|
+
# HACK: this still looks ugly somehow
|
142
|
+
def lut_read_from_cache(name)
|
143
|
+
lut_write_to_cache(name) unless lut_cache_exists?(name)
|
85
144
|
|
86
|
-
|
87
|
-
|
88
|
-
status = Rails.cache.write("#{lut_name}/#{lut_item}", lut_data)
|
89
|
-
raise "Cache::write returned false" unless status
|
90
|
-
end
|
145
|
+
i = 0
|
146
|
+
lut = {}
|
91
147
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
148
|
+
while item = lut_read_cache_item(name, i)
|
149
|
+
lut.merge!(item) if item
|
150
|
+
i += 1
|
151
|
+
end
|
96
152
|
|
97
|
-
|
98
|
-
lut.merge!(res) if res
|
99
|
-
i += 1
|
153
|
+
return lut
|
100
154
|
end
|
101
155
|
|
102
|
-
|
103
|
-
|
156
|
+
# Reads a single item of a LookUpTable from Cache
|
157
|
+
def lut_read_cache_item(name, item)
|
158
|
+
Rails.cache.read("#{name}/#{item}")
|
159
|
+
end
|
104
160
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
161
|
+
# Write a LookUpTable into Cache
|
162
|
+
def lut_write_to_cache(name)
|
163
|
+
if lut_options(name)[:sql_mode]
|
164
|
+
count = lut_write_to_cache_sql_mode(name)
|
165
|
+
else
|
166
|
+
count = lut_write_to_cache_no_sql_mode(name)
|
167
|
+
end
|
109
168
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
def lut(lut_name, search_by=nil)
|
114
|
-
@@look_up_tables ||= {}
|
115
|
-
@@look_up_tables[lut_name.to_sym] ||= lut_read_from_cache(lut_name) || {}
|
169
|
+
# HACK: Writing a \0 to terminate batch_items
|
170
|
+
lut_write_cache_item(name, count, nil)
|
171
|
+
end
|
116
172
|
|
117
|
-
|
118
|
-
|
119
|
-
|
173
|
+
# HACK: somehow long method
|
174
|
+
def lut_write_to_cache_sql_mode(name)
|
175
|
+
batch_count = 0
|
120
176
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
177
|
+
self.find_in_batches(:batch_size => lut_options(name)[:batch_size]) do |items|
|
178
|
+
lut = {}
|
179
|
+
block = lut_proc(name)
|
180
|
+
|
181
|
+
items.each do |item|
|
182
|
+
if block
|
183
|
+
block.call(lut, item)
|
184
|
+
else
|
185
|
+
lut[item.send(name)] = item.id
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
self.lut_write_cache_item(name, batch_count, lut)
|
190
|
+
batch_count += 1
|
191
|
+
end
|
192
|
+
|
193
|
+
batch_count
|
194
|
+
end
|
195
|
+
|
196
|
+
# HACK: somehow long method
|
197
|
+
def lut_write_to_cache_no_sql_mode(name)
|
198
|
+
lut = {}
|
199
|
+
batch_count = 0
|
200
|
+
|
201
|
+
block = lut_proc(name)
|
202
|
+
block.call(lut)
|
203
|
+
|
204
|
+
keys = lut.keys
|
205
|
+
|
206
|
+
while
|
207
|
+
key_block = keys.slice!(0,batch_size)
|
208
|
+
break if key_block.empty?
|
209
|
+
|
210
|
+
lut_block = {}
|
211
|
+
key_block.each{|key| lut_block[key] = lut[key]}
|
212
|
+
|
213
|
+
self.lut_write_cache_item(name, batch_count, lut_block)
|
214
|
+
batch_count += 1
|
215
|
+
end
|
216
|
+
|
217
|
+
batch_count
|
218
|
+
end
|
219
|
+
|
220
|
+
# Write a single Item into LookUpTable-Cache
|
221
|
+
def lut_write_cache_item(name, lut_item, lut_data)
|
222
|
+
status = Rails.cache.write("#{name}/#{lut_item}", lut_data)
|
223
|
+
raise "Cache::write failed - Try lower :batch_size" unless status
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
# Delegating <attribute>_lut(args) method calls
|
229
|
+
# HACK
|
230
|
+
def method_missing(m, *args, &block)
|
231
|
+
method_name = m.to_s
|
232
|
+
if method_name.end_with?("_lut")
|
233
|
+
lut_name = method_name[0..-5]
|
234
|
+
self.lut(lut_name, args.first)
|
235
|
+
else
|
236
|
+
super(m, *args, &block)
|
237
|
+
end
|
129
238
|
end
|
130
|
-
end
|
131
239
|
|
132
240
|
end
|
133
241
|
end
|
Binary file
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended to check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(:version => 20111024130333) do
|
15
|
+
|
16
|
+
create_table "foobars", :force => true do |t|
|
17
|
+
t.string "foo"
|
18
|
+
t.integer "bar"
|
19
|
+
t.datetime "created_at"
|
20
|
+
t.datetime "updated_at"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
Binary file
|
@@ -0,0 +1,11 @@
|
|
1
|
+
[1m[36m (0.1ms)[0m [1mselect sqlite_version(*)[0m
|
2
|
+
[1m[35m (135.8ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
3
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
4
|
+
[1m[35m (88.2ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
5
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
6
|
+
Migrating to CreateFoobars (20111024130333)
|
7
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "foobars" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo" varchar(255), "bar" integer, "created_at" datetime, "updated_at" datetime)
|
8
|
+
[1m[36m (0.7ms)[0m [1mINSERT INTO "schema_migrations" ("version") VALUES ('20111024130333')[0m
|
9
|
+
[1m[35m (0.5ms)[0m select sqlite_version(*)
|
10
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
11
|
+
[1m[35m (0.0ms)[0m PRAGMA index_list("foobars")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
[1m[36m (0.1ms)[0m [1mselect sqlite_version(*)[0m
|
2
|
+
[1m[35m (115.3ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
3
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
4
|
+
[1m[35m (99.0ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
5
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
6
|
+
Migrating to CreateFoobars (20111024130333)
|
7
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "foobars" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo" varchar(255), "bar" integer, "created_at" datetime, "updated_at" datetime)
|
8
|
+
[1m[36m (0.6ms)[0m [1mINSERT INTO "schema_migrations" ("version") VALUES ('20111024130333')[0m
|
9
|
+
[1m[35m (0.3ms)[0m select sqlite_version(*)
|
10
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
11
|
+
[1m[35m (0.1ms)[0m PRAGMA index_list("foobars")
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: look_up_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0.rc0
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Patrick Helm
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-10-
|
12
|
+
date: 2011-10-24 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &85611210 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.1.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *85611210
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sqlite3
|
27
|
-
requirement: &
|
27
|
+
requirement: &85610990 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *85610990
|
36
36
|
description: A simple LookUpTable to cache large (!) and static(!) data
|
37
37
|
email:
|
38
38
|
- ph@werbeboten.de
|
@@ -49,9 +49,18 @@ files:
|
|
49
49
|
- README.rdoc
|
50
50
|
- test/test_helper.rb
|
51
51
|
- test/look_up_table_test.rb
|
52
|
+
- test/dummy/db/migrate/20111024130333_create_foobars.rb
|
53
|
+
- test/dummy/db/schema.rb
|
54
|
+
- test/dummy/db/development.sqlite3
|
55
|
+
- test/dummy/db/test.sqlite3
|
52
56
|
- test/dummy/config.ru
|
57
|
+
- test/dummy/test/fixtures/foobars.yml
|
58
|
+
- test/dummy/test/unit/foobar_test.rb
|
53
59
|
- test/dummy/Rakefile
|
60
|
+
- test/dummy/log/development.log
|
61
|
+
- test/dummy/log/test.log
|
54
62
|
- test/dummy/app/views/layouts/application.html.erb
|
63
|
+
- test/dummy/app/models/foobar.rb
|
55
64
|
- test/dummy/app/assets/javascripts/application.js
|
56
65
|
- test/dummy/app/assets/stylesheets/application.css
|
57
66
|
- test/dummy/app/helpers/application_helper.rb
|
@@ -75,6 +84,9 @@ files:
|
|
75
84
|
- test/dummy/public/422.html
|
76
85
|
- test/dummy/public/favicon.ico
|
77
86
|
- test/dummy/public/500.html
|
87
|
+
- test/dummy/tmp/cache/213/7D0/foo%2F1
|
88
|
+
- test/dummy/tmp/cache/203/1B0/bar%2F0
|
89
|
+
- test/dummy/tmp/cache/212/7C0/foo%2F0
|
78
90
|
- test/dummy/script/rails
|
79
91
|
homepage: http://www.deckel-gesucht.de
|
80
92
|
licenses: []
|
@@ -90,16 +102,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
102
|
version: '0'
|
91
103
|
segments:
|
92
104
|
- 0
|
93
|
-
hash:
|
105
|
+
hash: 67753825
|
94
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
107
|
none: false
|
96
108
|
requirements:
|
97
|
-
- - ! '
|
109
|
+
- - ! '>'
|
98
110
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
100
|
-
segments:
|
101
|
-
- 0
|
102
|
-
hash: -202588273
|
111
|
+
version: 1.3.1
|
103
112
|
requirements: []
|
104
113
|
rubyforge_project:
|
105
114
|
rubygems_version: 1.8.10
|
@@ -109,9 +118,18 @@ summary: A simple LookUpTable to cache large (!) and static(!) data
|
|
109
118
|
test_files:
|
110
119
|
- test/test_helper.rb
|
111
120
|
- test/look_up_table_test.rb
|
121
|
+
- test/dummy/db/migrate/20111024130333_create_foobars.rb
|
122
|
+
- test/dummy/db/schema.rb
|
123
|
+
- test/dummy/db/development.sqlite3
|
124
|
+
- test/dummy/db/test.sqlite3
|
112
125
|
- test/dummy/config.ru
|
126
|
+
- test/dummy/test/fixtures/foobars.yml
|
127
|
+
- test/dummy/test/unit/foobar_test.rb
|
113
128
|
- test/dummy/Rakefile
|
129
|
+
- test/dummy/log/development.log
|
130
|
+
- test/dummy/log/test.log
|
114
131
|
- test/dummy/app/views/layouts/application.html.erb
|
132
|
+
- test/dummy/app/models/foobar.rb
|
115
133
|
- test/dummy/app/assets/javascripts/application.js
|
116
134
|
- test/dummy/app/assets/stylesheets/application.css
|
117
135
|
- test/dummy/app/helpers/application_helper.rb
|
@@ -135,4 +153,7 @@ test_files:
|
|
135
153
|
- test/dummy/public/422.html
|
136
154
|
- test/dummy/public/favicon.ico
|
137
155
|
- test/dummy/public/500.html
|
156
|
+
- test/dummy/tmp/cache/213/7D0/foo%2F1
|
157
|
+
- test/dummy/tmp/cache/203/1B0/bar%2F0
|
158
|
+
- test/dummy/tmp/cache/212/7C0/foo%2F0
|
138
159
|
- test/dummy/script/rails
|