look_up_table 0.0.3 → 0.1.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module LookUpTable
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0.rc0"
3
3
  end
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 => true,
14
- :skip_memcached => false, #TODO
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
- if block_given?
20
- lut_write_to_cache(options[:batch_size], lut_name, options[:sql_mode], &Proc.new) if options[:write_on_init]
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
- # Write a LookUpTable into Cache
29
- # TODO refactor
30
- def lut_write_to_cache(batch_size, lut_name, sql_mode)
31
- if sql_mode
32
- if block_given?
33
- lut_write_to_cache_sql_mode(batch_size, lut_name, &Proc.new)
34
- else
35
- lut_write_to_cache_sql_mode(batch_size, lut_name)
36
- end
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
- if block_given?
39
- lut_write_to_cache_no_sql_mode(batch_size, lut_name, &Proc.new)
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
- lut_write_to_cache_no_sql_mode(batch_size, lut_name)
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
- self.find_in_batches(:batch_size => batch_size) do |items|
51
- lut = {}
52
- items.each do |item|
53
- if block_given?
54
- yield(lut, item)
55
- else
56
- lut[item.send(lut_name)] = item.id
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
- self.lut_write_cache_item(lut_name, batch_count, lut)
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
- def lut_write_to_cache_no_sql_mode(batch_size, lut_name)
67
- lut = {}
68
- batch_count = 0
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
- lut_block = {}
78
- key_block.each{|key| lut_block[key] = lut[key]}
130
+ #############
131
+ ### CACHE ###
132
+ #############
79
133
 
80
- self.lut_write_cache_item(lut_name, batch_count, lut_block)
81
- batch_count += 1
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
- # Write a single Item into LookUpTable-Cache
87
- def lut_write_cache_item(lut_name, lut_item, lut_data)
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
- # Reads a single LookUpTable from Cache
93
- def lut_read_from_cache(lut_name)
94
- i = 0
95
- lut = {}
148
+ while item = lut_read_cache_item(name, i)
149
+ lut.merge!(item) if item
150
+ i += 1
151
+ end
96
152
 
97
- while res = lut_read_cache_item(lut_name, i)
98
- lut.merge!(res) if res
99
- i += 1
153
+ return lut
100
154
  end
101
155
 
102
- return lut
103
- end
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
- # Reads a single item of a LookUpTable from Cache
106
- def lut_read_cache_item(lut_name, lut_item)
107
- Rails.cache.read("#{lut_name}/#{lut_item}")
108
- end
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
- # Call to a LookUpTable, example Usage:
111
- # * Tag.lut(:name, "Berlin")
112
- # Returns nil or stored objects
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
- return @@look_up_tables[lut_name.to_sym][search_by] if search_by
118
- return @@look_up_tables[lut_name.to_sym]
119
- end
173
+ # HACK: somehow long method
174
+ def lut_write_to_cache_sql_mode(name)
175
+ batch_count = 0
120
176
 
121
- # Delegating <attribute>_lut(args) method calls
122
- def method_missing(m, *args, &block)
123
- method_name = m.to_s
124
- if method_name.end_with?("_lut")
125
- lut_name = method_name[0..-5]
126
- self.lut(lut_name, args.first)
127
- else
128
- raise "MethodNotFound: #{m}"
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
@@ -0,0 +1,4 @@
1
+ class Foobar < ActiveRecord::Base
2
+ look_up_table :foo
3
+ end
4
+
Binary file
@@ -0,0 +1,10 @@
1
+ class CreateFoobars < ActiveRecord::Migration
2
+ def change
3
+ create_table :foobars do |t|
4
+ t.string :foo
5
+ t.integer :bar
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -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
+  (0.1ms) select sqlite_version(*)
2
+  (135.8ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
3
+  (0.1ms) PRAGMA index_list("schema_migrations")
4
+  (88.2ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
5
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
6
+ Migrating to CreateFoobars (20111024130333)
7
+  (1.1ms) CREATE TABLE "foobars" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo" varchar(255), "bar" integer, "created_at" datetime, "updated_at" datetime)
8
+  (0.7ms) INSERT INTO "schema_migrations" ("version") VALUES ('20111024130333')
9
+  (0.5ms) select sqlite_version(*)
10
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
11
+  (0.0ms) PRAGMA index_list("foobars")
@@ -0,0 +1,11 @@
1
+  (0.1ms) select sqlite_version(*)
2
+  (115.3ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
3
+  (0.1ms) PRAGMA index_list("schema_migrations")
4
+  (99.0ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
5
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
6
+ Migrating to CreateFoobars (20111024130333)
7
+  (1.1ms) CREATE TABLE "foobars" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo" varchar(255), "bar" integer, "created_at" datetime, "updated_at" datetime)
8
+  (0.6ms) INSERT INTO "schema_migrations" ("version") VALUES ('20111024130333')
9
+  (0.3ms) select sqlite_version(*)
10
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
11
+  (0.1ms) PRAGMA index_list("foobars")
@@ -0,0 +1,9 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
2
+
3
+ one:
4
+ foo: MyString
5
+ bar: 1
6
+
7
+ two:
8
+ foo: MyString
9
+ bar: 1
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class FoobarTest < ActiveSupport::TestCase
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ end
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.3
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-14 00:00:00.000000000Z
12
+ date: 2011-10-24 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &78698380 !ruby/object:Gem::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: *78698380
24
+ version_requirements: *85611210
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sqlite3
27
- requirement: &78698090 !ruby/object:Gem::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: *78698090
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: -202588273
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: '0'
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