dyoder-filebase 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/attributes.rb +46 -0
- data/lib/filebase.rb +13 -0
- data/lib/model.rb +82 -0
- data/lib/string.rb +47 -0
- data/lib/symbol.rb +7 -0
- data/lib/yaml.rb +33 -0
- metadata +66 -0
data/lib/attributes.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Attributes
|
2
|
+
|
3
|
+
def initialize(hash={})
|
4
|
+
# copy the hash, converting all keys to strings
|
5
|
+
@attrs = hash.inject({}) { |h,p| k,v = p; h[k.to_s] = v; h }
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(name,*args)
|
9
|
+
name = name.to_s
|
10
|
+
if name =~/=$/ and args.length == 1
|
11
|
+
set(name[0..-2], args[0] )
|
12
|
+
else
|
13
|
+
get(name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](name)
|
18
|
+
get(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def []=(name,val)
|
22
|
+
set(name,val)
|
23
|
+
end
|
24
|
+
|
25
|
+
def set(name, val)
|
26
|
+
@attrs[name.to_s] = val
|
27
|
+
end
|
28
|
+
|
29
|
+
def get(name)
|
30
|
+
rval = ( @attrs[name.to_s] )
|
31
|
+
if Hash === rval
|
32
|
+
Dynamo.new(rval)
|
33
|
+
else
|
34
|
+
rval
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
@attrs
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :to_hash, :to_h
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
data/lib/filebase.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'lib/yaml'
|
3
|
+
require 'lib/symbol'
|
4
|
+
require 'lib/string'
|
5
|
+
class Filebase
|
6
|
+
class << self ; attr_accessor :storage ; end
|
7
|
+
self.storage = YAML
|
8
|
+
def initialize( root = '.', storage = nil )
|
9
|
+
@storage = ( storage || Filebase.storage ).new( root )
|
10
|
+
end
|
11
|
+
# delegate everything to the storage object ...
|
12
|
+
def method_missing( name,*args ) ; @storage.send( name, *args ) ; end
|
13
|
+
end
|
data/lib/model.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'lib/filebase'
|
2
|
+
require 'lib/attributes'
|
3
|
+
|
4
|
+
class Filebase
|
5
|
+
|
6
|
+
Error = RuntimeError
|
7
|
+
|
8
|
+
module Model
|
9
|
+
|
10
|
+
def self.[]( path )
|
11
|
+
Module.new do |mixin|
|
12
|
+
( class << mixin ; self ; end ).module_eval do
|
13
|
+
define_method( :included ) do | model |
|
14
|
+
model.module_eval do
|
15
|
+
@db = Filebase.new( path )
|
16
|
+
extend Mixins::ClassMethods ; include Attributes ; include Mixins::InstanceMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Mixins
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
attr_accessor :db
|
27
|
+
def create( assigns ) ; save( new( assigns ) ) ; end
|
28
|
+
def all ; db.all.map { |attrs| new( attrs ) } ; end
|
29
|
+
def find( key ) ; attrs = db.find( key ); new( attrs.merge( :key => key ) ) if attrs ; 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.camel_case )
|
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
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/lib/string.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Waves extends String with a variety of methods for changing from singular to plural and back, and switching to different types of case and word separators. These methods are similar to those found in Rails and other frameworks, but some (all?) of the names are different. The names here were chosen for increased clarity and are hopefully easy to adjust to ...
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
# Does a File.join on the two arguments joined by the /. Very handy
|
6
|
+
# for doing platform-safe paths without having to use File.join.
|
7
|
+
#
|
8
|
+
# I unfortunately don't recall where i first saw this ... see
|
9
|
+
# Symbol extension as well, allowing for :files / 'afilename.txt'
|
10
|
+
|
11
|
+
def / ( string )
|
12
|
+
File.join(self,string.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
def singular
|
16
|
+
Inflect::English.singular(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method(:singularize, :singular)
|
20
|
+
|
21
|
+
def plural
|
22
|
+
Inflect::English.plural(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method(:pluralize, :plural)
|
26
|
+
|
27
|
+
def lower_camel_case
|
28
|
+
gsub(/(_)(\w)/) { $2.upcase }
|
29
|
+
end
|
30
|
+
|
31
|
+
def camel_case
|
32
|
+
lower_camel_case.gsub(/^([a-z])/) { $1.upcase }
|
33
|
+
end
|
34
|
+
|
35
|
+
def snake_case
|
36
|
+
gsub(/([a-z\d])([A-Z])/){ "#{$1}_#{$2}"}.tr("-", "_").downcase
|
37
|
+
end
|
38
|
+
|
39
|
+
def title_case
|
40
|
+
gsub(/(^|\s)\s*([a-z])/) { $1 + $2.upcase }
|
41
|
+
end
|
42
|
+
|
43
|
+
def text
|
44
|
+
gsub(/[\_\-\.\:]/,' ')
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/symbol.rb
ADDED
data/lib/yaml.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'extensions/io'
|
3
|
+
class Filebase
|
4
|
+
|
5
|
+
class YAML
|
6
|
+
|
7
|
+
def initialize( root )
|
8
|
+
@root = root
|
9
|
+
end
|
10
|
+
|
11
|
+
def path( key )
|
12
|
+
@root / key + '.yml'
|
13
|
+
end
|
14
|
+
|
15
|
+
def all
|
16
|
+
Dir[ path('*') ].map { |file| YAML.load( File.read( file ) ) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def find( key )
|
20
|
+
( ::YAML.load( File.read( path( key ) ) ) if File.exists?( path( key ) ) ) || nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def save( key, object )
|
24
|
+
File.write( path( key ), object.to_yaml )
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete( key )
|
28
|
+
FileUtils.remove( path( key ) )
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dyoder-filebase
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Yoder, Matthew King, Lawrence Pit
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-04-30 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: extensions
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description:
|
25
|
+
email: dan@zeraweb.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- lib/attributes.rb
|
34
|
+
- lib/filebase.rb
|
35
|
+
- lib/model.rb
|
36
|
+
- lib/string.rb
|
37
|
+
- lib/symbol.rb
|
38
|
+
- lib/yaml.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://dev.zeraweb.com/waves
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.8.6
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.0.1
|
62
|
+
signing_key:
|
63
|
+
specification_version: 2
|
64
|
+
summary: Simple file-based database with model support.
|
65
|
+
test_files: []
|
66
|
+
|