sadie 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1 +1,3 @@
1
- Up to v0.0.6: getting it all working
1
+ [Up to v0.0.7] getting it all working
2
+
3
+ [0.0.8] abstracted primer types such that sadie can now use plugins. with two working plugins, IniFile and Resource, it is functionaly equivalent to v0.0.7. More to come.
data/Gemfile CHANGED
@@ -1,8 +1,4 @@
1
- source :rubygems
2
- source "http://rubyforge.org"
3
- source :rubyforge
4
- source "http://gems.rubyforge.org"
5
- gem "ini", "~> 0.1.1"
1
+ source 'http://rubygems.org'
6
2
 
7
- # Specify your gem's dependencies in sadie.gemspec
3
+ # Please see sadie.gemspec for dependency information.
8
4
  gemspec
@@ -0,0 +1,26 @@
1
+ # WARNING: THIS DOESN'T WORK YET!!!
2
+
3
+ Sadie::registerPrimerPlugin( { "match" => /\.dbi\.conx$/,
4
+ "accepts-block" => true } ) do |sadie, key_prefix, primer_file_filepath, block|
5
+
6
+ # build parameter hash
7
+ dbparams = Hash.new
8
+ inifile = Ini.new( primer_file_filepath )
9
+ inifile.each do | section, key_from_ini_file, value |
10
+ section.match(/^connection$/) \
11
+ or next
12
+ dbparams[key_from_ini_file] = value
13
+ end
14
+
15
+ # validate dbistr
16
+ dbparams.has_key( 'dbistr' ) \
17
+ or raise 'requried connection::dbistr was not defined'
18
+
19
+ # default user and pass to nil
20
+ user = dbparams.has_key('user') ? dbparams['user']: nil;
21
+ pass = dbparams.has_key('pass') ? dbparams['pass']: nil;
22
+
23
+ # call connect with block
24
+ require 'dbi'
25
+ DBI.connect( dbparams['dbistr'], user, pass, block )
26
+ end
@@ -0,0 +1,21 @@
1
+ Sadie::registerPrimerPlugin( { "match" => /\.ini$/,
2
+ "accepts-block" => false,
3
+ "prime-on-init" => true } ) do |sadie, key_prefix, primer_file_filepath|
4
+
5
+ require 'ini'
6
+
7
+ ini_file_basename = File.basename primer_file_filepath
8
+ ini_file_root = ini_file_basename.gsub( /\.ini$/, "" )
9
+
10
+ inifile = Ini.new( primer_file_filepath )
11
+ # puts "key_prefix: #{key_prefix}, primer_file_filepath: #{primer_file_filepath}"
12
+ inifile.each do | section, key_from_ini_file, value |
13
+
14
+ # compute key
15
+ # key_prefix = sadie.getCurrentPrimerKeyPrefix
16
+ key_to_set = key_prefix + "." + ini_file_root + "." +section + "." + key_from_ini_file
17
+ key_to_set = key_to_set.gsub( /^\.+/, "" )
18
+
19
+ sadie.set( key_to_set, value )
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ Sadie::registerPrimerPlugin( { "match" => /(\.res|\.res\.rb)$/,
2
+ "accepts-block" => true,
3
+ "prime-on-init" => false } ) do |sadie, key_prefix, primer_file_filepath, block|
4
+
5
+ load( primer_file_filepath )
6
+
7
+ end
@@ -0,0 +1,21 @@
1
+ # WARNING: THIS DOESN'T WORK YET!!!
2
+
3
+ Sadie::registerPrimerPlugin( { "match" => /\.sql$/,
4
+ "accepts-block" => true } ) do |sadie, key_prefix, primer_file_filepath, block|
5
+
6
+ # read query from file @filepath, ditch newlines
7
+ f = open( primer_file_filepath )
8
+ query = f.read
9
+ close( f )
10
+ query = query.gsub(/\n/,'')
11
+
12
+ # get the database and run query
13
+ db_key = key_prefix+".db.conx"
14
+ sadie.get( db_key ) do | dbh |
15
+
16
+ # run the query
17
+ dbh.select_all( query, block )
18
+
19
+ end
20
+ raise 'Sadie returned nil for key: #{db_key}'
21
+ end
data/lib/sadie/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # this file sets the version of the Sadie gem
3
3
 
4
4
  class Sadie
5
- VERSION = "0.0.7"
5
+ VERSION = "0.0.8"
6
6
  end
data/lib/sadie.rb CHANGED
@@ -9,7 +9,7 @@ Bundler.require(:default)
9
9
  # ==Description: Sadie
10
10
  # Sadie is a data framework intended to ease the pain of constructing, accessing, and
11
11
  # managing the resources required by large stores of inter-related data. It supports
12
- # sessions, lazy on-demand, one-time evaluation and file-based storage/retrieval
12
+ # sessions, lazy, on-demand, one-time evaluation and file-based storage/retrieval
13
13
  # operations for resource-heavy data.
14
14
  #
15
15
  # For simplicity, it supports simple, ini-style data
@@ -19,47 +19,95 @@ Bundler.require(:default)
19
19
 
20
20
  class Sadie
21
21
 
22
+ # ==method: Sadie::getSadieInstance
23
+ #
24
+ # returns a new Sadie instance. Options match those of Sadie's constructor method
25
+ def self.getSadieInstance( options )
26
+ Sadie.new(options)
27
+ end
28
+
29
+ # ==method: Sadie::setCurrentSadieInstance
30
+ #
31
+ # this is called just prior to calling a primer plugin to handle a primer to provide
32
+ # a current sadie instance for Sadie::getCurrentSadieInstance to return
33
+ def self.setCurrentSadieInstance ( instance )
34
+ @@current_sadie_instance = instance
35
+ end
36
+
37
+ # ==method: Sadie::setCurrentSadieInstance
38
+ #
39
+ # called by plugin handlers to get access to the current Sadie instance
40
+ def self.getCurrentSadieInstance
41
+ @@current_sadie_instance
42
+ end
43
+
44
+ # ==method: Sadie::Prime
45
+ #
46
+ # called my the .res files to register the keys the .res will prime for
47
+ #
48
+ # accepts as an argument a hash and a block. The hash must include the key:
49
+ # 'provides' and it must define an array
50
+ # of keys that the calling resource (.res) file will have provided after the block is
51
+ # evaluated
52
+ def self.prime ( primer_definition, &block )
53
+ current_sadie_instance = Sadie::getCurrentSadieInstance
54
+ current_sadie_instance.prime( primer_definition, &block )
55
+ end
56
+
57
+ # ==method: Sadie::registerPrimerPlugin
58
+ #
59
+ # this method is called in the .plugin.rb files to register new plugin types
60
+ #
61
+ def self.registerPrimerPlugin ( arghash, &block )
62
+ current_sadie_instance = Sadie::getCurrentSadieInstance
63
+ current_sadie_instance.registerPrimerPlugin( arghash, &block )
64
+ end
65
+
22
66
 
23
67
  # ==method: constructor
24
68
  # options can include any kay, value pairs but the following key values bear mention:
25
69
  # REQUIRED
26
70
  #
27
71
  # sadie.sessions_dirpath
28
- # or
29
- # sadie.session_id
30
- # or
31
- # sadie.session_filepath <- this is probably a bad call, use with caution
72
+ # or
73
+ # sadie.session_id
74
+ # or
75
+ # sadie.session_filepath <- this is probably a bad call, use with caution
32
76
  #
33
77
  # and
34
78
  #
35
- # sadie.primers_dirpath
79
+ # sadie.primers_dirpath
80
+ #
81
+ # and
82
+ # sadie.primer_plugins_dirpath
36
83
  def initialize( options )
37
84
 
38
- # start with blank slate short-term memory, primed and expensive flag hashes
39
- @shortterm = Hash.new
40
- @flag_expensive = Hash.new
41
- @flag_primed = Hash.new
42
- @flag_eachtimeprime = Hash.new
43
-
44
- # init class
45
- Sadie::_checkSanity
46
-
47
- # init mid_primer_initialization if not already done
48
- if ! defined? @@mid_primer_initialization
49
- @@mid_primer_initialization = false
50
- @@mid_primer_filepath = nil
51
- @@mid_primer_toplevel_primer_dirpath = nil
52
- end
85
+ # check instance sanity
86
+ _checkInstanceSanity
87
+ _checkClassSanity
53
88
 
54
89
  # internalize defaults to shortterm
55
90
  DEFAULTS.each do |key, value|
56
91
  _set( key, value )
57
92
  end
58
93
 
59
- # internalize supplied defaults
94
+ # internalize supplied defaults, postponing a set of sadie.primers_dirpath
95
+ # until the end if one is supplied. The reason for this is that the setter
96
+ # attempts to read the plugins and if the primer plugin dirpath has not
97
+ # yet been set, then it'll choke if it processes the wrong one first
98
+ delay_set_primers_dirpath = nil
99
+
100
+ # iterate over constructor args, but do primers_dirpath last since it
101
+ # causes a call to initializePrimers
60
102
  options.each do |key, value|
61
- set( key, value )
103
+ if ( key.eql? "sadie.primers_dirpath")
104
+ delay_set_primers_dirpath = value
105
+ else
106
+ set( key, value )
107
+ end
62
108
  end
109
+ defined? delay_set_primers_dirpath \
110
+ and set( "sadie.primers_dirpath", delay_set_primers_dirpath )
63
111
 
64
112
  # if a path to a session is given, init using session file
65
113
  if defined? options[:sadie.session_filepath] && options[:sadie.session_filepath].match(/^[^\s]+$/)
@@ -78,23 +126,7 @@ class Sadie
78
126
 
79
127
  end
80
128
 
81
- # ==method: Sadie::getSadieInstance
82
- #
83
- # returns a new Sadie instance. Options match those of Sadie's constructor method
84
- def self.getSadieInstance( options )
85
- Sadie.new(options)
86
- end
87
-
88
- # ==method: Sadie::Prime
89
- #
90
- # called my the .res files to register the keys the .res will prime for
91
- #
92
- # accepts as an argument a hash and a block. The hash must include the key:
93
- # 'provides' and it must define an array
94
- # of keys that the calling resource (.res) file will have provided after the block is
95
- # evaluated
96
- def self.Prime ( primer_definition )
97
-
129
+ def prime ( primer_definition, &block )
98
130
  # validate params
99
131
  defined? primer_definition \
100
132
  or raise "Prime called without parameters"
@@ -105,18 +137,17 @@ class Sadie
105
137
 
106
138
  # if initializing primers, just remember how to get back to the primer later,
107
139
  # otherwise, prime
108
- if Sadie::_midPrimerInit?
140
+ if midPrimerInit?
109
141
 
110
142
  # mid primer init, just memorize primer location
111
- Sadie::_memorizePrimerLocation( @@mid_primer_filepath, primer_definition["provides"] )
143
+ memorizePrimerLocation( @@mid_primer_filepath, primer_definition["provides"] )
112
144
  else
113
145
 
114
146
  # run code block with the current sadie instance
115
- current_sadie_instance = Sadie::_getCurrentSadieInstance
116
- yield( current_sadie_instance )
147
+ block.call( self )
117
148
 
118
149
  # loop thru all primer provides, ensuring each primed
119
- current_primer_filepath = Sadie::_getCurrentPrimerFilepath
150
+ current_primer_filepath = getCurrentPrimerFilepath
120
151
  primer_definition["provides"].each do | key |
121
152
 
122
153
  # skip blank lines
@@ -125,11 +156,77 @@ class Sadie
125
156
  #puts "Prime> providing: #{key}"
126
157
 
127
158
  # key primed or raise error
128
- current_sadie_instance.primed? key \
159
+ primed? key \
129
160
  or raise "primer definition file: #{current_primer_filepath} was supposed to define #{key}, but did not"
130
161
  end
131
162
  end
163
+
132
164
  end
165
+
166
+ def registerPrimerPlugin ( arghash, &block )
167
+ if midPluginInit?
168
+
169
+ # init mode, just store arghash info
170
+ accepts_block = arghash.has_key?( "accepts-block" ) && arghash["accepts-block"] ? true : false
171
+ prime_on_init = arghash.has_key?( "prime-on-init" ) && arghash["prime-on-init"] ? true : false
172
+ regPluginMatch( arghash["match"], @@mid_plugin_filepath, accepts_block, prime_on_init )
173
+
174
+ else
175
+
176
+ # prime mode
177
+ currentPrimerPluginPrimerOnInit? \
178
+ or setMidPrimerInit( @@current_primer_filepath )
179
+ key_prefix = getCurrentPrimerKeyPrefix
180
+ if currentPrimerPluginAcceptsBlock?
181
+
182
+ # call with block only if accepts block
183
+ yield( self, key_prefix, @@current_primer_filepath, block )
184
+
185
+ else
186
+
187
+ yield( self, key_prefix, @@current_primer_filepath )
188
+
189
+ end
190
+ currentPrimerPluginPrimerOnInit? \
191
+ or unsetMidPrimerInit
192
+
193
+ end
194
+ end
195
+
196
+
197
+
198
+ # # ==method: pathToKey
199
+ # #
200
+ # # returns a dot-separated version of the filepath such that
201
+ # # with parentify=1 returns dot path to directory file is in,
202
+ # # with parentify=2 returns dot path to directory above directory file is in, etc.
203
+ # def pathToKey( filepath, parentify=0 )
204
+ #
205
+ # # separate path into basename,dirname
206
+ # path_basename = File.basename( filepath )
207
+ # path_dirname = File.dirname( filepath )
208
+ #
209
+ # # create stack of dir components
210
+ # path_stack = Array.new
211
+ # temp_path_stack = path_dirname.split(/\//)
212
+ # temp_path_stack.each do |item|
213
+ # next if item.match(/^\s*$/)
214
+ # path_stack.push item
215
+ # end
216
+ #
217
+ # # lose the suffix on the basename
218
+ # root_path_basename = path_basename.gsub( /\.[^\.]*$/, "" )
219
+ # path_stack.push( root_path_basename )
220
+ # if parentify > 1
221
+ # parentify.times do |i|
222
+ # path_stack.pop
223
+ # end
224
+ # end
225
+ #
226
+ # path_stack.join( "," )
227
+ #
228
+ # end
229
+
133
230
 
134
231
  # ==method: get
135
232
  #
@@ -137,110 +234,70 @@ class Sadie
137
234
  # completely behind-the-scenes as directed by the resource (.res) files
138
235
  def get( k )
139
236
 
237
+
238
+ if ! isset?( k )
239
+ # prime if not yet primed
240
+ primed?( k ) or _prime( k )
241
+ end
242
+
243
+ return _recallExpensive( k ) if expensive?( k )
244
+
140
245
  # if it's already set, return known answer
141
- if _isset?( k )
246
+ if isset?( k )
142
247
 
143
248
  # _get the return value
144
249
  return_value = _get( k )
145
250
 
146
251
  # unset and unprime if destructOnGet?
147
- if destructOnGet?( k )
148
- # puts "destructing #{k}"
149
- unset( k )
150
- unprime( k )
151
- end
252
+ destroyOnGet?( k ) \
253
+ and destroy! k
152
254
 
153
255
  return return_value
154
256
  end
155
257
 
156
- # prime if not yet primed
157
- primed?( k ) \
158
- or _prime( k )
159
-
160
- # if not expensive, then return what's already known
161
- expensive?( k ) \
162
- and return _recallExpensive( k )
163
-
164
- # _get the return value
165
- return_value = _get( k )
166
-
167
- # unset and unprime if destructOnGet?
168
- if destructOnGet?( k )
169
- # puts "destructing #{k}"
170
- unset( k )
171
- unprime( k )
172
- end
173
-
174
- return return_value
175
258
  end
176
259
 
177
-
178
- # ==method: setCheap
260
+ # ==method: isset?
179
261
  #
180
- # the expensive setter. key, value pairs stored via this method are not kept in memory
181
- # but are stored to file and recalled as needed
182
- def setExpensive(k,v)
183
- expensive_filepath = _computeExpensiveFilepath( k )
184
- serialized_value = Marshal::dump( v )
185
- File.open(expensive_filepath, 'w') { |f|
186
- f.write( serialized_value )
187
- }
188
- _expensive( k, true )
189
- _primed( k, true )
262
+ # returns true if sadie has a value for the key
263
+ def isset?( key )
264
+ return @shortterm.has_key?( key )
190
265
  end
191
266
 
192
- # ==method: setDestructOnGet
267
+ # ==method: setDestroyOnGet
193
268
  #
194
269
  # key value will go away and key will be unprimed and unset after next get
195
270
  #
196
271
  # NOTE: this doesn't make sense with keys that were set via setExpensive
197
272
  # so it can be set, but nothing's going to happen differently
198
- def setDestructOnGet( key, turnon=true )
199
- # puts "setDestructOnGet( #{key}, #{turnon} )"
273
+ def setDestroyOnGet( key, turnon=true )
200
274
  if ( turnon )
201
- # puts "turning on destructOnGet for key: #{key}"
202
- @flag_eachtimeprime["#{key}"] = true
275
+ @flag_destroyonget["#{key}"] = true
203
276
  return true
204
277
  end
205
- @flag_eachtimeprime.has_key?( key ) \
206
- and @flag_eachtimeprime.delete( key )
278
+ @flag_destroyonget.has_key?( key ) \
279
+ and @flag_destroyonget.delete( key )
280
+ end
281
+
282
+ # ==method: destroy!
283
+ #
284
+ # remove the key from sadie
285
+ def destroy! ( key )
286
+ unset( key )
287
+ primed?( key ) and unprime( key )
207
288
  end
208
289
 
209
- # ==method: destructOnGet?
290
+ # ==method: destroyOnGet?
210
291
  #
211
292
  # returns true if the destructOnGet flag is set for the key
212
- def destructOnGet?( key )
213
- # print "destructOnGet?> key #{key} "
214
- @flag_eachtimeprime.has_key?( key ) \
293
+ def destroyOnGet?( key )
294
+ @flag_destroyonget.has_key?( key ) \
215
295
  or return _newline( false )
216
- # print " defined-in-eachtimeprime "
217
- @flag_eachtimeprime["#{key}"] \
296
+ @flag_destroyonget["#{key}"] \
218
297
  and return _newline( true )
219
- # print " defined-but-false "
220
298
  return _newline(false)
221
299
  end
222
300
 
223
- def _newline( rval=true )
224
- #puts
225
- return rval
226
- end
227
-
228
- # ==method: unset
229
- # unsets the value of k. Note that this does not unprime, so
230
- # get(key) will simply return nil. Run with unprime to have the
231
- # primer run again
232
- def unset( key )
233
- _unset( key )
234
- end
235
-
236
- # ==method: unprime
237
- # unprimes k. Note that this does not unset the value, so
238
- # get(key) will continue to return whatever it otherwise would have.
239
- # run unset as well to have the primer run again.
240
- def unprime( key )
241
- _primed( key, false )
242
- end
243
-
244
301
  # ==method: set
245
302
  # alias for setCheap(k,v)
246
303
  def set( k, v )
@@ -252,29 +309,67 @@ class Sadie
252
309
  # the cheap setter. key, value pairs stored via this method are kept in memory
253
310
  def setCheap( k, v )
254
311
 
312
+ # puts "setCheap( #{k}, #{v} )"
313
+
255
314
  # set it, mark not expensive and primed
256
315
  _set( k, v )
257
316
  _expensive( k, false )
258
- _primed( k, true )
259
317
 
260
318
  # if we've reset the primers dirpath, init the primers
261
319
  if k.eql?( "sadie.primers_dirpath" )
262
- Sadie::_setMidPrimerTopLevelPrimersDirpath( v )
263
- Sadie::_setCurrentSadieInstance( self )
264
- Sadie::_init_primers
320
+ initializePrimers
321
+ end
322
+
323
+ _primed( k, true )
324
+
325
+ # if we've reset the primers dirpath, init the primers
326
+ if k.eql?( "sadie.primers_dirpath" )
327
+ Sadie::setCurrentSadieInstance( self )
265
328
  end
266
329
 
267
330
  end
268
331
 
332
+ def cheap?( k )
333
+ ! expensive? ( k )
334
+ end
335
+
336
+ # ==method: setExpensive
337
+ #
338
+ # the expensive setter. key, value pairs stored via this method are not kept in memory
339
+ # but are stored to file and recalled as needed
340
+ def setExpensive(k,v)
341
+ expensive_filepath = _computeExpensiveFilepath( k )
342
+ serialized_value = Marshal::dump( v )
343
+ File.open(expensive_filepath, 'w') { |f|
344
+ f.write( serialized_value )
345
+ }
346
+ _expensive( k, true )
347
+ _primed( k, true )
348
+ end
349
+
350
+ # ==method: primed?
351
+ #
352
+ # INTERNAL: this method should only be called the the class method, Prime
353
+ #
354
+ def expensive?( k )
355
+ @flag_expensive.has_key?( k ) or return false;
356
+ @flag_expensive["#{k}"] \
357
+ and return true
358
+ return false
359
+ end
360
+
361
+
269
362
  # ==method: save
270
363
  #
271
364
  # serialize to session file
272
365
  def save
273
- session_filepath = File.expand_path( "session."+value, get( "sadie.sessions_dirpath" ) )
366
+ session_id = get("sadie.session_id")
367
+ session_filepath = File.expand_path( "session."+session_id, get( "sadie.sessions_dirpath" ) )
274
368
  serialized_value = Marshal::dump( [ @shortterm, @flag_primed, @flag_expensive ] )
275
369
  File.open(session_filepath, 'w') { |f|
276
370
  f.write( serialized_value )
277
- }
371
+ }
372
+ return session_id
278
373
  end
279
374
 
280
375
  # ==method: revert!
@@ -291,6 +386,18 @@ class Sadie
291
386
  _initializeWithSessionId( get( "sadie.session_id" ) )
292
387
  end
293
388
 
389
+
390
+
391
+ private
392
+
393
+ # ==method: unprime
394
+ # unprimes k. Note that this does not unset the value, so
395
+ # get(key) will continue to return whatever it otherwise would have.
396
+ # run unset as well to have the primer run again.
397
+ def unprime( key )
398
+ _primed( key, false )
399
+ end
400
+
294
401
  # ==method: primed?
295
402
  #
296
403
  # INTERNAL: this method should only be called the the class method, Prime
@@ -303,122 +410,297 @@ class Sadie
303
410
  return false
304
411
  end
305
412
 
306
- # ==method: primed?
307
- #
308
- # INTERNAL: this method should only be called the the class method, Prime
309
- #
310
- def expensive?( k )
311
- @flag_expensive.has_key?( k ) or return false;
312
- @flag_expensive["#{k}"] \
313
- and return true
314
- return false
413
+ # direct access getter for shortterm memory
414
+ def _get( key )
415
+ value = @shortterm["#{key}"]
416
+ return value
315
417
  end
316
418
 
317
419
 
318
420
 
319
- private
320
-
321
-
322
- def _prime ( k )
323
- # puts "_prime( #{k} )"
324
- # fetch primers dirpath and validate the primer hash
325
- primer_dirpath = _get("sadie.primers_dirpath")
326
- @@primer_hash.has_key?(primer_dirpath) \
327
- or @@primer_hash[primer_dirpath] = Hash.new
421
+ def primerPluginRegistered?( filename )
328
422
 
329
- primers = @@primer_hash[primer_dirpath]
330
- primers.has_key?( k ) or return true
331
-
332
- if primer_filepath = primers[k]
333
- # puts "loading filepath: #{primer_filepath}"
334
- Sadie::_setCurrentPrimerFilepath(primer_filepath)
335
- Sadie::_setCurrentSadieInstance( self )
336
- load primer_filepath
423
+ @@primer_plugin_lookup.each do | plugin_array |
424
+ re, path,accepts_block = plugin_array
425
+ re.match( filename ) \
426
+ and return true
427
+ end
428
+ return false;
429
+ end
430
+
431
+ def primeWithPlugin( key_prefix, filepath )
432
+
433
+ # when this primes, the block run of registerPrimerPlugin needs
434
+ # to know whether or not it accepts block
435
+ @@primer_plugin_lookup.each do | plugin_array |
436
+
437
+ # we just need to match the basename
438
+ filename = File.basename( filepath )
439
+
440
+ regexp, plugin_filepath, accepts_block, prime_on_init = plugin_array
441
+
442
+ if regexp.match( filename )
443
+
444
+ currentPrimerPluginAcceptsBlock( accepts_block )
445
+ currentPrimerPluginPrimeOnInit( prime_on_init )
446
+
447
+ plugin_filename = File.basename( plugin_filepath )
448
+
449
+ load( plugin_filepath )
450
+
451
+ return
452
+ end
337
453
  end
338
- return true
339
-
340
454
  end
341
455
 
342
- def self._setCurrentPrimerFilepath ( filepath )
343
- @@current_primer_filepath = filepath
456
+ def currentPrimerPluginAcceptsBlock( accepts )
457
+ @@primer_plugin_accepts_block = accepts
344
458
  end
345
459
 
346
- def self._getCurrentPrimerFilepath
347
- @@current_primer_filepath
460
+ def currentPrimerPluginAcceptsBlock?
461
+ @@primer_plugin_accepts_block
348
462
  end
349
463
 
350
- def self._setCurrentSadieInstance ( instance )
351
- @@current_sadie_instance = instance
464
+ def currentPrimerPluginPrimeOnInit( prime_on_init )
465
+ @@primer_plugin_prime_on_init = prime_on_init
352
466
  end
353
467
 
354
- def self._getCurrentSadieInstance
355
- @@current_sadie_instance
468
+ def currentPrimerPluginPrimerOnInit?
469
+ @@primer_plugin_prime_on_init
470
+ end
471
+
472
+ def setMidPluginInit( filepath )
473
+ @@mid_plugin_initialization = true
474
+ @@mid_plugin_filepath = filepath
356
475
  end
357
476
 
477
+ def unsetMidPluginInit
478
+ @@mid_plugin_initialization = false
479
+ end
480
+
481
+ def midPluginInit?
482
+ @@mid_plugin_initialization
483
+ end
358
484
 
359
- def self._init_primers( key_prefix="", current_dirpath="" )
485
+ def regPluginMatch ( regexp, filepath, accepts_block, prime_on_init )
486
+ @@primer_plugin_lookup.push( [ regexp, filepath, accepts_block, prime_on_init ] )
487
+ end
488
+
489
+ def primerPluginsInitialized?
490
+ @@primer_plugins_initialized
491
+ end
492
+
493
+ # == initializePrimerPlugins
494
+ #
495
+ # register all the primer plugins
496
+ #
497
+ # called by initializePrimers so it's not necessary to call this separate from that
498
+ def initializePrimerPlugins
360
499
 
361
- # default to the top-level primers dirpath
362
- if current_dirpath.empty?
363
- sadie_instance = Sadie::_getCurrentSadieInstance
364
- current_dirpath = sadie_instance.get( "sadie.primers_dirpath" ) \
365
- or raise "sadie.primers_dirpath not set"
366
- end
500
+ plugins_dirpath = get( "sadie.primer_plugins_dirpath" ) \
501
+ or raise 'sadie.primer_plugins_dirpath not set'
367
502
 
503
+ puts "Initializing primer plugins..."
368
504
 
505
+ # load the plugins
506
+ Dir.foreach( plugins_dirpath ) do |filename|
507
+ next if ! filename.match( /\.plugin\.rb$/ )
508
+
509
+ filepath = File.expand_path( filename, plugins_dirpath )
369
510
 
370
- # loop thru each file in the directory, recurse into subdirs and
371
- # process known filetypes
511
+ puts "initializing primer plugin with file: #{filename}"
512
+
513
+ setMidPluginInit( filepath )
514
+ load( filepath )
515
+ unsetMidPluginInit
516
+ end
517
+ @@primer_plugins_initialized = true
518
+ end
519
+
520
+ def setMidPrimerInit ( filepath )
521
+ @@mid_primer_initialization = true
522
+ @@mid_primer_filepath = filepath
523
+ end
524
+
525
+ def unsetMidPrimerInit
526
+ @@mid_primer_initialization = false
527
+ end
528
+
529
+ def midPrimerInit?
530
+ @@mid_primer_initialization \
531
+ and return true;
532
+ return false;
533
+ end
534
+
535
+
536
+
537
+ def primersInitialized? ( toplevel_dirpath )
538
+ @@flag_primed.has_key?( toplevel_dirpath ) \
539
+ or return false;
540
+ return @@flag_primed[toplevel_dirpath]
541
+ end
542
+
543
+ def initializePrimers
544
+
545
+ Sadie::setCurrentSadieInstance( self )
546
+
547
+ # make sure primer plugins have been initialized
548
+ primerPluginsInitialized? \
549
+ or initializePrimerPlugins
550
+
551
+
552
+ primers_dirpath = get( "sadie.primers_dirpath" ) \
553
+ or raise "sadie.primers_dirpath not set"
554
+
555
+ return true if primersInitialized? primers_dirpath
556
+
557
+ puts "Initializing primers..."
558
+ initializePrimerDirectory( "", primers_dirpath )
559
+
560
+
561
+ @@flag_primed[primers_dirpath] = true
562
+ end
563
+
564
+ def initializePrimerDirectory( key_prefix, current_dirpath )
565
+ puts "initializing primer directory: #{current_dirpath}"
372
566
  Dir.foreach( current_dirpath ) do |filename|
373
567
 
568
+ # skip the dit dirs
569
+ next if filename.eql?(".") || filename.eql?("..")
570
+
374
571
  filepath = File.expand_path( filename, current_dirpath )
375
572
 
376
- if File.directory?( filepath )
377
-
378
- # recurse
379
- filename.eql?(".") || filename.eql?("..") \
380
- or Sadie::_init_primers( key_prefix + "." + filename, filepath )
573
+ if File.directory? filepath
574
+ new_key_prefix = key_prefix + '.' + filename
575
+ new_key_prefix = new_key_prefix.gsub(/^\.+/,"")
576
+ initializePrimerDirectory( new_key_prefix, filepath )
381
577
  else
382
-
383
- # proc known filetypes
384
- if matches = filename.match( /^(.*)\.ini$/ )
385
- prefix = key_prefix + "." + matches[1]
386
- prefix.gsub( /^\.+/, "" )
387
-
388
- Sadie::_init_primers_proc_ini_file( prefix, filepath )
389
- elsif filename.match( /\.res$/ ) || filename.match( /\.res.rb$/ )
390
- Sadie::_init_primers_proc_res_file( filepath )
391
- end
578
+ initializePrimerFile( key_prefix, filepath )
392
579
  end
393
580
  end
394
581
  end
395
582
 
396
- def self._init_primers_proc_ini_file( key_prefix, filepath )
397
- inifile = Ini.new( filepath )
398
- inifile.each do | section, key_from_ini_file, value |
583
+ def initializePrimerFile( key_prefix, filepath )
584
+
585
+
586
+ basename = File.basename( filepath )
587
+ if primerPluginRegistered? basename
588
+ setCurrentPrimerFilepath filepath
399
589
 
400
- # compute key
401
- key_to_set = key_prefix + "." + section + "." + key_from_ini_file
402
- key_to_set = key_to_set.gsub( /^\.+/, "" )
403
- #puts "key_to_set: #{key_to_set}"
590
+ setCurrentPrimerKeyPrefix key_prefix
404
591
 
405
- # get sadie instance and set
406
- sadie_instance = Sadie::_getCurrentSadieInstance
407
- sadie_instance.set( key_to_set, value )
592
+ basename = File.basename( filepath )
593
+ primeWithPlugin( key_prefix, filepath )
594
+ end
595
+ end
596
+
597
+
598
+
599
+ def setCurrentPrimerKeyPrefix ( prefix )
600
+ @@current_primer_keyprefix = prefix
601
+ end
602
+
603
+ def getCurrentPrimerKeyPrefix
604
+ @@current_primer_keyprefix
605
+ end
606
+
607
+ def setCurrentPrimerFilepath ( filepath )
608
+ @@current_primer_filepath = filepath
609
+ end
610
+
611
+ def getCurrentPrimerFilepath
612
+ @@current_primer_filepath
613
+ end
614
+
615
+
616
+
617
+ # ==memorizePrimerLocation
618
+ #
619
+ # internal, ignore the man behind the curtain
620
+ def memorizePrimerLocation( filepath, primer_provides )
621
+
622
+ # validate primer hash
623
+ #primer_dirpath = @@mid_primer_toplevel_primer_dirpath
624
+ primer_dirpath = _get("sadie.primers_dirpath")
625
+ @@primer_hash.has_key?( primer_dirpath ) \
626
+ or @@primer_hash["#{primer_dirpath}"] = Hash.new
627
+
628
+ # interate over provides setting primer providers for each
629
+ primer_provides.each do | key |
630
+ setPrimerProvider( key, filepath )
408
631
  end
409
632
  end
410
633
 
411
- def self._init_primers_proc_res_file( filepath )
634
+
635
+ # ==setPrimerProvider
636
+ #
637
+ # internal, ignore the man behind the curtain
638
+ def setPrimerProvider( primer_name, primer_filepath )
639
+
640
+ primer_dirpath = _get( "sadie.primers_dirpath" )
641
+ @@primer_hash.has_key?( primer_dirpath ) \
642
+ or @@primer_hash[primer_dirpath] = Hash.new
643
+
644
+ @@primer_hash["#{primer_dirpath}"]["#{primer_name}"] = primer_filepath
645
+
646
+ end
647
+
648
+ def getPrimerProvider( key )
412
649
 
413
- # puts "Loading #{filepath}..."
650
+ # fetch primers dirpath and validate the primer hash
651
+ primer_dirpath = _get( "sadie.primers_dirpath" )
652
+ @@primer_hash.has_key?( primer_dirpath ) \
653
+ or @@primer_hash[primer_dirpath] = Hash.new
414
654
 
415
- # load the res file
416
- Sadie::_setMidPrimerInit( filepath )
417
- load( filepath )
418
- Sadie::_unsetMidPrimerInit
655
+ primers = @@primer_hash[primer_dirpath]
656
+ primers.has_key?( key ) \
657
+ or return nil # primer not defined
419
658
 
659
+ return primers[key]
420
660
  end
421
661
 
662
+
663
+
664
+ def _primed ( k, is_primed )
665
+ defined? k \
666
+ or raise '_primed> reqd parameter, k, was undefined'
667
+ k.is_a?( String ) \
668
+ or raise '_primed> reqd parameter, k, was non-string'
669
+ if ( is_primed )
670
+ @flag_primed[k] = true
671
+ return true
672
+ end
673
+ @flag_primed.has_key?( k ) \
674
+ or return true
675
+ @flag_primed.delete( k )
676
+ end
677
+
678
+ def _prime ( k )
679
+
680
+ provider = getPrimerProvider( k ) \
681
+ or return true;
682
+
683
+ setCurrentPrimerFilepath(provider)
684
+ Sadie::setCurrentSadieInstance( self )
685
+ load provider
686
+ true
687
+
688
+ end
689
+
690
+
691
+ def _newline( rval=true )
692
+ #puts
693
+ return rval
694
+ end
695
+
696
+ # ==method: unset
697
+ # unsets the value of k. Note that this does not unprime, so
698
+ # get(key) will simply return nil. Run with unprime to have the
699
+ # primer run again
700
+ def unset( key )
701
+ _unset( key )
702
+ end
703
+
422
704
  def _recallExpensive( k )
423
705
  expensive_filepath = _computeExpensiveFilepath( k )
424
706
  File.exists? expensive_filepath \
@@ -434,14 +716,6 @@ class Sadie
434
716
  File.expand_path("session."+session_id+".exp."+k, _get( "sadie.sessions_dirpath" ) )
435
717
  end
436
718
 
437
- def _primed( k, isprimed )
438
- if isprimed
439
- @flag_primed["#{k}"] = true
440
- return
441
- end
442
- @flag_primed.delete( k )
443
- end
444
-
445
719
  def _expensive( k, isexpensive )
446
720
  if isexpensive
447
721
  @flag_expensive["#{k}"] = true
@@ -450,13 +724,6 @@ class Sadie
450
724
  @flag_expensive.delete( k )
451
725
  end
452
726
 
453
- # direct access getter for shortterm memory
454
- def _get( key )
455
- value = @shortterm["#{key}"]
456
- #puts "_get(#{key})> #{value}"
457
- return value
458
- end
459
-
460
727
  # direct access setter for shortterm memory
461
728
  def _set( key, value )
462
729
 
@@ -469,9 +736,6 @@ class Sadie
469
736
  and @shortterm.delete( key )
470
737
  end
471
738
 
472
- def _isset?( key )
473
- return @shortterm.has_key?( key )
474
- end
475
739
 
476
740
  # init given path to session file
477
741
  def _initializeWithSessionFilePath(session_filepath)
@@ -515,43 +779,49 @@ class Sadie
515
779
  return value
516
780
  end
517
781
 
518
- def self._setMidPrimerInit ( filepath )
519
- @@mid_primer_initialization = true
520
- @@mid_primer_filepath = filepath
521
- end
522
-
523
- def self._unsetMidPrimerInit
524
- @@mid_primer_initialization = false
525
- end
526
-
527
- def self._midPrimerInit?
528
- @@mid_primer_initialization
782
+ # ==method: checkInstanceSanity
783
+ #
784
+ # verifies that needed instance variables are defined
785
+ def _checkInstanceSanity
786
+ defined? @shortterm \
787
+ or @shortterm = Hash.new
788
+ defined? @flag_expensive \
789
+ or @flag_expensive = Hash.new
790
+ defined? @flag_destroyonget \
791
+ or @flag_destroyonget = Hash.new
792
+ defined? @flag_primed \
793
+ or @flag_primed = Hash.new
794
+
529
795
  end
530
796
 
531
- def self._memorizePrimerLocation( filepath, primer_provides )
532
- primer_dirpath = @@mid_primer_toplevel_primer_dirpath
533
- @@primer_hash.has_key?( primer_dirpath ) \
534
- or @@primer_hash["#{primer_dirpath}"] = Hash.new
535
- primer_provides.each do | key |
536
- Sadie::_setPrimerProvider( key, filepath )
797
+ # ==method: checkClassSanity
798
+ #
799
+ # verifies that needed class variables are defined
800
+ def _checkClassSanity
801
+ defined? @@flag_primed \
802
+ or @@flag_primed = Hash.new
803
+
804
+ # init primer plugin vars
805
+ if ( ! defined? @@primer_plugin_lookup )
806
+ @@mid_plugin_initialization = false
807
+ @@primer_plugin_lookup = Array.new
808
+ @@primer_plugins_initialized = false
537
809
  end
538
- end
539
-
540
- def self._setMidPrimerTopLevelPrimersDirpath( dirpath )
541
- @@mid_primer_toplevel_primer_dirpath = dirpath
542
- end
543
-
544
- def self._setPrimerProvider( primer_name, primer_filepath )
545
- primer_dirpath = @@mid_primer_toplevel_primer_dirpath
546
- @@primer_hash["#{primer_dirpath}"]["#{primer_name}"] = primer_filepath
547
- end
548
-
549
- def self._checkSanity
550
- if ! defined? @@primer_hash
551
- @@primer_hash = Hash.new
810
+
811
+ # init primer vars
812
+ defined? @@primer_hash \
813
+ or @@primer_hash = Hash.new
814
+ defined? @flag_primed \
815
+ or @flag_primed = Hash.new
816
+ if ! defined? @@mid_primer_initialization
817
+ @@mid_primer_initialization = false
818
+ @@mid_primer_filepath = nil
819
+ # @@mid_primer_toplevel_primer_dirpath = nil
552
820
  end
553
821
 
554
822
  end
823
+
824
+
555
825
  end
556
826
 
557
827
  require "sadie/version"
data/sadie.gemspec CHANGED
@@ -21,4 +21,7 @@ Gem::Specification.new do |s|
21
21
  # specify any dependencies here; for example:
22
22
  # s.add_development_dependency "rspec"
23
23
  # s.add_runtime_dependency "rest-client"
24
+
25
+ s.add_runtime_dependency "ini"
26
+
24
27
  end
@@ -8,7 +8,8 @@ class TestSadieToplevel < Test::Unit::TestCase
8
8
  def test_simple
9
9
  Dir.mktmpdir("sadie_testdir") do | dir |
10
10
  sadie = Sadie::getSadieInstance( { "sadie.primers_dirpath" => "test/test_primers",
11
- "sadie.sessions_dirpath" => dir } )
11
+ "sadie.sessions_dirpath" => dir,
12
+ "sadie.primer_plugins_dirpath" => "lib/sadie/primer_plugins" } )
12
13
 
13
14
  # test top-level ini
14
15
  assert_equal( sadie.get( "toplevel.somegroup.somekey" ), "someval" )
@@ -8,7 +8,8 @@ class TestSadieTwoDeep < Test::Unit::TestCase
8
8
  def test_simple
9
9
  Dir.mktmpdir("sadie_testdir") do | dir |
10
10
  sadie = Sadie::getSadieInstance( { "sadie.primers_dirpath" => "test/test_primers",
11
- "sadie.sessions_dirpath" => dir } )
11
+ "sadie.sessions_dirpath" => dir,
12
+ "sadie.primer_plugins_dirpath" => "lib/sadie/primer_plugins" } )
12
13
 
13
14
  # test two-deep ini
14
15
  assert_equal( sadie.get( "two.deep.conf.section.thiskey" ), "thisval" )
@@ -0,0 +1 @@
1
+ *.kate-swp
@@ -1,6 +1,4 @@
1
- require 'sadie'
2
-
3
- Sadie::Prime( "provides" => %w{ onedeep.multiresult.oneprime
1
+ Sadie::prime( "provides" => %w{ onedeep.multiresult.oneprime
4
2
  onedeep.multiresult.twoprime } ) do |sadie|
5
3
  sadie.set( "onedeep.multiresult.oneprime", "primedthem" )
6
4
  sadie.set( "onedeep.multiresult.twoprime", "primedthem" )
@@ -1,11 +1,9 @@
1
- require 'sadie'
2
-
3
- Sadie::Prime( "provides" => %w{ toplevel_destructonget.oneprime
1
+ Sadie::prime( "provides" => %w{ toplevel_destructonget.oneprime
4
2
  toplevel_destructonget.twoprime } ) do |sadie|
5
3
  puts "running destructonget primer..."
6
4
  timeobj = Time.now
7
5
  timeinsecs = timeobj.to_f
8
6
  sadie.set( "toplevel_destructonget.oneprime", "primedthem - #{timeinsecs}" )
9
7
  sadie.set( "toplevel_destructonget.twoprime", "primedthem" )
10
- sadie.setDestructOnGet("toplevel_destructonget.oneprime")
8
+ sadie.setDestroyOnGet("toplevel_destructonget.oneprime")
11
9
  end
@@ -1,7 +1,5 @@
1
- require 'sadie'
2
-
3
- Sadie::Prime( "provides" => %w{ toplevel_double.oneprime
4
- toplevel_double.twoprime } ) do |sadie|
1
+ Sadie::prime( "provides" => %w{ toplevel_double.oneprime
2
+ toplevel_double.twoprime } ) do |sadie|
5
3
  sadie.set( "toplevel_double.oneprime", "primedthem" )
6
4
  sadie.set( "toplevel_double.twoprime", "primedthem" )
7
5
  end
@@ -1,5 +1,3 @@
1
- require 'sadie'
2
-
3
- Sadie::Prime( "provides" => %w{ toplevel_single.oneprime } ) do |sadie|
1
+ Sadie::prime( "provides" => %w{ toplevel_single.oneprime } ) do |sadie|
4
2
  sadie.set( "toplevel_single.oneprime", "primedit" )
5
3
  end
@@ -1,5 +1,3 @@
1
- require 'sadie'
2
-
3
- Sadie::Prime( "provides" => %w{ expensive.oneprime } ) do |sadie|
1
+ Sadie::prime( "provides" => %w{ expensive.oneprime } ) do |sadie|
4
2
  sadie.setExpensive( "expensive.oneprime", "primedit" )
5
3
  end
@@ -1,7 +1,8 @@
1
- require 'sadie'
2
-
3
- Sadie::Prime( { "provides" => %w{ two.deep.two_results.firstkey \
1
+ Sadie::prime( { "provides" => %w{ two.deep.two_results.firstkey \
4
2
  two.deep.two_results.secondkey } } ) do |sadie|
3
+
4
+ #puts "priming two_results.res"
5
+
5
6
  sadie.set( "two.deep.two_results.firstkey", "primedthem" )
6
7
  sadie.set( "two.deep.two_results.secondkey", "primedthem" )
7
8
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sadie
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Fred McDavid
@@ -15,9 +15,22 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-20 00:00:00 Z
19
- dependencies: []
20
-
18
+ date: 2012-01-24 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: ini
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
21
34
  description: Sadie is a data framework intended to ease the pain of managing related data.
22
35
  email:
23
36
  - fred@landmetrics.com
@@ -38,6 +51,10 @@ files:
38
51
  - lib/.gitignore
39
52
  - lib/sadie.rb
40
53
  - lib/sadie/defaults.rb
54
+ - lib/sadie/primer_plugins/DatabaseConnection.plugin.rb
55
+ - lib/sadie/primer_plugins/IniFile.plugin.rb
56
+ - lib/sadie/primer_plugins/Resource.plugin.rb
57
+ - lib/sadie/primer_plugins/SQLQuery.plugin.rb
41
58
  - lib/sadie/version.rb
42
59
  - rdoc/classes/Sadie.html
43
60
  - rdoc/created.rid
@@ -53,7 +70,7 @@ files:
53
70
  - sadie.gemspec
54
71
  - test/tc_sadie_toplevel.rb
55
72
  - test/tc_sadie_twodeep.rb
56
- - test/test_primers/.toplevel_double.res.rb.kate-swp
73
+ - test/test_primers/.gitignore
57
74
  - test/test_primers/onedeep/multiresult.res
58
75
  - test/test_primers/toplevel.ini
59
76
  - test/test_primers/toplevel_destructonget.res.rb