sadie 0.0.52 → 0.1.6
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 +7 -0
- data/CHANGELOG +2 -1
- data/README +76 -22
- data/Rakefile +41 -1
- data/TODO +2 -31
- data/bin/sadie +17 -0
- data/bin/sadie_query_server +15 -0
- data/bin/sadie_server +27 -0
- data/bin/sadie_server.rb +23 -0
- data/doc/v2 +161 -0
- data/lib/primer.rb +201 -0
- data/lib/sadie/version.rb +1 -1
- data/lib/sadie_server.rb +59 -0
- data/lib/sadie_session.rb +194 -0
- data/lib/sadie_storage_manager.rb +60 -0
- data/lib/sadie_storage_mechanism.rb +18 -0
- data/lib/storage/memory.rb +24 -0
- data/sadie.gemspec +6 -2
- data/spec/primer.rb +167 -0
- data/spec/sadie_server.rb +39 -0
- data/spec/sadie_server_lib.rb +31 -0
- data/spec/sadie_session.rb +99 -0
- data/spec/storage_manager.rb +58 -0
- data/spec/storage_mechanisms/memory.rb +28 -0
- data/test/v2/test_installation/primers/minimal.rb +5 -0
- data/test/v2/test_installation/primers/onelevel/twolevel/test_subdir.rb +5 -0
- data/test/v2/test_installation/primers/test_after_each.rb +14 -0
- data/test/v2/test_installation/primers/test_after_key.rb +14 -0
- data/test/v2/test_installation/primers/test_before_each.rb +14 -0
- data/test/v2/test_installation/primers/test_before_key.rb +14 -0
- data/test/v2/test_installation/primers/test_expires_after_n_secs.rb +6 -0
- data/test/v2/test_installation/primers/test_expires_on_get.rb +6 -0
- data/test/v2/test_installation/primers/test_refresh.rb +10 -0
- metadata +84 -49
- data/lib/sadie/debug.rb +0 -1
- data/lib/sadie/defaults.rb +0 -14
- data/lib/sadie/primer_plugins/DatabaseConnection.plugin.rb +0 -80
- data/lib/sadie/primer_plugins/IniFile.plugin.rb +0 -23
- data/lib/sadie/primer_plugins/Resource.plugin.rb +0 -7
- data/lib/sadie/primer_plugins/SQLQueryTo2DArray.plugin.rb +0 -39
- data/lib/sadie/primer_plugins/TemplateTextFile.plugin.rb +0 -13
- data/lib/sadie.rb +0 -1315
- data/test/README +0 -9
- data/test/tc_sadie_toplevel.rb +0 -43
- data/test/tc_sadie_twodeep.rb +0 -48
- data/test/test_primers/.gitignore +0 -1
- data/test/test_primers/onedeep/multiresult.res +0 -5
- data/test/test_primers/toplevel.ini +0 -5
- data/test/test_primers/toplevel.somegroup.somekey.each +0 -15
- data/test/test_primers/toplevel_destructonget.res.rb +0 -9
- data/test/test_primers/toplevel_double.oneprime.each +0 -14
- data/test/test_primers/toplevel_double.res.rb +0 -5
- data/test/test_primers/toplevel_single.res.rb +0 -3
- data/test/test_primers/toplevel_testeach.res.rb +0 -4
- data/test/test_primers/two/deep/conf.ini +0 -2
- data/test/test_primers/two/deep/expensive.res +0 -3
- data/test/test_primers/two/deep/test.dbi.conx +0 -4
- data/test/test_primers/two/deep/test_template.txt.tmpl +0 -10
- data/test/test_primers/two/deep/testquery.test.sql2ar +0 -1
- data/test/test_primers/two/deep/testquery.test.sql2ar.each +0 -16
- data/test/test_primers/two/deep/two_results.res +0 -8
data/lib/sadie.rb
DELETED
@@ -1,1315 +0,0 @@
|
|
1
|
-
# this requires the gem: ini
|
2
|
-
require 'rubygems'
|
3
|
-
require "bundler/setup"
|
4
|
-
require 'bundler'
|
5
|
-
Bundler.require(:default)
|
6
|
-
require 'sadie/defaults'
|
7
|
-
require 'sadie/version'
|
8
|
-
require 'erb'
|
9
|
-
|
10
|
-
# ==Description: Sadie
|
11
|
-
# Sadie is a data framework intended to ease the pain of constructing, accessing, and
|
12
|
-
# managing the resources required by large stores of inter-related data. It supports
|
13
|
-
# sessions, lazy, on-demand, one-time evaluation and file-based storage/retrieval
|
14
|
-
# operations for resource-heavy data.
|
15
|
-
#
|
16
|
-
# New types of data primers can be added by calling addPrimerPluginsDirPath with a
|
17
|
-
# directory containing plugin definitions
|
18
|
-
#
|
19
|
-
|
20
|
-
def S( key )
|
21
|
-
instance = Sadie::getCurrentSadieInstance
|
22
|
-
return instance.get( key )
|
23
|
-
end
|
24
|
-
|
25
|
-
class Sadie
|
26
|
-
|
27
|
-
|
28
|
-
BEFORE = 1
|
29
|
-
AFTER = 2
|
30
|
-
EACH = 3
|
31
|
-
|
32
|
-
# ==method: Sadie::getSadieInstance
|
33
|
-
#
|
34
|
-
# returns a new Sadie instance. Options match those of Sadie's constructor method
|
35
|
-
def self.getSadieInstance( options )
|
36
|
-
Sadie.new(options)
|
37
|
-
end
|
38
|
-
|
39
|
-
# ==method: Sadie::setCurrentSadieInstance
|
40
|
-
#
|
41
|
-
# this is called just prior to calling a primer plugin to handle a primer to provide
|
42
|
-
# a current sadie instance for Sadie::getCurrentSadieInstance to return
|
43
|
-
def self.setCurrentSadieInstance ( instance )
|
44
|
-
@current_sadie_instance = instance
|
45
|
-
end
|
46
|
-
|
47
|
-
# ==method: Sadie::getCurrentSadieInstance
|
48
|
-
#
|
49
|
-
# called by plugin handlers to get access to the current Sadie instance
|
50
|
-
def self.getCurrentSadieInstance
|
51
|
-
@current_sadie_instance
|
52
|
-
end
|
53
|
-
|
54
|
-
# ==method: Sadie::Prime
|
55
|
-
#
|
56
|
-
# called by the .res files to register the keys the .res will prime for
|
57
|
-
#
|
58
|
-
# accepts as an argument a hash and a block. The hash must include the key:
|
59
|
-
# 'provides' and it must define an array
|
60
|
-
# of keys that the calling resource (.res) file will have provided after the block is
|
61
|
-
# evaluated
|
62
|
-
def self.prime ( primer_definition, &block )
|
63
|
-
current_sadie_instance = Sadie::getCurrentSadieInstance
|
64
|
-
current_sadie_instance.prime( primer_definition, &block )
|
65
|
-
end
|
66
|
-
|
67
|
-
# ==method: Sadie::eacher
|
68
|
-
#
|
69
|
-
# called by eacher files to hook into priming operations and calls to set method
|
70
|
-
def self.eacher( eacher_params, &block )
|
71
|
-
current_sadie_instance = Sadie::getCurrentSadieInstance
|
72
|
-
current_sadie_instance.eacher( eacher_params, &block )
|
73
|
-
end
|
74
|
-
|
75
|
-
# ==method: Sadie::eacherFrame
|
76
|
-
#
|
77
|
-
# eacherFrame is called by get and set methods and is available to primer plugins
|
78
|
-
# as well. when eacher primer files call eacher, they are registering code to
|
79
|
-
# be run either BEFORE or AFTER the key/value store is set. Note that the BEFORE
|
80
|
-
# eacherFrame runs just before priming when a primer exists and just before set
|
81
|
-
# for keys set without primers. EACH eacherFrames are called as the data is being
|
82
|
-
# assembled, if such a thing makes sense. The included SQLQueryTo2DArray plugin
|
83
|
-
# tries to call any eacherFrame with an EACH occurAt parameter with each row and
|
84
|
-
# the registering an EACH eacher might make sense for any number of incrementally
|
85
|
-
# built data types
|
86
|
-
#
|
87
|
-
def self.eacherFrame( sadiekey, occur_at, param=nil )
|
88
|
-
current_sadie_instance = Sadie::getCurrentSadieInstance
|
89
|
-
current_sadie_instance.eacherFrame( sadiekey, occur_at, param )
|
90
|
-
end
|
91
|
-
|
92
|
-
# ==method: Sadie::registerPrimerPlugin
|
93
|
-
#
|
94
|
-
# this method is called in the .plugin.rb files to register new plugin types
|
95
|
-
#
|
96
|
-
def self.registerPrimerPlugin ( arghash, &block )
|
97
|
-
current_sadie_instance = Sadie::getCurrentSadieInstance
|
98
|
-
current_sadie_instance.registerPrimerPlugin( arghash, &block )
|
99
|
-
end
|
100
|
-
|
101
|
-
# ==method: Sadie::iniFileToHash
|
102
|
-
#
|
103
|
-
# utility class method. accepts a filepath. digests ini file and returns hash of hashes.
|
104
|
-
#
|
105
|
-
def self.iniFileToHash ( filepath )
|
106
|
-
section = nil
|
107
|
-
ret = Hash.new
|
108
|
-
File.open( filepath, "r" ).each do |f|
|
109
|
-
f.each_line do |line|
|
110
|
-
next if line.match(/^;/) # skip comments
|
111
|
-
if matches = line.match(/\[([^\]]+)\]/)
|
112
|
-
section = matches[1]
|
113
|
-
ret[section] = Hash.new
|
114
|
-
elsif matches = line.match(/^\s*([^\s\=]+)\s*\=\s*([^\s]+.*)\s*$/)
|
115
|
-
key = matches[1]
|
116
|
-
value = matches[2]
|
117
|
-
|
118
|
-
# strip quotes
|
119
|
-
if qmatches = value.match(/[\'\"](.*)[\'\"]/)
|
120
|
-
value = qmatches[1]
|
121
|
-
end
|
122
|
-
|
123
|
-
if defined? section
|
124
|
-
ret[section][key] = value
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
ret.empty? and return nil
|
130
|
-
return ret
|
131
|
-
end
|
132
|
-
|
133
|
-
# ==method: Sadie::templatedFileToString
|
134
|
-
#
|
135
|
-
# utility class method. accepts a filepath. digests a template and returns
|
136
|
-
# a string containing processed template output
|
137
|
-
#
|
138
|
-
def self.templatedFileToString( filepath, binding=nil )
|
139
|
-
|
140
|
-
template = ERB.new File.new(filepath).read
|
141
|
-
current_sadie_instance = Sadie::getCurrentSadieInstance
|
142
|
-
if defined? binding
|
143
|
-
template.result binding
|
144
|
-
else
|
145
|
-
template.result self
|
146
|
-
end
|
147
|
-
|
148
|
-
end
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
# ==method: constructor
|
153
|
-
# options can include any kay, value pairs but the following key values bear mention:
|
154
|
-
# REQUIRED
|
155
|
-
#
|
156
|
-
# sadie.sessions_dirpath
|
157
|
-
# or
|
158
|
-
# sadie.session_id
|
159
|
-
# or
|
160
|
-
# sadie.session_filepath <- this is probably a bad call, use with caution
|
161
|
-
#
|
162
|
-
# and
|
163
|
-
#
|
164
|
-
# sadie.primers_dirpath
|
165
|
-
#
|
166
|
-
# and
|
167
|
-
# sadie.primer_plugins_dirpath
|
168
|
-
def initialize( options )
|
169
|
-
|
170
|
-
# check instance sanity
|
171
|
-
_checkInstanceSanity
|
172
|
-
_checkClassSanity
|
173
|
-
|
174
|
-
Sadie::setCurrentSadieInstance( self )
|
175
|
-
|
176
|
-
# internalize defaults to shortterm
|
177
|
-
DEFAULTS.each do |key, value|
|
178
|
-
_set( key, value )
|
179
|
-
end
|
180
|
-
|
181
|
-
# iterate over constructor args, but do primers_dirpath last since it
|
182
|
-
# causes a call to initializePrimers
|
183
|
-
options.each do |key, value|
|
184
|
-
set( key, value )
|
185
|
-
end
|
186
|
-
|
187
|
-
# if a path to a session is given, init using session file
|
188
|
-
if options.has_key?( "sadie.session_filepath" )
|
189
|
-
set( "sadie.session_filepath", options["sadie.session_filepath"] )
|
190
|
-
_initializeWithSessionFilePath( get("sadie.session_filepath") )
|
191
|
-
elsif options.has_key?( "sadie.session_id" )
|
192
|
-
set( "sadie.session_id", options["sadie.session_id"] )
|
193
|
-
_initializeWithSessionId( get( "sadie.session_id" ) )
|
194
|
-
else
|
195
|
-
set( "sadie.session_id", _generateNewSessionId )
|
196
|
-
end
|
197
|
-
|
198
|
-
# add the default sadie plugins dir
|
199
|
-
plugins_dirpath = "lib/sadie/primer_plugins" # for dev
|
200
|
-
if ! File.exists? plugins_dirpath
|
201
|
-
plugins_dirpath = File.join(
|
202
|
-
ENV['GEM_HOME'],
|
203
|
-
"gems/sadie-#{Sadie::VERSION}",
|
204
|
-
"lib/sadie/primer_plugins"
|
205
|
-
)
|
206
|
-
|
207
|
-
if ! File.exists? plugins_dirpath
|
208
|
-
plugins_dirpath = File.expand_path "../sadie/lib/sadie/primer_plugins"
|
209
|
-
end
|
210
|
-
|
211
|
-
end
|
212
|
-
addPrimerPluginsDirPath plugins_dirpath
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
# ==method: setDebugLevel
|
217
|
-
#
|
218
|
-
# from 0 to 10 with 0 being no debugging messages and 10 being all debugging messages
|
219
|
-
#
|
220
|
-
def setDebugLevel( lvl )
|
221
|
-
lvl > 10 and lvl = 10
|
222
|
-
lvl < 0 and lvl = 0
|
223
|
-
@debug_level = lvl.to_i
|
224
|
-
end
|
225
|
-
|
226
|
-
# ==method: getDebugLevel
|
227
|
-
#
|
228
|
-
# return current debug level (default is 10)
|
229
|
-
#
|
230
|
-
def getDebugLevel
|
231
|
-
defined? @debug_level or @debug_level = 10
|
232
|
-
@debug_level
|
233
|
-
end
|
234
|
-
|
235
|
-
# ==method: getDebugLevel
|
236
|
-
#
|
237
|
-
# will print a debugging message if the current debug level is greater than
|
238
|
-
# or equal to lvl
|
239
|
-
#
|
240
|
-
def debug!( lvl, msg )
|
241
|
-
defined? @debug_level or @debug_level = 10
|
242
|
-
(lvl <= @debug_level) and puts "SADIE(#{lvl}): #{msg}"
|
243
|
-
end
|
244
|
-
|
245
|
-
# ==method: eacher
|
246
|
-
#
|
247
|
-
# ( usually this will be called by the class method...it looks better )
|
248
|
-
#
|
249
|
-
# see class method eacher for an explanation
|
250
|
-
#
|
251
|
-
def eacher( params, &block )
|
252
|
-
filepath = getCurrentPrimerFilepath
|
253
|
-
key_prefix = getCurrentPrimerKeyPrefix
|
254
|
-
occur_at = params[:when]
|
255
|
-
|
256
|
-
# gen sadie key
|
257
|
-
basefilename = filepath.gsub(/^.*\//,"")
|
258
|
-
sadiekey = key_prefix + "." + basefilename.gsub(/\.each(?:\..*)*$/,"")
|
259
|
-
sadiekey = sadiekey.gsub( /^\.+/,"" )
|
260
|
-
if params.has_key? :sadiekey
|
261
|
-
sadiekey = params[:sadiekey]
|
262
|
-
end
|
263
|
-
|
264
|
-
|
265
|
-
whichEacherFrame != Sadie::EACH and debug! 10, "whicheacherframe: #{whichEacherFrame}, occur_at: #{occur_at}"
|
266
|
-
|
267
|
-
if midEacherInit?
|
268
|
-
|
269
|
-
debug! 10, "in mid eacher init (#{sadiekey})"
|
270
|
-
|
271
|
-
memorizeEacherFileLocation( sadiekey, filepath )
|
272
|
-
|
273
|
-
if params.has_key? :provides
|
274
|
-
|
275
|
-
# make sure we're passing an array
|
276
|
-
provide_array = params[:provides]
|
277
|
-
provide_array.respond_to? "each" or provide_array = [provide_array]
|
278
|
-
|
279
|
-
# tell sadie that the sadiekey primer also provides everything in the provide array
|
280
|
-
setEachersProvidedByPrimer( sadiekey, provide_array )
|
281
|
-
|
282
|
-
end
|
283
|
-
|
284
|
-
elsif whichEacherFrame == occur_at
|
285
|
-
|
286
|
-
# bugfix: running eachers that aren't supposed to be run because they're
|
287
|
-
# in the same eacher file
|
288
|
-
#puts "sadiekey: #{sadiekey}, getEacherKey: #{getEacherKey}"
|
289
|
-
#return if sadiekey != getEacherKey
|
290
|
-
|
291
|
-
occur_at != Sadie::EACH and debug! 10, "pre-yield for skey: #{sadiekey}, #{occur_at}"
|
292
|
-
|
293
|
-
if block.arity == 0
|
294
|
-
yield self
|
295
|
-
else
|
296
|
-
yield self, getEacherParam
|
297
|
-
end
|
298
|
-
|
299
|
-
occur_at != Sadie::EACH and debug! 10, "post-yield for skey: #{sadiekey}, #{occur_at}"
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
# ==method: eacherFrame
|
304
|
-
#
|
305
|
-
# ( usually this will be called by the class method...it looks better )
|
306
|
-
#
|
307
|
-
# see class method eacherFrame for an explanation
|
308
|
-
#
|
309
|
-
def eacherFrame( sadiekey, occur_at, param=nil )
|
310
|
-
|
311
|
-
occur_at != Sadie::EACH and debug! 8, "eacherFrame(#{occur_at}): #{sadiekey}"
|
312
|
-
|
313
|
-
setEacherFrame( occur_at )
|
314
|
-
defined? param and setEacherParam( param )
|
315
|
-
setEacherKey sadiekey
|
316
|
-
if filepaths = eacherFilepaths( sadiekey )
|
317
|
-
filepaths.each do |filepath|
|
318
|
-
occur_at != Sadie::EACH and debug! 8, "eacher frame loading: #{filepath} for sadiekey: #{sadiekey}"
|
319
|
-
load filepath
|
320
|
-
end
|
321
|
-
end
|
322
|
-
unsetEacherParam
|
323
|
-
unsetEacherFrame
|
324
|
-
unsetEacherKey
|
325
|
-
end
|
326
|
-
|
327
|
-
|
328
|
-
# ==method: addPrimerPluginsDirPath
|
329
|
-
#
|
330
|
-
# addPrimerPluginsDirPath adds a directory which will be scanned for plugins to
|
331
|
-
# register just before initializePrimers looks for primers to initialize
|
332
|
-
#
|
333
|
-
def addPrimerPluginsDirPath( path )
|
334
|
-
|
335
|
-
exppath = File.expand_path(path)
|
336
|
-
|
337
|
-
# add the path to the system load path
|
338
|
-
$LOAD_PATH.include?(exppath) \
|
339
|
-
or $LOAD_PATH.unshift(exppath)
|
340
|
-
|
341
|
-
# add the path to the pluginsdir array
|
342
|
-
defined? @plugins_dir_paths \
|
343
|
-
or @plugins_dir_paths = Array.new
|
344
|
-
@plugins_dir_paths.include?(exppath) \
|
345
|
-
or @plugins_dir_paths.unshift(exppath)
|
346
|
-
|
347
|
-
@primer_plugins_initialized = nil
|
348
|
-
return self
|
349
|
-
end
|
350
|
-
|
351
|
-
# ==method: prime
|
352
|
-
#
|
353
|
-
# ( usually this will be called by the class method...it looks better )
|
354
|
-
#
|
355
|
-
# see class method prime for an explanation
|
356
|
-
#
|
357
|
-
def prime( primer_definition, &block )
|
358
|
-
# validate params
|
359
|
-
defined? primer_definition \
|
360
|
-
or raise "Prime called without parameters"
|
361
|
-
primer_definition.is_a? Hash \
|
362
|
-
or raise "Prime called without hash parameters"
|
363
|
-
defined? primer_definition["provides"] \
|
364
|
-
or raise "Prime called without provides parameter"
|
365
|
-
|
366
|
-
# if initializing primers, just remember how to get back to the primer later,
|
367
|
-
# otherwise, prime
|
368
|
-
if midPrimerInit?
|
369
|
-
|
370
|
-
# mid primer init, just memorize primer location
|
371
|
-
memorizePrimerLocation( @mid_primer_filepath, getCurrentPrimerPluginFilepath, primer_definition["provides"] )
|
372
|
-
else
|
373
|
-
|
374
|
-
# run code block with the current sadie instance
|
375
|
-
block.call( self )
|
376
|
-
|
377
|
-
# loop thru all primer provides, ensuring each primed
|
378
|
-
current_primer_filepath = getCurrentPrimerFilepath
|
379
|
-
primer_definition["provides"].each do | key |
|
380
|
-
|
381
|
-
# skip blank lines
|
382
|
-
next if key.match /^\s*$/
|
383
|
-
|
384
|
-
# key primed or raise error
|
385
|
-
primed? key \
|
386
|
-
or raise "primer definition file: #{current_primer_filepath} was supposed to define #{key}, but did not"
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
end
|
391
|
-
|
392
|
-
# ==method: registerPrimerPlugin
|
393
|
-
#
|
394
|
-
# ( usually this will be called by the class method...it looks better )
|
395
|
-
#
|
396
|
-
# see class method registerPrimerPlugin for an explanation
|
397
|
-
#
|
398
|
-
def registerPrimerPlugin ( arghash, &block )
|
399
|
-
|
400
|
-
# if mid plugin init is set, we're registering the plugin
|
401
|
-
# init mode, just store arghash info
|
402
|
-
accepts_block = arghash.has_key?( "accepts-block" ) && arghash["accepts-block"] ? true : false
|
403
|
-
prime_on_init = arghash.has_key?( "prime-on-init" ) && arghash["prime-on-init"] ? true : false
|
404
|
-
|
405
|
-
# if mid plugin init, register the plugin params with the match
|
406
|
-
if midPluginInit?
|
407
|
-
|
408
|
-
regPluginMatch( arghash["match"], @mid_plugin_filepath, accepts_block, prime_on_init )
|
409
|
-
|
410
|
-
# midplugininit returned false, we're actually in the process of either initializing
|
411
|
-
# a primer or actually priming
|
412
|
-
else
|
413
|
-
yield self, getCurrentPrimerKeyPrefix, getCurrentPrimerFilepath
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
# ==method: get
|
420
|
-
#
|
421
|
-
# a standard getter which primes the unprimed and recalls "expensive" facts from files
|
422
|
-
# completely behind-the-scenes as directed by the resource (.res) files
|
423
|
-
def get( k )
|
424
|
-
|
425
|
-
debug! 10, "get(#{k})"
|
426
|
-
|
427
|
-
defined? @eacher_frame_redirect or @eacher_frame_redirect = Hash.new
|
428
|
-
|
429
|
-
if ! isset?( k )
|
430
|
-
debug! 10, "#{k} is not set"
|
431
|
-
if isEacherKey?( k )
|
432
|
-
debug! 10, "sadiekey: #[k} is eacher, fetching: #{@eacher_frame_redirect[k]}"
|
433
|
-
get @eacher_frame_redirect[k]
|
434
|
-
|
435
|
-
elsif primeable?( k )
|
436
|
-
|
437
|
-
debug! 10, "calling eacher from get method for #{k}"
|
438
|
-
setUnbalancedEacher k
|
439
|
-
Sadie::eacherFrame( k, BEFORE )
|
440
|
-
|
441
|
-
# prime if not yet primed
|
442
|
-
primed?( k ) or _prime( k )
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
return _recallExpensive( k ) if expensive?( k )
|
447
|
-
|
448
|
-
# if it's already set, return known answer
|
449
|
-
if isset?( k )
|
450
|
-
|
451
|
-
# _get the return value
|
452
|
-
return_value = _get( k )
|
453
|
-
|
454
|
-
# unset and unprime if destructOnGet?
|
455
|
-
destroyOnGet?( k ) \
|
456
|
-
and destroy! k
|
457
|
-
|
458
|
-
return return_value
|
459
|
-
end
|
460
|
-
|
461
|
-
end
|
462
|
-
|
463
|
-
# ==method: output
|
464
|
-
#
|
465
|
-
# an alias for get. intended for use with primers that produce an output beyond their return value
|
466
|
-
def output( k )
|
467
|
-
return get( k )
|
468
|
-
end
|
469
|
-
|
470
|
-
# ==method: isset?
|
471
|
-
#
|
472
|
-
# returns true if sadie has a value for the key
|
473
|
-
def isset?( key )
|
474
|
-
return true if @shortterm.has_key?( key )
|
475
|
-
return true if expensive?( key )
|
476
|
-
false
|
477
|
-
end
|
478
|
-
|
479
|
-
# ==method: setDestroyOnGet
|
480
|
-
#
|
481
|
-
# key value will go away and key will be unprimed and unset after next get
|
482
|
-
#
|
483
|
-
# NOTE: this doesn't make sense with keys that were set via setExpensive
|
484
|
-
# so it can be set, but nothing's going to happen differently
|
485
|
-
def setDestroyOnGet( key, turnon=true )
|
486
|
-
if ( turnon )
|
487
|
-
@flag_destroyonget["#{key}"] = true
|
488
|
-
return true
|
489
|
-
end
|
490
|
-
@flag_destroyonget.has_key?( key ) \
|
491
|
-
and @flag_destroyonget.delete( key )
|
492
|
-
end
|
493
|
-
|
494
|
-
# ==method: destroy!
|
495
|
-
#
|
496
|
-
# remove the key from sadie
|
497
|
-
def destroy! ( key )
|
498
|
-
unset( key )
|
499
|
-
primed?( key ) and unprime( key )
|
500
|
-
end
|
501
|
-
|
502
|
-
# ==method: destroyOnGet?
|
503
|
-
#
|
504
|
-
# returns true if the destructOnGet flag is set for the key
|
505
|
-
def destroyOnGet?( key )
|
506
|
-
( @flag_destroyonget.has_key?( key ) && @flag_destroyonget["#{key}"] )
|
507
|
-
end
|
508
|
-
|
509
|
-
# ==method: set
|
510
|
-
# alias for setCheap(k,v)
|
511
|
-
def set( k, v )
|
512
|
-
setCheap( k, v )
|
513
|
-
end
|
514
|
-
|
515
|
-
# ==method: setCheap
|
516
|
-
#
|
517
|
-
# the cheap setter. key, value pairs stored via this method are kept in memory
|
518
|
-
def setCheap( k, v )
|
519
|
-
|
520
|
-
# debug! 8, "setting cheap: [#{k},#{v}]"
|
521
|
-
Sadie::eacherFrame( k, BEFORE ) if ! eacherUnbalanced?( k )
|
522
|
-
setUnbalancedEacher k
|
523
|
-
|
524
|
-
if getDebugLevel == 10
|
525
|
-
debug! 10, "dumping value:"
|
526
|
-
pp v
|
527
|
-
end
|
528
|
-
|
529
|
-
# set it, mark not expensive and primed
|
530
|
-
_set( k, v )
|
531
|
-
_expensive( k, false )
|
532
|
-
_primed( k, true )
|
533
|
-
|
534
|
-
Sadie::eacherFrame( k, AFTER, v )
|
535
|
-
clearUnbalancedEacher k
|
536
|
-
|
537
|
-
end
|
538
|
-
|
539
|
-
# ==method: setExpensive
|
540
|
-
#
|
541
|
-
# the expensive setter. key, value pairs stored via this method are not kept in memory
|
542
|
-
# but are stored to file and recalled as needed
|
543
|
-
def setExpensive(k,v)
|
544
|
-
|
545
|
-
debug! 9, "setting expensive: #{k}"
|
546
|
-
Sadie::eacherFrame( k, BEFORE ) if ! eacherUnbalanced?( k )
|
547
|
-
setUnbalancedEacher k
|
548
|
-
|
549
|
-
|
550
|
-
expensive_filepath = _computeExpensiveFilepath( k )
|
551
|
-
serialized_value = Marshal::dump( v )
|
552
|
-
|
553
|
-
File.exist? File.dirname( expensive_filepath ) \
|
554
|
-
or Dir.mkdir File.dirname( expensive_filepath )
|
555
|
-
|
556
|
-
File.open(expensive_filepath, 'w') { |f|
|
557
|
-
f.write( serialized_value )
|
558
|
-
}
|
559
|
-
_expensive( k, true )
|
560
|
-
_primed( k, true )
|
561
|
-
|
562
|
-
Sadie::eacherFrame( k, AFTER, v )
|
563
|
-
clearUnbalancedEacher k
|
564
|
-
end
|
565
|
-
|
566
|
-
|
567
|
-
# ==method: save
|
568
|
-
#
|
569
|
-
# serialize to session file
|
570
|
-
def save
|
571
|
-
session_id = get("sadie.session_id")
|
572
|
-
session_filepath = File.expand_path( "session."+session_id, get( "sadie.sessions_dirpath" ) )
|
573
|
-
serialized_value = Marshal::dump( [ @shortterm, @flag_primed, @flag_expensive ] )
|
574
|
-
File.open(session_filepath, 'w') { |f|
|
575
|
-
f.write( serialized_value )
|
576
|
-
}
|
577
|
-
return session_id
|
578
|
-
end
|
579
|
-
|
580
|
-
# ==method: revert!
|
581
|
-
#
|
582
|
-
# return to last saved state
|
583
|
-
#
|
584
|
-
def revert!
|
585
|
-
|
586
|
-
@shortterm = {
|
587
|
-
"sadie.session_id" => get( "sadie.session_id" ),
|
588
|
-
"sadie.sessions_dirpath" => get( "sadie.sessions_dirpath" )
|
589
|
-
}
|
590
|
-
|
591
|
-
_initializeWithSessionId( get( "sadie.session_id" ) )
|
592
|
-
end
|
593
|
-
|
594
|
-
# ==method: initializePrimers
|
595
|
-
#
|
596
|
-
# call this method only after registering all the plugin directories and setting the
|
597
|
-
# appropriate session and primer directory paths. after this is called, the key/val
|
598
|
-
# pairs will be available via get
|
599
|
-
#
|
600
|
-
def initializePrimers
|
601
|
-
|
602
|
-
Sadie::setCurrentSadieInstance( self )
|
603
|
-
|
604
|
-
# make sure primer plugins have been initialized
|
605
|
-
primerPluginsInitialized? \
|
606
|
-
or initializePrimerPlugins
|
607
|
-
|
608
|
-
eachersInitialized? \
|
609
|
-
or initializeEachers
|
610
|
-
|
611
|
-
primers_dirpath = get( "sadie.primers_dirpath" ) \
|
612
|
-
or raise "sadie.primers_dirpath not set"
|
613
|
-
|
614
|
-
return true if primersInitialized? primers_dirpath
|
615
|
-
|
616
|
-
debug! 1, "Initializing primers..."
|
617
|
-
initializePrimerDirectory( "", primers_dirpath )
|
618
|
-
debug! 1, "...finished initializing primers."
|
619
|
-
|
620
|
-
@flag_primed[primers_dirpath] = true
|
621
|
-
end
|
622
|
-
|
623
|
-
def getEacherKey
|
624
|
-
return nil if ! defined? @eacher_key
|
625
|
-
@eacher_key.last
|
626
|
-
end
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
# ------------------------------------------------------------------------------------------------
|
631
|
-
# ------------------------------------------------------------------------------------------------
|
632
|
-
|
633
|
-
private
|
634
|
-
|
635
|
-
def setUnbalancedEacher( k )
|
636
|
-
debug! 10, "setting eacher unbalanced: #{k}"
|
637
|
-
defined? @eacher_unbalanced or @eacher_unbalanced = Hash.new
|
638
|
-
@eacher_unbalanced[k] = true
|
639
|
-
end
|
640
|
-
|
641
|
-
def clearUnbalancedEacher( k )
|
642
|
-
debug! 10, "clearing eacher unbalanced: #{k}"
|
643
|
-
@eacher_unbalanced[k] = false if defined? @eacher_unbalanced
|
644
|
-
end
|
645
|
-
|
646
|
-
def eacherUnbalanced?( k )
|
647
|
-
return false if ! defined? @eacher_unbalanced
|
648
|
-
return false if ! @eacher_unbalanced.has_key?( k )
|
649
|
-
return @eacher_unbalanced[k]
|
650
|
-
end
|
651
|
-
|
652
|
-
def cheap?( k )
|
653
|
-
! expensive? ( k )
|
654
|
-
end
|
655
|
-
|
656
|
-
# ==method: primed?
|
657
|
-
#
|
658
|
-
# INTERNAL: this method should only be called the the class method, Prime
|
659
|
-
#
|
660
|
-
def expensive?( k )
|
661
|
-
@flag_expensive.has_key?( k ) or return false;
|
662
|
-
@flag_expensive["#{k}"] \
|
663
|
-
and return true
|
664
|
-
return false
|
665
|
-
end
|
666
|
-
|
667
|
-
|
668
|
-
# == initialize eachers
|
669
|
-
#
|
670
|
-
# register all the eachers
|
671
|
-
#
|
672
|
-
# called by initializePrimers so it's not necessary to call this separate from that
|
673
|
-
def initializeEachers
|
674
|
-
|
675
|
-
primers_dirpath = get( "sadie.primers_dirpath" ) \
|
676
|
-
or raise "sadie.primers_dirpath not set"
|
677
|
-
|
678
|
-
puts "Initializing eachers..."
|
679
|
-
setEacherInit
|
680
|
-
initializeEacherDirectory( "", primers_dirpath )
|
681
|
-
clearEacherInit
|
682
|
-
puts "...finished initializing eachers."
|
683
|
-
|
684
|
-
|
685
|
-
@eachers_initialized = true
|
686
|
-
end
|
687
|
-
|
688
|
-
def initializeEacherDirectory( key_prefix, current_dirpath )
|
689
|
-
|
690
|
-
debug! 3, "initializing eacher directory: #{current_dirpath}"
|
691
|
-
Dir.foreach( current_dirpath ) do |filename|
|
692
|
-
|
693
|
-
# skip the dit dirs
|
694
|
-
next if filename.eql?(".") || filename.eql?("..") || filename =~ /\~$/
|
695
|
-
|
696
|
-
|
697
|
-
filepath = File.expand_path( filename, current_dirpath )
|
698
|
-
|
699
|
-
if File.directory? filepath
|
700
|
-
new_key_prefix = key_prefix + '.' + filename
|
701
|
-
new_key_prefix = new_key_prefix.gsub(/^\.+/,"")
|
702
|
-
initializeEacherDirectory( new_key_prefix, filepath )
|
703
|
-
else
|
704
|
-
if filename =~ /\.each(?:\..*)*$/
|
705
|
-
initializeEacherFile( key_prefix, filepath )
|
706
|
-
end
|
707
|
-
end
|
708
|
-
end
|
709
|
-
end
|
710
|
-
|
711
|
-
def initializeEacherFile( key_prefix, filepath )
|
712
|
-
debug! 8, "initializing eacher file (#{key_prefix}): #{filepath}"
|
713
|
-
setCurrentPrimerFilepath filepath
|
714
|
-
setCurrentPrimerKeyPrefix key_prefix
|
715
|
-
load filepath
|
716
|
-
end
|
717
|
-
|
718
|
-
def eachersInitialized?
|
719
|
-
defined? @eachers_initialized or return false
|
720
|
-
@eachers_initialized and return true
|
721
|
-
return false
|
722
|
-
end
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
def whichEacherFrame
|
728
|
-
return nil if ! defined? @eacher_frame
|
729
|
-
@eacher_frame.last
|
730
|
-
end
|
731
|
-
|
732
|
-
def setEacherFrame( f )
|
733
|
-
defined? @eacher_frame or @eacher_frame = Array.new
|
734
|
-
@eacher_frame.push f
|
735
|
-
end
|
736
|
-
|
737
|
-
def unsetEacherFrame
|
738
|
-
if defined? @eacher_frame
|
739
|
-
@eacher_frame.pop
|
740
|
-
end
|
741
|
-
end
|
742
|
-
|
743
|
-
def setEacherParam( p )
|
744
|
-
defined? @eacher_param or @eacher_param = Array.new
|
745
|
-
@eacher_param.push p
|
746
|
-
end
|
747
|
-
|
748
|
-
def unsetEacherParam
|
749
|
-
if defined? @eacher_param
|
750
|
-
@eacher_param.pop
|
751
|
-
end
|
752
|
-
end
|
753
|
-
|
754
|
-
def getEacherParam
|
755
|
-
return nil if ! defined? @eacher_param
|
756
|
-
@eacher_param.last
|
757
|
-
end
|
758
|
-
|
759
|
-
def setEacherKey( k )
|
760
|
-
defined? @eacher_key or @eacher_key = Array.new
|
761
|
-
@eacher_key.push k
|
762
|
-
end
|
763
|
-
|
764
|
-
def unsetEacherKey
|
765
|
-
if defined? @eacher_key
|
766
|
-
@eacher_key.pop
|
767
|
-
end
|
768
|
-
end
|
769
|
-
|
770
|
-
|
771
|
-
def isEacherKey?( key )
|
772
|
-
|
773
|
-
defined? @eacher_frame_redirect or return false
|
774
|
-
@eacher_frame_redirect.has_key? key or return false
|
775
|
-
return true
|
776
|
-
end
|
777
|
-
|
778
|
-
def getEacherDependency( key )
|
779
|
-
defined? @eacher_frame_redirect or return nil
|
780
|
-
@eacher_frame_redirect.has_key? key or return nil
|
781
|
-
@eacher_frame_redirect[key]
|
782
|
-
end
|
783
|
-
|
784
|
-
def getEachersProvidedByPrimer( sadiekey )
|
785
|
-
defined? @eachers_provided or return nil
|
786
|
-
@eachers_provided.has_key? sadiekey or return nil
|
787
|
-
@eachers_provided[sadiekey]
|
788
|
-
end
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
def eacherFilepaths( sadiekey )
|
793
|
-
defined? @eacher_filepaths or return nil
|
794
|
-
@eacher_filepaths.has_key? sadiekey or return nil
|
795
|
-
@eacher_filepaths[sadiekey]
|
796
|
-
end
|
797
|
-
|
798
|
-
def midEacherInit?
|
799
|
-
defined? @eacher_init or return false
|
800
|
-
@eacher_init or return false
|
801
|
-
true
|
802
|
-
end
|
803
|
-
|
804
|
-
def setEacherInit
|
805
|
-
@eacher_init = true
|
806
|
-
end
|
807
|
-
|
808
|
-
def clearEacherInit
|
809
|
-
@eacher_init = nil
|
810
|
-
end
|
811
|
-
|
812
|
-
|
813
|
-
def setEachersProvidedByPrimer( sadiekey, providers )
|
814
|
-
|
815
|
-
# record reverse map for use by eacherFrame
|
816
|
-
defined? @eacher_frame_redirect \
|
817
|
-
or @eacher_frame_redirect = Hash.new
|
818
|
-
providers.each do |provider|
|
819
|
-
debug! 10, "setting provider reverse map for #{provider} to #{sadiekey}"
|
820
|
-
@eacher_frame_redirect[provider] = sadiekey
|
821
|
-
end
|
822
|
-
|
823
|
-
defined? @eachers_provided or @eachers_provided = Hash.new
|
824
|
-
if @eachers_provided.has_key? sadiekey
|
825
|
-
@eachers_provided[sadiekey] = @eachers_provided[sadiekey].concat( providers )
|
826
|
-
else
|
827
|
-
@eachers_provided[sadiekey] = providers
|
828
|
-
end
|
829
|
-
end
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
def memorizeEacherFileLocation( sadiekey, filepath )
|
834
|
-
debug! 8, "memorizing eacher file location: #{filepath} for #{sadiekey}"
|
835
|
-
# store the file path
|
836
|
-
defined? @eacher_filepaths or @eacher_filepaths = Hash.new
|
837
|
-
if ! @eacher_filepaths.has_key? sadiekey
|
838
|
-
@eacher_filepaths[sadiekey] = [filepath]
|
839
|
-
elsif ! @eacher_filepaths[sadiekey].include? filepath
|
840
|
-
@eacher_filepaths[sadiekey].push filepath
|
841
|
-
end
|
842
|
-
end
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
# ==method: unprime
|
847
|
-
# unprimes k. Note that this does not unset the value, so
|
848
|
-
# get(key) will continue to return whatever it otherwise would have.
|
849
|
-
# run unset as well to have the primer run again.
|
850
|
-
def unprime( key )
|
851
|
-
_primed( key, false )
|
852
|
-
end
|
853
|
-
|
854
|
-
# ==method: primed?
|
855
|
-
#
|
856
|
-
# INTERNAL: this method should only be called the the class method, Prime
|
857
|
-
#
|
858
|
-
def primed?( k )
|
859
|
-
|
860
|
-
isset?( k ) and return true
|
861
|
-
|
862
|
-
@flag_primed.has_key?( k ) \
|
863
|
-
or return false
|
864
|
-
@flag_primed["#{k}"] \
|
865
|
-
and return true
|
866
|
-
return false
|
867
|
-
end
|
868
|
-
|
869
|
-
# direct access getter for shortterm memory
|
870
|
-
def _get( key )
|
871
|
-
value = @shortterm["#{key}"]
|
872
|
-
return value
|
873
|
-
end
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
def primerPluginRegistered?( filename )
|
878
|
-
|
879
|
-
@primer_plugin_lookup.each do | plugin_array |
|
880
|
-
re, path,accepts_block = plugin_array
|
881
|
-
re.match( filename ) \
|
882
|
-
and return true
|
883
|
-
end
|
884
|
-
return false;
|
885
|
-
end
|
886
|
-
|
887
|
-
def currentPrimerPluginAcceptsBlock( accepts )
|
888
|
-
@primer_plugin_accepts_block = accepts
|
889
|
-
end
|
890
|
-
|
891
|
-
def currentPrimerPluginAcceptsBlock?
|
892
|
-
@primer_plugin_accepts_block
|
893
|
-
end
|
894
|
-
|
895
|
-
def currentPrimerPluginPrimeOnInit( prime_on_init )
|
896
|
-
@primer_plugin_prime_on_init = prime_on_init
|
897
|
-
end
|
898
|
-
|
899
|
-
def currentPrimerPluginPrimeOnInit?
|
900
|
-
@primer_plugin_prime_on_init
|
901
|
-
end
|
902
|
-
|
903
|
-
def setMidPluginInit( filepath )
|
904
|
-
@mid_plugin_initialization = true
|
905
|
-
@mid_plugin_filepath = filepath
|
906
|
-
end
|
907
|
-
|
908
|
-
def unsetMidPluginInit
|
909
|
-
@mid_plugin_initialization = false
|
910
|
-
end
|
911
|
-
|
912
|
-
def midPluginInit?
|
913
|
-
@mid_plugin_initialization
|
914
|
-
end
|
915
|
-
|
916
|
-
def regPluginMatch ( regexp, filepath, accepts_block, prime_on_init )
|
917
|
-
@primer_plugin_lookup.push( [ regexp, filepath, accepts_block, prime_on_init ] )
|
918
|
-
end
|
919
|
-
|
920
|
-
def primerPluginsInitialized?
|
921
|
-
@primer_plugins_initialized
|
922
|
-
end
|
923
|
-
|
924
|
-
# == initializePrimerPlugins
|
925
|
-
#
|
926
|
-
# register all the primer plugins
|
927
|
-
#
|
928
|
-
# called by initializePrimers so it's not necessary to call this separate from that
|
929
|
-
def initializePrimerPlugins
|
930
|
-
|
931
|
-
defined? @plugins_dir_paths \
|
932
|
-
or raise 'plugins_dir_paths not set'
|
933
|
-
|
934
|
-
debug! 1, "Initializing primer plugins..."
|
935
|
-
|
936
|
-
# load the plugins
|
937
|
-
@plugins_dir_paths.each do | dirpath |
|
938
|
-
Dir.foreach( dirpath ) do |filename|
|
939
|
-
next if ! filename.match( /\.plugin\.rb$/ )
|
940
|
-
|
941
|
-
filepath = File.expand_path( filename, dirpath )
|
942
|
-
|
943
|
-
debug! 2, "initializing primer plugin with file: #{filename}"
|
944
|
-
|
945
|
-
setMidPluginInit( filepath )
|
946
|
-
load( filename )
|
947
|
-
unsetMidPluginInit
|
948
|
-
end
|
949
|
-
end
|
950
|
-
debug! 1, "...finished initializing primer plugins"
|
951
|
-
@primer_plugins_initialized = true
|
952
|
-
end
|
953
|
-
|
954
|
-
def setMidPrimerInit ( filepath )
|
955
|
-
@mid_primer_initialization = true
|
956
|
-
@mid_primer_filepath = filepath
|
957
|
-
end
|
958
|
-
|
959
|
-
def unsetMidPrimerInit
|
960
|
-
@mid_primer_initialization = false
|
961
|
-
end
|
962
|
-
|
963
|
-
def midPrimerInit?
|
964
|
-
@mid_primer_initialization \
|
965
|
-
and return true;
|
966
|
-
return false;
|
967
|
-
end
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
def primersInitialized? ( toplevel_dirpath )
|
972
|
-
@flag_primed.has_key?( toplevel_dirpath ) \
|
973
|
-
or return false;
|
974
|
-
return @flag_primed[toplevel_dirpath]
|
975
|
-
end
|
976
|
-
|
977
|
-
def initializePrimerDirectory( key_prefix, current_dirpath )
|
978
|
-
puts "initializing primer directory: #{current_dirpath}"
|
979
|
-
Dir.foreach( current_dirpath ) do |filename|
|
980
|
-
|
981
|
-
# skip the dit dirs
|
982
|
-
next if filename.eql?(".") || filename.eql?("..") || filename =~ /\~$/
|
983
|
-
|
984
|
-
filepath = File.expand_path( filename, current_dirpath )
|
985
|
-
|
986
|
-
if File.directory? filepath
|
987
|
-
new_key_prefix = key_prefix + '.' + filename
|
988
|
-
new_key_prefix = new_key_prefix.gsub(/^\.+/,"")
|
989
|
-
initializePrimerDirectory( new_key_prefix, filepath )
|
990
|
-
else
|
991
|
-
initializePrimerFile( key_prefix, filepath )
|
992
|
-
end
|
993
|
-
end
|
994
|
-
end
|
995
|
-
|
996
|
-
def initializePrimerFile( key_prefix, filepath )
|
997
|
-
|
998
|
-
|
999
|
-
basename = File.basename( filepath )
|
1000
|
-
if primerPluginRegistered? basename
|
1001
|
-
setCurrentPrimerFilepath filepath
|
1002
|
-
|
1003
|
-
setCurrentPrimerKeyPrefix key_prefix
|
1004
|
-
|
1005
|
-
basename = File.basename( filepath )
|
1006
|
-
initializePrimerWithPlugin( key_prefix, filepath )
|
1007
|
-
|
1008
|
-
|
1009
|
-
end
|
1010
|
-
end
|
1011
|
-
|
1012
|
-
def initializePrimerWithPlugin( key_prefix, filepath )
|
1013
|
-
|
1014
|
-
debug! 9, "initializing primer file #{File.basename(filepath)} with plugin"
|
1015
|
-
|
1016
|
-
@primer_plugin_lookup.each do | plugin_array |
|
1017
|
-
|
1018
|
-
# we just need to match the basename
|
1019
|
-
filename = File.basename( filepath )
|
1020
|
-
|
1021
|
-
regexp, plugin_filepath, accepts_block, prime_on_init = plugin_array
|
1022
|
-
|
1023
|
-
if regexp.match( filename )
|
1024
|
-
|
1025
|
-
setCurrentPrimerPluginFilepath( plugin_filepath )
|
1026
|
-
prime_on_init \
|
1027
|
-
or setMidPrimerInit( filepath )
|
1028
|
-
|
1029
|
-
plugin_filename = File.basename( plugin_filepath )
|
1030
|
-
|
1031
|
-
load( plugin_filepath )
|
1032
|
-
|
1033
|
-
prime_on_init \
|
1034
|
-
or unsetMidPrimerInit
|
1035
|
-
|
1036
|
-
|
1037
|
-
return
|
1038
|
-
end
|
1039
|
-
end
|
1040
|
-
end
|
1041
|
-
|
1042
|
-
def setCurrentPrimerPluginFilepath( filepath )
|
1043
|
-
@current_primer_plugin_filepath = filepath
|
1044
|
-
end
|
1045
|
-
|
1046
|
-
def getCurrentPrimerPluginFilepath
|
1047
|
-
@current_primer_plugin_filepath
|
1048
|
-
end
|
1049
|
-
|
1050
|
-
def setCurrentPrimerKeyPrefix ( prefix )
|
1051
|
-
@current_primer_keyprefix = prefix
|
1052
|
-
end
|
1053
|
-
|
1054
|
-
def getCurrentPrimerKeyPrefix
|
1055
|
-
@current_primer_keyprefix
|
1056
|
-
end
|
1057
|
-
|
1058
|
-
def setCurrentPrimerFilepath ( filepath )
|
1059
|
-
@current_primer_filepath = filepath
|
1060
|
-
end
|
1061
|
-
|
1062
|
-
def getCurrentPrimerFilepath
|
1063
|
-
@current_primer_filepath
|
1064
|
-
end
|
1065
|
-
|
1066
|
-
def setCurrentPrimerRequestingKey( key )
|
1067
|
-
@current_primer_requesting_key = key
|
1068
|
-
end
|
1069
|
-
|
1070
|
-
def getCurrentPrimerRequestingKey
|
1071
|
-
@current_primer_requesting_key
|
1072
|
-
end
|
1073
|
-
|
1074
|
-
# ==memorizePrimerLocation
|
1075
|
-
#
|
1076
|
-
# internal, ignore the man behind the curtain
|
1077
|
-
def memorizePrimerLocation( filepath, plugin_filepath, primer_provides )
|
1078
|
-
|
1079
|
-
# validate primer hash
|
1080
|
-
#primer_dirpath = @mid_primer_toplevel_primer_dirpath
|
1081
|
-
primer_dirpath = _get("sadie.primers_dirpath")
|
1082
|
-
@primer_hash.has_key?( primer_dirpath ) \
|
1083
|
-
or @primer_hash["#{primer_dirpath}"] = Hash.new
|
1084
|
-
|
1085
|
-
# interate over provides setting primer providers for each
|
1086
|
-
primer_provides.each do | key |
|
1087
|
-
setPrimerProvider( key, filepath, plugin_filepath, getCurrentPrimerKeyPrefix )
|
1088
|
-
|
1089
|
-
end
|
1090
|
-
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
|
1094
|
-
# ==setPrimerProvider
|
1095
|
-
#
|
1096
|
-
# internal, ignore the man behind the curtain
|
1097
|
-
def setPrimerProvider( primer_name, primer_filepath, primer_plugin_filepath, key_prefix )
|
1098
|
-
|
1099
|
-
primer_dirpath = _get( "sadie.primers_dirpath" )
|
1100
|
-
@primer_hash.has_key?( primer_dirpath ) \
|
1101
|
-
or @primer_hash[primer_dirpath] = Hash.new
|
1102
|
-
|
1103
|
-
@primer_hash["#{primer_dirpath}"]["#{primer_name}"] = [ primer_filepath, primer_plugin_filepath, key_prefix ]
|
1104
|
-
|
1105
|
-
end
|
1106
|
-
|
1107
|
-
def primeable?( key )
|
1108
|
-
p = getPrimerProvider( key )
|
1109
|
-
return nil if ! defined? (p )
|
1110
|
-
return nil if p == nil
|
1111
|
-
return true
|
1112
|
-
end
|
1113
|
-
|
1114
|
-
def getPrimerProvider( key )
|
1115
|
-
|
1116
|
-
# fetch primers dirpath and validate the primer hash
|
1117
|
-
primer_dirpath = _get( "sadie.primers_dirpath" )
|
1118
|
-
@primer_hash.has_key?( primer_dirpath ) \
|
1119
|
-
or @primer_hash[primer_dirpath] = Hash.new
|
1120
|
-
|
1121
|
-
primers = @primer_hash[primer_dirpath]
|
1122
|
-
primers.has_key?( key ) \
|
1123
|
-
or return nil # primer not defined
|
1124
|
-
|
1125
|
-
return primers[key]
|
1126
|
-
end
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
def _primed ( k, is_primed )
|
1131
|
-
defined? k \
|
1132
|
-
or raise '_primed> reqd parameter, k, was undefined'
|
1133
|
-
k.is_a?( String ) \
|
1134
|
-
or raise '_primed> reqd parameter, k, was non-string'
|
1135
|
-
if ( is_primed )
|
1136
|
-
@flag_primed[k] = true
|
1137
|
-
return true
|
1138
|
-
end
|
1139
|
-
@flag_primed.has_key?( k ) \
|
1140
|
-
or return true
|
1141
|
-
@flag_primed.delete( k )
|
1142
|
-
end
|
1143
|
-
|
1144
|
-
def _prime ( k )
|
1145
|
-
|
1146
|
-
debug! 10, "priming: #{k}"
|
1147
|
-
|
1148
|
-
if isEacherKey? k
|
1149
|
-
get( getEacherDependency( k ) )
|
1150
|
-
else
|
1151
|
-
|
1152
|
-
#Sadie::eacherFrame( k, BEFORE )
|
1153
|
-
if provider = getPrimerProvider( k )
|
1154
|
-
primer_filepath, plugin_filepath, key_prefix = provider
|
1155
|
-
|
1156
|
-
currfilepath = getCurrentPrimerFilepath
|
1157
|
-
|
1158
|
-
setCurrentPrimerFilepath(primer_filepath)
|
1159
|
-
setCurrentPrimerKeyPrefix( key_prefix )
|
1160
|
-
Sadie::setCurrentSadieInstance( self )
|
1161
|
-
|
1162
|
-
load plugin_filepath
|
1163
|
-
|
1164
|
-
if defined? currfilepath
|
1165
|
-
setCurrentPrimerFilepath currfilepath
|
1166
|
-
end
|
1167
|
-
end
|
1168
|
-
#Sadie::eacherFrame( k, AFTER )
|
1169
|
-
end
|
1170
|
-
end
|
1171
|
-
|
1172
|
-
|
1173
|
-
def _newline( rval=true )
|
1174
|
-
return rval
|
1175
|
-
end
|
1176
|
-
|
1177
|
-
# ==method: unset
|
1178
|
-
# unsets the value of k. Note that this does not unprime, so
|
1179
|
-
# get(key) will simply return nil. Run with unprime to have the
|
1180
|
-
# primer run again
|
1181
|
-
def unset( key )
|
1182
|
-
_unset( key )
|
1183
|
-
end
|
1184
|
-
|
1185
|
-
def _recallExpensive( k )
|
1186
|
-
expensive_filepath = _computeExpensiveFilepath( k )
|
1187
|
-
File.exists? expensive_filepath \
|
1188
|
-
or raise "expensive filepath: #{filepath} does not exist"
|
1189
|
-
f = open( expensive_filepath )
|
1190
|
-
v = Marshal::load( f.read )
|
1191
|
-
|
1192
|
-
return v
|
1193
|
-
end
|
1194
|
-
|
1195
|
-
def _computeExpensiveFilepath( k )
|
1196
|
-
session_id = get( "sadie.session_id" )
|
1197
|
-
File.expand_path("session."+session_id+".exp."+k, _get( "sadie.sessions_dirpath" ) )
|
1198
|
-
end
|
1199
|
-
|
1200
|
-
def _expensive( k, isexpensive )
|
1201
|
-
if isexpensive
|
1202
|
-
@flag_expensive["#{k}"] = true
|
1203
|
-
return
|
1204
|
-
end
|
1205
|
-
@flag_expensive.delete( k )
|
1206
|
-
end
|
1207
|
-
|
1208
|
-
# direct access setter for shortterm memory
|
1209
|
-
def _set( key, value )
|
1210
|
-
@shortterm["#{key}"] = value
|
1211
|
-
end
|
1212
|
-
|
1213
|
-
def _unset( key )
|
1214
|
-
@shortterm.has_key?( key ) \
|
1215
|
-
and @shortterm.delete( key )
|
1216
|
-
end
|
1217
|
-
|
1218
|
-
|
1219
|
-
# init given path to session file
|
1220
|
-
def _initializeWithSessionFilePath( session_filepath )
|
1221
|
-
|
1222
|
-
puts "session_filepath: #{session_filepath}"
|
1223
|
-
|
1224
|
-
defined?( session_filepath ) \
|
1225
|
-
or raise "session_filepath was undefined"
|
1226
|
-
|
1227
|
-
/^\s*$/.match("#{session_filepath}") \
|
1228
|
-
and raise "session_filepath was empty string"
|
1229
|
-
|
1230
|
-
# bail on non-existant file
|
1231
|
-
File.exist?( session_filepath ) \
|
1232
|
-
or raise "session file, " + session_filepath + " does not exist"
|
1233
|
-
|
1234
|
-
# open session file and read internal vars from it
|
1235
|
-
File.open( session_filepath, "r" ).each do |f|
|
1236
|
-
|
1237
|
-
# make sure no writing happens while we read
|
1238
|
-
f.flock(File::Lock_SH)
|
1239
|
-
|
1240
|
-
# read vars from file
|
1241
|
-
mem, primed, expensive = Marshal::load( f.read )
|
1242
|
-
end
|
1243
|
-
|
1244
|
-
# destructive set on flag vars
|
1245
|
-
@flag_primed = primed
|
1246
|
-
@flag_expensive = expensive
|
1247
|
-
|
1248
|
-
# additive set on shortterm mem
|
1249
|
-
mem.each do |k,v|
|
1250
|
-
set(k, v)
|
1251
|
-
end
|
1252
|
-
end
|
1253
|
-
|
1254
|
-
# init given session id
|
1255
|
-
def _initializeWithSessionId(session_id)
|
1256
|
-
session_filepath = File.expand_path( "session."+session_id, _get( "sadie.sessions_dirpath" ) )
|
1257
|
-
_initializeWithSessionFilePath( session_filepath )
|
1258
|
-
end
|
1259
|
-
|
1260
|
-
# gen new session id
|
1261
|
-
def _generateNewSessionId
|
1262
|
-
begin
|
1263
|
-
value = ""
|
1264
|
-
24.times{value << (65 + rand(25)).chr}
|
1265
|
-
end while File.exist?(File.expand_path("session."+value, get( "sadie.sessions_dirpath" ) ) )
|
1266
|
-
return value
|
1267
|
-
end
|
1268
|
-
|
1269
|
-
# ==method: checkInstanceSanity
|
1270
|
-
#
|
1271
|
-
# verifies that needed instance variables are defined
|
1272
|
-
def _checkInstanceSanity
|
1273
|
-
defined? @shortterm \
|
1274
|
-
or @shortterm = Hash.new
|
1275
|
-
defined? @flag_expensive \
|
1276
|
-
or @flag_expensive = Hash.new
|
1277
|
-
defined? @flag_destroyonget \
|
1278
|
-
or @flag_destroyonget = Hash.new
|
1279
|
-
defined? @flag_primed \
|
1280
|
-
or @flag_primed = Hash.new
|
1281
|
-
|
1282
|
-
end
|
1283
|
-
|
1284
|
-
# ==method: checkClassSanity
|
1285
|
-
#
|
1286
|
-
# verifies that needed class variables are defined
|
1287
|
-
def _checkClassSanity
|
1288
|
-
defined? @flag_primed \
|
1289
|
-
or @flag_primed = Hash.new
|
1290
|
-
|
1291
|
-
# init primer plugin vars
|
1292
|
-
if ( ! defined? @primer_plugin_lookup )
|
1293
|
-
@mid_plugin_initialization = false
|
1294
|
-
@primer_plugin_lookup = Array.new
|
1295
|
-
@primer_plugins_initialized = false
|
1296
|
-
end
|
1297
|
-
|
1298
|
-
# init primer vars
|
1299
|
-
defined? @primer_hash \
|
1300
|
-
or @primer_hash = Hash.new
|
1301
|
-
defined? @flag_primed \
|
1302
|
-
or @flag_primed = Hash.new
|
1303
|
-
if ! defined? @mid_primer_initialization
|
1304
|
-
@mid_primer_initialization = false
|
1305
|
-
@mid_primer_filepath = nil
|
1306
|
-
end
|
1307
|
-
|
1308
|
-
end
|
1309
|
-
|
1310
|
-
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
require "sadie/version"
|
1314
|
-
require "sadie/defaults"
|
1315
|
-
|