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.
@@ -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