lore 0.4.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.
- data/LICENSE +19 -0
- data/README +74 -0
- data/aspect.rb +80 -0
- data/behaviours/lockable.rb +41 -0
- data/behaviours/movable.rb +54 -0
- data/behaviours/versioned.rb +24 -0
- data/benchmark.rb +193 -0
- data/bits.rb +52 -0
- data/cache/abstract_entity_cache.rb +82 -0
- data/cache/bits.rb +22 -0
- data/cache/cacheable.rb +202 -0
- data/cache/cached_entities.rb +116 -0
- data/cache/file_index.rb +35 -0
- data/cache/mmap_entity_cache.rb +67 -0
- data/clause.rb +528 -0
- data/connection.rb +155 -0
- data/custom_functions.sql +14 -0
- data/exception/ambiguous_attribute.rb +14 -0
- data/exception/cache_exception.rb +30 -0
- data/exception/invalid_klass_parameters.rb +63 -0
- data/exception/invalid_parameter.rb +42 -0
- data/exception/unknown_typecode.rb +19 -0
- data/file_index.sql +56 -0
- data/gui/erb_template.rb +79 -0
- data/gui/erb_template_helpers.rhtml +19 -0
- data/gui/form.rb +314 -0
- data/gui/form_element.rb +676 -0
- data/gui/form_generator.rb +151 -0
- data/gui/templates/button.rhtml +2 -0
- data/gui/templates/checkbox.rhtml +3 -0
- data/gui/templates/checkbox_row.rhtml +1 -0
- data/gui/templates/file.rhtml +2 -0
- data/gui/templates/file_readonly.rhtml +3 -0
- data/gui/templates/form_element.rhtml +5 -0
- data/gui/templates/form_element_horizontal.rhtml +3 -0
- data/gui/templates/form_element_listed.rhtml +8 -0
- data/gui/templates/form_table.rhtml +3 -0
- data/gui/templates/form_table_blank.rhtml +3 -0
- data/gui/templates/form_table_horizontal.rhtml +8 -0
- data/gui/templates/password.rhtml +2 -0
- data/gui/templates/password_readonly.rhtml +3 -0
- data/gui/templates/radio.rhtml +1 -0
- data/gui/templates/radio_row.rhtml +1 -0
- data/gui/templates/select.rhtml +23 -0
- data/gui/templates/text.rhtml +2 -0
- data/gui/templates/text_readonly.rhtml +3 -0
- data/gui/templates/textarea.rhtml +3 -0
- data/gui/templates/textarea_readonly.rhtml +4 -0
- data/lore.gemspec +40 -0
- data/lore.rb +94 -0
- data/migration.rb +48 -0
- data/model.rb +139 -0
- data/model_factory.rb +202 -0
- data/model_shortcuts.rb +16 -0
- data/query_shortcuts.rb +367 -0
- data/reserved_methods.txt +3 -0
- data/result.rb +100 -0
- data/symbol.rb +58 -0
- data/table_accessor.rb +1926 -0
- data/table_deleter.rb +115 -0
- data/table_inserter.rb +168 -0
- data/table_instance.rb +384 -0
- data/table_selector.rb +314 -0
- data/table_updater.rb +155 -0
- data/test/README +31 -0
- data/test/env.rb +5 -0
- data/test/lore_test.log +8218 -0
- data/test/model.rb +142 -0
- data/test/prepare.rb +37 -0
- data/test/tc_aspect.rb +58 -0
- data/test/tc_cache.rb +80 -0
- data/test/tc_clause.rb +104 -0
- data/test/tc_deep_inheritance.rb +49 -0
- data/test/tc_factory.rb +57 -0
- data/test/tc_filter.rb +37 -0
- data/test/tc_form.rb +32 -0
- data/test/tc_model.rb +86 -0
- data/test/tc_prepare.rb +45 -0
- data/test/tc_refined_query.rb +88 -0
- data/test/tc_table_accessor.rb +265 -0
- data/test/test.log +181 -0
- data/test/test_db.sql +400 -0
- data/test/ts_lore.rb +49 -0
- data/types.rb +55 -0
- data/validation/message.rb +60 -0
- data/validation/parameter_validator.rb +104 -0
- data/validation/reason.rb +54 -0
- data/validation/type_validator.rb +91 -0
- data/validation.rb +65 -0
- metadata +170 -0
data/cache/cacheable.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
|
2
|
+
require('pstore')
|
3
|
+
|
4
|
+
require('lore/cache/bits')
|
5
|
+
require('lore/exception/cache_exception')
|
6
|
+
|
7
|
+
module Lore
|
8
|
+
module Cache
|
9
|
+
|
10
|
+
module Cacheable
|
11
|
+
|
12
|
+
@@cache_control = Hash.new
|
13
|
+
@@cache_on_pkeys = Hash.new
|
14
|
+
@@distinctive_params = Hash.new
|
15
|
+
@@cache_entities = false
|
16
|
+
|
17
|
+
@@logger = Lore.logger
|
18
|
+
|
19
|
+
public
|
20
|
+
|
21
|
+
def is_cacheable(controller)
|
22
|
+
controller = controller.intern unless controller.instance_of? Symbol
|
23
|
+
return !@@cache_control[controller].nil? && @@cache_control[controller]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns whether a Table_Accessor state
|
27
|
+
# is cached or not.
|
28
|
+
def is_cached(controller, mode, keys)
|
29
|
+
|
30
|
+
store_filename = Lore::Cache::store_name(self.name.to_s, controller, mode, keys)
|
31
|
+
if store_filename.nil? then
|
32
|
+
excep_mesg = 'Cannot resolve store filename for ['+self.name.to_s+'|'+controller+'|'+mode+']'
|
33
|
+
excep_mesg += ' Keys: '+keys.to_s
|
34
|
+
raise ::Exception.new(excep_mesg)
|
35
|
+
end
|
36
|
+
|
37
|
+
if FileTest.exist?(store_filename) then
|
38
|
+
true
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def cache(controller, additional_params=nil)
|
48
|
+
controller = controller.intern unless controller.instance_of? Symbol
|
49
|
+
@@cache_control[controller] = true
|
50
|
+
if !additional_params.nil? then
|
51
|
+
@@distinctive_params[controller] = Array.new unless !@@distinctive_params[controller].nil?
|
52
|
+
@@distinctive_params[controller] += additional_params
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def cache_select_entities
|
58
|
+
@@cache_entities = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def cache_entities
|
62
|
+
@@cache_entities
|
63
|
+
end
|
64
|
+
|
65
|
+
def cache_on_pkeys(controller, additional_params=nil)
|
66
|
+
@@logger.log('Caching depending from pkeys only, controller: ' << controller.to_s << ', params: ' << additional_params.to_s)
|
67
|
+
cache(controller, additional_params)
|
68
|
+
@@cache_on_pkeys[controller] = true
|
69
|
+
end
|
70
|
+
|
71
|
+
def cache_pkeys_only?(controller)
|
72
|
+
!@@cache_on_pkeys[controller].nil? && @@cache_on_pkeys[controller]
|
73
|
+
end
|
74
|
+
|
75
|
+
def nocache(controller)
|
76
|
+
controller = controller.intern unless controller.instance_of? Symbol
|
77
|
+
@@cache_control[controller] = false
|
78
|
+
end
|
79
|
+
|
80
|
+
public
|
81
|
+
|
82
|
+
def cache_params(controller)
|
83
|
+
return @@distinctive_params[controller] unless @@distinctive_params[controller].nil?
|
84
|
+
return Hash.new
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_cache(controller, mode, keys, output)
|
88
|
+
|
89
|
+
@@logger.log('cache_on_pkeys: '+@@cache_on_pkeys.inspect)
|
90
|
+
if !@@cache_on_pkeys[controller.intern].nil? &&
|
91
|
+
@@cache_on_pkeys[controller.intern]
|
92
|
+
then
|
93
|
+
keys = filter_pkeys(self, controller, keys)
|
94
|
+
@@logger.log('Filtered keys: '+keys.inspect)
|
95
|
+
end
|
96
|
+
|
97
|
+
if !@@cache_control[controller.intern].nil? &&
|
98
|
+
@@cache_control[controller.intern]
|
99
|
+
then
|
100
|
+
|
101
|
+
if !@@cache_control[:self].nil? &&
|
102
|
+
@@cache_control[:self]
|
103
|
+
then
|
104
|
+
class_copy = self
|
105
|
+
end
|
106
|
+
|
107
|
+
if is_cached(controller, mode, keys) then
|
108
|
+
return
|
109
|
+
end
|
110
|
+
|
111
|
+
store = create_store(controller, mode, keys, output)
|
112
|
+
store.transaction do
|
113
|
+
store['klass'] = class_copy unless class_copy.nil?
|
114
|
+
store['controller'] = controller
|
115
|
+
store['mode'] = mode
|
116
|
+
store['keys'] = keys
|
117
|
+
store['output'] = output
|
118
|
+
end
|
119
|
+
|
120
|
+
else
|
121
|
+
raise Cache_Write_Exception.new(self.name.to_s, controller, mode, keys)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
public
|
127
|
+
|
128
|
+
def create_cache!(controller, mode, keys, output)
|
129
|
+
invalidate(controller, mode, keys)
|
130
|
+
create_cache(controller, mode, keys)
|
131
|
+
end
|
132
|
+
|
133
|
+
public
|
134
|
+
|
135
|
+
def read_cache(controller, mode, keys)
|
136
|
+
|
137
|
+
if !@@cache_control[controller.intern].nil? &&
|
138
|
+
@@cache_control[controller.intern] &&
|
139
|
+
is_cached(controller, mode, keys)
|
140
|
+
then
|
141
|
+
|
142
|
+
output = ''
|
143
|
+
store = create_store(controller, mode, keys, output)
|
144
|
+
store.transaction do
|
145
|
+
output = store['output']
|
146
|
+
end
|
147
|
+
|
148
|
+
return output
|
149
|
+
|
150
|
+
else
|
151
|
+
raise Cache_Read_Exception.new(self.name.to_s, controller, mode, keys)
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
def invalidate(controller, mode, keys)
|
157
|
+
File.unlink(Lore::Cache::store_name(self.name.to_s, controller, mode, keys))
|
158
|
+
end
|
159
|
+
def invalidate_all(controller=:all, mode=:all, keys=:all)
|
160
|
+
cwd = Dir.getwd
|
161
|
+
Dir.chdir('/tmp/')
|
162
|
+
if keys == :all then keys = Hash.new end
|
163
|
+
invalid_cache_pattern = Lore::Cache::store_name(self.name.to_s, controller, mode, keys)
|
164
|
+
@@logger.log('Deleting cache for: '+invalid_cache_pattern)
|
165
|
+
invalid_cache_files = Dir.glob(invalid_cache_pattern)
|
166
|
+
invalid_cache_files.each { |cache_file|
|
167
|
+
@@logger.log('Deleting '+cache_file)
|
168
|
+
File.delete(cache_file)
|
169
|
+
}
|
170
|
+
Dir.chdir(cwd)
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def create_store(controller, mode, keys, output)
|
176
|
+
store_file = Lore::Cache::store_name(self.to_s, controller, mode, keys)
|
177
|
+
store = PStore.new(store_file) unless store_file.nil?
|
178
|
+
return store
|
179
|
+
end
|
180
|
+
|
181
|
+
def filter_pkeys(model_klass, controller, keys)
|
182
|
+
if !model_klass.respond_to? 'key_array' then
|
183
|
+
@@logger.log('could not filter for pkeys')
|
184
|
+
return keys
|
185
|
+
end
|
186
|
+
result = Hash.new
|
187
|
+
model_klass.key_array.each { |pkey|
|
188
|
+
result[pkey] = keys[pkey]
|
189
|
+
}
|
190
|
+
if !@@distinctive_params[controller].nil? then
|
191
|
+
@@distinctive_params[controller].each { |param|
|
192
|
+
result[param] = keys[param]
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
return result
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end # module
|
202
|
+
end # module
|
@@ -0,0 +1,116 @@
|
|
1
|
+
|
2
|
+
require('logger')
|
3
|
+
|
4
|
+
module Lore
|
5
|
+
module Cache
|
6
|
+
|
7
|
+
class Cached_Entities
|
8
|
+
|
9
|
+
@@logger = Lore.logger
|
10
|
+
@@mmap_cache = Hash.new
|
11
|
+
@@file_index = Hash.new
|
12
|
+
|
13
|
+
public
|
14
|
+
|
15
|
+
def self.flush(type)
|
16
|
+
index = type.table_name
|
17
|
+
return if (!Lore.cache_entities() || @@file_index[index].nil?)
|
18
|
+
@@file_index[index].each { |cache_file|
|
19
|
+
@@logger.debug { 'Clearing cache file ' << cache_file }
|
20
|
+
File.unlink(cache_file)
|
21
|
+
}
|
22
|
+
@@file_index.delete(type.table_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.[]=(query_string, result)
|
26
|
+
if $cb__use_pstore_cache then
|
27
|
+
create_pstore_cache(query_string, result)
|
28
|
+
else
|
29
|
+
create_mmap_cache(query_string, result)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.create(accessor, query_string, result)
|
34
|
+
if $cb__use_pstore_cache then
|
35
|
+
file = create_pstore_cache(query_string, result)
|
36
|
+
else
|
37
|
+
file = create_mmap_cache(query_string, result)
|
38
|
+
end
|
39
|
+
@@file_index[accessor.table_name] = Array.new unless @@file_index[accessor.table_name]
|
40
|
+
@@file_index[accessor.table_name] << file
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.[](query_string)
|
44
|
+
if $cb__use_pstore_cache then
|
45
|
+
return read_pstore_cache(query_string)
|
46
|
+
else
|
47
|
+
return read_mmap_cache(query_string)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.include?(query_string)
|
52
|
+
FileTest.exist?(storefile_of(query_string))
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def self.create_pstore_cache(query_string, result)
|
58
|
+
storefile = storefile_of(query_string)
|
59
|
+
store = create_store(storefile)
|
60
|
+
store.transaction do
|
61
|
+
store['dump'] = result
|
62
|
+
end
|
63
|
+
return storefile
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.read_pstore_cache(query_string)
|
67
|
+
store = create_store(storefile_of(query_string))
|
68
|
+
result = Array.new
|
69
|
+
store.transaction do
|
70
|
+
result = store['dump']
|
71
|
+
end
|
72
|
+
return result
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.create_mmap_cache(query_string, result)
|
76
|
+
storefile = storefile_of(query_string)
|
77
|
+
store = create_store(storefile)
|
78
|
+
store.transaction do
|
79
|
+
store['dump'] = result
|
80
|
+
end
|
81
|
+
@@mmap_cache[index_for(query_string)] = Mmap.new(storefile)
|
82
|
+
return storefile
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.read_mmap_cache(query_string)
|
86
|
+
@@logger.debug { 'Loading from cache: ' << index_for(query_string) }
|
87
|
+
store = @@mmap_cache[index_for(query_string)]
|
88
|
+
@@logger.debug { 'STORE: ' << store.inspect }
|
89
|
+
return [] unless store
|
90
|
+
result = Marshal::load(store)
|
91
|
+
return result['dump']
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.delete_mmap_cache(index)
|
95
|
+
@@mmap_cache[index].munmap
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def self.index_for(query)
|
101
|
+
Digest::MD5.hexdigest(query)
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.storefile_of(query)
|
105
|
+
'/tmp/cb__cache__entities__' << Digest::MD5.hexdigest(query)
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.create_store(storefile_name)
|
109
|
+
store = PStore.new(storefile_name) unless storefile_name.nil?
|
110
|
+
return store
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
data/cache/file_index.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
require 'lore/model'
|
3
|
+
|
4
|
+
Lore.disable_cache
|
5
|
+
|
6
|
+
module Lore
|
7
|
+
module Cache
|
8
|
+
|
9
|
+
class File_Index < Lore::Model
|
10
|
+
context :lore
|
11
|
+
table :file_index, :public
|
12
|
+
primary_key :file_index_id, :file_index_id_seq
|
13
|
+
|
14
|
+
# Return array of cache file names depending
|
15
|
+
# from model
|
16
|
+
def self.for(table_name)
|
17
|
+
select { |i|
|
18
|
+
i.where(i.model == table_name)
|
19
|
+
}.collect { |index|
|
20
|
+
index.file
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.delete_entry(table_name)
|
25
|
+
delete { |i|
|
26
|
+
i.where(i.model == table_name)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Lore.enable_cache
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require 'lore'
|
3
|
+
require 'lore/cache/abstract_entity_cache'
|
4
|
+
require 'mmap'
|
5
|
+
|
6
|
+
module Lore
|
7
|
+
module Cache
|
8
|
+
|
9
|
+
|
10
|
+
# Implementation of entity cache using MMapped PStor files.
|
11
|
+
# Derived from Abstract_Entity_Cache.
|
12
|
+
# Uses Lore::Cache::Cache_Helpers for generating PStor files.
|
13
|
+
class Mmap_Entity_Cache < Abstract_Entity_Cache
|
14
|
+
extend Cache_Helpers
|
15
|
+
|
16
|
+
@@logger = Logger.new('/tmp/lore_cache.log')
|
17
|
+
|
18
|
+
|
19
|
+
def self.flush(accessor)
|
20
|
+
index = accessor.table_name
|
21
|
+
return unless Lore.cache_enabled?
|
22
|
+
Dir.glob("/tmp/lore_cache__#{index}*").each { |cache_file|
|
23
|
+
@@logger.debug('Clearing cache file ' << cache_file)
|
24
|
+
begin
|
25
|
+
File.unlink(cache_file)
|
26
|
+
rescue ::Exception => excep
|
27
|
+
# Another process already killed this file
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.read(accessor, query_string)
|
33
|
+
@@logger.debug('Loading from cache: ' << index_for(query_string))
|
34
|
+
store = Mmap.new(storefile_of(accessor.table_name, query_string))
|
35
|
+
@@logger.debug('STORE: ' << store.inspect)
|
36
|
+
return [] unless store
|
37
|
+
result = Marshal::load(store)
|
38
|
+
return result['dump']
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.create(accessor, query_string, result)
|
42
|
+
storefile = create_mmap(accessor, query_string, result)
|
43
|
+
end
|
44
|
+
def self.create_mmap(accessor, query_string, result)
|
45
|
+
storefile = storefile_of(accessor.table_name, query_string)
|
46
|
+
store = create_store(storefile)
|
47
|
+
store.transaction do
|
48
|
+
store['dump'] = result
|
49
|
+
end
|
50
|
+
@@logger.debug('Creating cache entry for ' << storefile )
|
51
|
+
Mmap.new(storefile)
|
52
|
+
return storefile
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.include?(accessor, query_string)
|
56
|
+
FileTest.exist?(storefile_of(accessor.table_name, query_string))
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.delete(index)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|