dyoder-filebase 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ require 'yaml'
2
+ require 'extensions/io'
3
+ class Filebase
4
+
5
+ class YAML
6
+
7
+ def initialize( root )
8
+ @root = root.to_s
9
+ end
10
+
11
+ def path( key )
12
+ File.join( @root, key.to_s ) + '.yml'
13
+ end
14
+
15
+ def all
16
+ Dir[ path('*') ].map { |file| find( File.basename(file,'.yml' ) ) }.compact
17
+ end
18
+
19
+ def find( key )
20
+ obj = ::YAML.load( File.read( path( key ) ) ) rescue nil
21
+ obj['key'] = key if Hash === obj
22
+ obj or nil # convert false to nil
23
+ end
24
+
25
+ def save( key, object )
26
+ File.write( path( key ), object.to_yaml )
27
+ end
28
+
29
+ def delete( key )
30
+ FileUtils.remove( path( key ) )
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,48 @@
1
+ module Attributes
2
+
3
+ def initialize(hash = {} )
4
+ attributes = hash
5
+ end
6
+
7
+ def attributes=( hash )
8
+ # copy the hash, converting all keys to strings
9
+ @attrs = hash.inject({}) { |h,p| k,v = p; h[k.to_s] = v; h }
10
+ end
11
+
12
+ def attributes
13
+ @attrs ||= {}
14
+ end
15
+
16
+ def method_missing(name,*args)
17
+ name = name.to_s
18
+ if name =~/=$/ and args.length == 1
19
+ set(name[0..-2], args[0] )
20
+ else
21
+ get(name)
22
+ end
23
+ end
24
+
25
+ def [](name)
26
+ get(name)
27
+ end
28
+
29
+ def []=(name,val)
30
+ set(name,val)
31
+ end
32
+
33
+ def set(name, val)
34
+ attributes[name.to_s] = val
35
+ end
36
+
37
+ def get(name)
38
+ rval = attributes[name.to_s]
39
+ rval.is_a?( Hash ) ? Attributes.new( rval ) : rval
40
+ end
41
+
42
+ def to_h
43
+ @attrs
44
+ end
45
+
46
+ alias_method :to_hash, :to_h
47
+
48
+ end
@@ -0,0 +1,84 @@
1
+ require 'filebase/attributes'
2
+
3
+ class Filebase
4
+
5
+ Error = RuntimeError
6
+
7
+ module Model
8
+
9
+ def self.[]( path )
10
+ Module.new do |mixin|
11
+ ( class << mixin ; self ; end ).module_eval do
12
+ define_method( :included ) do | model |
13
+ model.module_eval do
14
+ @db = Filebase.new( path )
15
+ extend Mixins::ClassMethods ; include Attributes ; include Mixins::InstanceMethods
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ module Mixins
23
+
24
+ module ClassMethods
25
+ attr_accessor :db
26
+ def create( assigns ) ; save( new( assigns ) ) ; end
27
+ def all ; db.all.map { |attrs| new( attrs ) } ; end
28
+ def find( key ) ; attrs = db.find( key ); new( attrs ) if attrs ; end
29
+ def []( key ) ; find( key ) ; end
30
+ def save( object )
31
+ raise( Filebase::Error.new, 'attempted to save an object with nil key' ) if object.key.nil? or object.key.empty?
32
+ db.save( object.key, object.to_h )
33
+ end
34
+ def delete( object )
35
+ raise( Filebase::Error.new, 'attempted to delete an object with nil key' ) if object.key.nil? or object.key.empty?
36
+ db.delete( object.key )
37
+ end
38
+ def has_one( name, options = {} )
39
+ module_eval do
40
+ define_method name do
41
+ @has_one ||= {}
42
+ options[:class] ||= Object.module_eval( name.to_s.gsub(/(_)(\w)/) { $2.upcase }.gsub(/^([a-z])/) { $1.upcase } )
43
+ @has_one[name] ||= options[:class].find( get( name ) )
44
+ end
45
+ define_method( name.to_s + '=' ) do | val |
46
+ @has_one ||= {}; @has_one[name] = nil
47
+ set( name, String === val ? val : val.key )
48
+ end
49
+ end
50
+ end
51
+ def has_many( name, options = {} )
52
+ module_eval do
53
+ define_method( name ) do
54
+ @has_many ||= {}
55
+ options[:class] ||= Object.module_eval( name.to_s.camel_case )
56
+ @has_many[name] ||= ( get( name ) || [] ).uniq.map { |key| options[:class].find( key ) }
57
+ end
58
+ # when we save, make sure to pick up any changes to the array
59
+ (class<<self;self;end).module_eval do
60
+ old_save = instance_method(:save)
61
+ define_method :save do |object|
62
+ object.set( name, object.send( name ).map{ |x| x.key }.uniq )
63
+ old_save.bind(self).call(object)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ module InstanceMethods
71
+ def initialize( assigns ) ; super ; assign( assigns ) ; end
72
+ def assign( assigns ) ; assigns.each { |k,v| self.send( "#{k}=", v ) }; self ; end
73
+ def save ; self.class.save( self ) ; self; end
74
+ def delete ; self.class.delete( self ) ; self ; end
75
+ def ==(object) ; key == object.key ; end
76
+ def eql?(object) ; key == object.key ; end
77
+ def hash ; key.hash ; end
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+ end
data/lib/filebase.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'drivers/yaml'
3
+ class Filebase
4
+ class << self ; attr_accessor :storage ; end
5
+ self.storage = YAML
6
+ def initialize( root = '.', storage = nil )
7
+ @storage = ( storage || Filebase.storage ).new( root )
8
+ end
9
+ # delegate everything to the storage object ...
10
+ def method_missing( name,*args ) ; @storage.send( name, *args ) ; end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyoder-filebase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Yoder