splash 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Rakefile +19 -0
  2. data/lib/splash/acts_as_collection.rb +55 -0
  3. data/lib/splash/acts_as_scope.rb +118 -0
  4. data/lib/splash/acts_as_scope_root.rb +10 -0
  5. data/lib/splash/annotated.rb +34 -0
  6. data/lib/splash/application.rb +36 -0
  7. data/lib/splash/attribute.rb +45 -0
  8. data/lib/splash/attributed_struct.rb +8 -0
  9. data/lib/splash/collection.rb +52 -0
  10. data/lib/splash/connection.rb +26 -0
  11. data/lib/splash/constraint/all.rb +24 -0
  12. data/lib/splash/constraint/any.rb +13 -0
  13. data/lib/splash/constraint/in.rb +13 -0
  14. data/lib/splash/constraint/not_nil.rb +9 -0
  15. data/lib/splash/constraint.rb +62 -0
  16. data/lib/splash/document.rb +38 -0
  17. data/lib/splash/embed.rb +37 -0
  18. data/lib/splash/has_attributes.rb +146 -0
  19. data/lib/splash/has_constraint.rb +9 -0
  20. data/lib/splash/namespace.rb +67 -0
  21. data/lib/splash/password.rb +31 -0
  22. data/lib/splash/persister.rb +66 -0
  23. data/lib/splash/query_interface.rb +84 -0
  24. data/lib/splash/saveable.rb +141 -0
  25. data/lib/splash/scope/options.rb +58 -0
  26. data/lib/splash/scope.rb +46 -0
  27. data/lib/splash/scope_delegator.rb +14 -0
  28. data/lib/splash/scope_options.rb +31 -0
  29. data/lib/splash/standart_extensions/hash.rb +45 -0
  30. data/lib/splash/standart_extensions/module.rb +73 -0
  31. data/lib/splash/standart_extensions/object.rb +11 -0
  32. data/lib/splash/standart_extensions/string.rb +5 -0
  33. data/lib/splash/validates.rb +75 -0
  34. data/lib/splash/validator.rb +24 -0
  35. data/lib/splash.rb +35 -0
  36. data/spec/helper.rb +15 -0
  37. data/spec/lib/annotated_spec.rb +87 -0
  38. data/spec/lib/collection_spec.rb +64 -0
  39. data/spec/lib/has_attributes_spec.rb +43 -0
  40. data/spec/lib/has_constraints_spec.rb +53 -0
  41. data/spec/lib/inheritance_spec.rb +69 -0
  42. metadata +139 -0
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/gempackagetask'
4
+ gem 'rspec'
5
+ require 'spec/version'
6
+ require 'spec/rake/spectask'
7
+ require 'spec/ruby'
8
+
9
+ task :default => [:spec]
10
+
11
+ spec = Gem::Specification.load "splash.gemspec"
12
+ Rake::GemPackageTask.new(spec) do |pkg|
13
+ pkg.need_zip = true
14
+ pkg.need_tar = true
15
+ end
16
+
17
+ Spec::Rake::SpecTask.new('spec') do |t|
18
+ t.spec_files = FileList['spec/**/*_spec.rb']
19
+ end
@@ -0,0 +1,55 @@
1
+ module Splash::ActsAsCollection
2
+
3
+ include Enumerable
4
+
5
+ def self.of(klass)
6
+ m = Module.new
7
+ s = self
8
+ m.class_eval do
9
+ include(s)
10
+ end
11
+ m.collection_class = klass
12
+ return m
13
+ end
14
+
15
+ class << self
16
+ def included(base)
17
+ if base.kind_of? Class
18
+ base.extend(ClassMethods)
19
+ else
20
+ base.extend(SubModuleMethods)
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+ module SubModuleMethods
27
+ attr_accessor :collection_class
28
+
29
+ def included(base)
30
+ base.extend(ClassMethods)
31
+ s = self
32
+ base.instance_eval do
33
+ @collection_class = s.collection_class
34
+ end
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+ attr_reader :collection_class
40
+ end
41
+
42
+ def create(*args,&block)
43
+ object=self.class.collection_class.new(*args,&block)
44
+ self << object
45
+ return object
46
+ end
47
+
48
+ def accepts?(object)
49
+ return object === collection_class
50
+ end
51
+
52
+ def include?(object)
53
+ accepts?(object) && super
54
+ end
55
+ end
@@ -0,0 +1,118 @@
1
+ module Splash
2
+ module ActsAsScope
3
+ include QueryInterface
4
+
5
+
6
+ # the following methods have to be defined
7
+ # when including this Module:
8
+ # - collection
9
+ # - scope_root
10
+
11
+
12
+ def scope_options
13
+ @scope_options ||= Splash::Scope::Options.new
14
+ end
15
+
16
+ def query(options)
17
+ Scope.new(self,scope_options.merge(options))
18
+ end
19
+
20
+ def dup
21
+
22
+ end
23
+
24
+ def all
25
+ clone
26
+ end
27
+
28
+ def each(&block)
29
+ self.clone.scope_cursor.each do |o|
30
+ yield Saveable.load(o,self)
31
+ end
32
+ self
33
+ end
34
+
35
+ def to_a
36
+ result = []
37
+ each do |object|
38
+ result << object
39
+ end
40
+ return result
41
+ end
42
+
43
+ def has_next?
44
+ scope_cursor.has_next?
45
+ end
46
+
47
+ def next_document
48
+ nd = scope_cursor.next_document
49
+ return nil if nd.nil?
50
+ return Saveable.load(nd,self)
51
+ end
52
+
53
+ def first
54
+ self.clone.limit(1).next_document
55
+ end
56
+
57
+ def clone
58
+ return Scope.new(self.scope_root,scope_options.dup)
59
+ end
60
+
61
+ def next_raw_document
62
+ scope_cursor.next_document
63
+ end
64
+
65
+ def inspect
66
+ scope_options.inspect
67
+ end
68
+
69
+ =begin
70
+ def finish!
71
+ self.scope_cursor
72
+ self
73
+ end
74
+
75
+ def finished?
76
+ !@scope_cursor.nil?
77
+ end
78
+
79
+ def reset!
80
+ self.unset_scope_cursor
81
+ self
82
+ end
83
+ =end
84
+
85
+ def count
86
+ self.clone.scope_cursor.count
87
+ end
88
+
89
+ def scope_root?
90
+ false
91
+ end
92
+
93
+ def <<(object)
94
+ end
95
+
96
+ def scoped_methods(*modules,&block)
97
+
98
+ end
99
+
100
+ protected
101
+ def scope_cursor()
102
+ @scope_cursor ||= find!(scope_options.selector,scope_options.options)
103
+ end
104
+
105
+ def unset_scope_cursor()
106
+ @scope_cursor=nil
107
+ end
108
+
109
+ def query!(options)
110
+ @scope_options = scope_options.merge(options)
111
+ end
112
+
113
+ def find!(selector,options)
114
+ selector["Type"]=self.scope_root.to_s
115
+ self.scope_root.collection.find(selector,options)
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,10 @@
1
+ module Splash::ActsAsScopeRoot
2
+ include Splash::ActsAsScope
3
+
4
+ def scope_root
5
+ self
6
+ end
7
+ def scope_root?
8
+ true
9
+ end
10
+ end
@@ -0,0 +1,34 @@
1
+ module Splash::Annotated
2
+
3
+ class << self
4
+ def included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+ end
8
+
9
+
10
+ module ClassMethods
11
+
12
+ def method_added(meth)
13
+ apply_annotations(meth)
14
+ super
15
+ end
16
+
17
+ def apply_annotations(meth)
18
+ return if @annotations.nil?
19
+ @annotations.each do |(fn,args,block)|
20
+ args.unshift(meth)
21
+ self.send(fn,*args,&block)
22
+ end
23
+ @annotations=[]
24
+ return nil
25
+ end
26
+
27
+ def included(base)
28
+ included_modules.each do |mod|
29
+ mod.included(base)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ module Splash
2
+ module Application
3
+ class << self
4
+ def respond(request)
5
+
6
+
7
+
8
+ end
9
+
10
+
11
+ def call(env)
12
+ t='<form action="" method="post">
13
+ <p>
14
+ <input id="openid_identifier" name="openid[identifier][id]" type="text" />
15
+ </p>
16
+
17
+ <p>
18
+ <input name="commit" type="submit" value="Sign in" />
19
+ </p>
20
+ </form>'
21
+ request=Rack::Request.new(env)
22
+ if resp = env["rack.openid.response"]
23
+ if resp.status == :missing
24
+ return [401, {"WWW-Authenticate" => "OpenID identifier=\"#{request["openid_identifier"]}\""}, []]
25
+ else
26
+ env["rack.session"]["user"]=resp.identity_url
27
+ return [200,{'Content-Type' => 'text/html'},'<html>Welcome!<pre>'+(env.to_yaml)+'</pre></html>']
28
+ end
29
+ elsif request["openid_identifier"]
30
+ return [401, {"WWW-Authenticate" => "OpenID identifier=\"#{request["openid_identifier"]}\""}, []]
31
+ end
32
+ return [200,{'Content-Type' => 'text/html'},'<html>'+t+'<pre>'+(request.to_yaml)+'</pre></html>']
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ class Splash::Attribute
2
+
3
+ include ::Humanized
4
+ include Splash::HasConstraint
5
+
6
+ attr_accessor :persister, :type, :default
7
+
8
+ def initialize(t=nil,&block)
9
+ self.type=t if t
10
+ instance_eval &block if block_given?
11
+ end
12
+
13
+ def type= t
14
+ @persister = Splash::HasAttributes.get_persister(t)
15
+ @type = t
16
+ end
17
+
18
+ def persisted_by(*args,&block)
19
+ @persister = Splash::HasAttributes.get_persister(*args, &block)
20
+ end
21
+
22
+ def read(value)
23
+ return value unless @persister
24
+ @persister.read(value)
25
+ end
26
+
27
+ def write(value)
28
+ return value unless @persister
29
+ @persister.write(value)
30
+ end
31
+
32
+ def persisted_class
33
+ return Object unless @persister
34
+ @persister.persisted_class
35
+ end
36
+
37
+ def missing()
38
+ if self.default
39
+ self.default.clone
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,8 @@
1
+ class Splash::AttributedStruct
2
+
3
+ include Splash::HasAttributes
4
+
5
+ def initialize(attr={})
6
+ self.attributes.load(attr)
7
+ end
8
+ end
@@ -0,0 +1,52 @@
1
+ class Splash::Collection < Array
2
+ include Splash::ActsAsCollection
3
+
4
+ COLLECTION_CLASSES = {}
5
+
6
+ def self.of(klass)
7
+
8
+ return COLLECTION_CLASSES[klass] if COLLECTION_CLASSES.key? klass
9
+
10
+ c = Class.new(self)
11
+ c.instance_eval do
12
+ @collection_class = klass
13
+ end
14
+
15
+ COLLECTION_CLASSES[klass] = c
16
+ return c
17
+ end
18
+
19
+
20
+ class Persister < Splash::Persister
21
+
22
+ def read(val)
23
+ return nil if val.nil?
24
+ nu=persisted_class.new
25
+ val.inject(nu){|memo,e|
26
+ memo << @persister.read(e)
27
+ memo
28
+ }
29
+ end
30
+
31
+ def write(val)
32
+ return nil if val.nil?
33
+ val.inject([]){|memo,e|
34
+ memo << @persister.write(e)
35
+ memo
36
+ }
37
+ end
38
+
39
+ def persist_class(col)
40
+ @persister=Splash::HasAttributes.get_persister(col.collection_class)
41
+ super
42
+ end
43
+
44
+ end
45
+
46
+ class << self
47
+ def persister
48
+ return Splash::Collection::Persister
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,26 @@
1
+ class Splash::Connection
2
+ def initialize(host,db)
3
+ @host=host
4
+ @db=db
5
+ end
6
+
7
+ def get(id)
8
+ Net::HTTP.start("localhost", 5984){|http|
9
+ http.get('/splash/'+id)
10
+ }.body.parse_json
11
+ end
12
+
13
+ def put(id,val)
14
+ id = id.to_s
15
+ req=Net::HTTP::Put.new('/splash/'+id)
16
+ req.set_content_type("application/json")
17
+ Net::HTTP.start("localhost", 5984){|http|
18
+ http.request(req,val.to_json)
19
+ }.body
20
+ end
21
+
22
+ def uuid
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,24 @@
1
+ class Splash::Constraint::All < Set
2
+
3
+ include Splash::Constraint
4
+ include Splash::ActsAsCollection.of(Splash::Constraint)
5
+
6
+ def accept?(value)
7
+ self.all? do |constr|
8
+ constr.accept?(value)
9
+ end
10
+ end
11
+
12
+ def not_accepting(value)
13
+ result = Splash::Constraint::All.new
14
+ self.each do |constr|
15
+ result << constr unless constr.accept?(value)
16
+ end
17
+ return result
18
+ end
19
+
20
+ def initialize
21
+ super("all!")
22
+ end
23
+
24
+ end
@@ -0,0 +1,13 @@
1
+ class Splash::Constraint::Any < Set
2
+
3
+ include Splash::Constraint
4
+ include Splash::ActsAsCollection.of(Splash::Constraint)
5
+
6
+ def accept?(value)
7
+ self.all? do |constr|
8
+ constr.accept?(value)
9
+ end
10
+ end
11
+
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ class Splash::Constraint::In
2
+
3
+ include Splash::Constraint
4
+
5
+ def initialize(collection,desc="")
6
+ @collection = collection
7
+ super(desc)
8
+ end
9
+
10
+ def accept?(value)
11
+ return value.nil? || collection.include?(value)
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ class Splash::Constraint::NotNil
2
+
3
+ include Splash::Constraint
4
+
5
+ def accept?(value)
6
+ !value.nil?
7
+ end
8
+
9
+ end
@@ -0,0 +1,62 @@
1
+ module Splash::Constraint
2
+
3
+ attr_reader :description
4
+
5
+ autoload :Any, File.join( File.dirname(__FILE__), 'constraint/any' )
6
+ autoload :All, File.join( File.dirname(__FILE__), 'constraint/all' )
7
+ autoload :NotNil, File.join( File.dirname(__FILE__), 'constraint/not_nil' )
8
+ autoload :In, File.join( File.dirname(__FILE__), 'constraint/in' )
9
+
10
+ class Simple
11
+
12
+ include Splash::Constraint
13
+
14
+ def initialize(descr,&block)
15
+ @description = descr
16
+ @block = block
17
+ end
18
+
19
+ def accept?(value)
20
+ return @block.call(value)
21
+ end
22
+
23
+ end
24
+
25
+ def self.new(*args,&block)
26
+ if self == Splash::Constraint
27
+ return Simple.new(*args,&block)
28
+ end
29
+ super
30
+ end
31
+
32
+ def self.and(*args)
33
+ if args.length == 0
34
+ return Splash::Constraint::All.new
35
+ elsif args.length == 1
36
+ return args.first
37
+ else
38
+ result = Splash::Constraint::All.new
39
+ args.each do |constr|
40
+ if constr.kind_of? Splash::Constraint::All
41
+ result += constr
42
+ else
43
+ result << constr
44
+ end
45
+
46
+ end
47
+ return result
48
+ end
49
+ end
50
+
51
+ def not_accepting(value)
52
+ return self unless self.accept?(value)
53
+ end
54
+
55
+ def initialize(descr)
56
+ @description = descr
57
+ super()
58
+ end
59
+
60
+ alias_method :to_s, :description
61
+
62
+ end
@@ -0,0 +1,38 @@
1
+ module Splash::Document
2
+
3
+ include Splash::Saveable
4
+ include Splash::HasAttributes
5
+ include Splash::Validates
6
+
7
+ class << self
8
+ def included(base)
9
+ included_modules.each do |mod|
10
+ mod.included(base)
11
+ end
12
+
13
+ dd = self
14
+
15
+ base.instance_eval do
16
+ include Splash::ActsAsCollection.of(base)
17
+ extend Splash::ActsAsScopeRoot
18
+
19
+ def included(base)
20
+ Splash::Document.included(base)
21
+ super(base)
22
+ end
23
+ end
24
+ end
25
+
26
+ def persister
27
+ Splash::Saveable::MultiPersister
28
+ end
29
+ end
30
+
31
+ def initialize(args={})
32
+ self.attributes.load(args)
33
+ end
34
+
35
+ def to_saveable
36
+ attributes.raw
37
+ end
38
+ end
@@ -0,0 +1,37 @@
1
+ module Splash::Embed
2
+
3
+ include Splash::HasAttributes
4
+ include Splash::Validates
5
+
6
+ class << self
7
+ def included(base)
8
+ base.extend(ClassMethods)
9
+ included_modules.each do |mod|
10
+ mod.included(base)
11
+ end
12
+ end
13
+
14
+ def define(&block)
15
+ c=Class.new()
16
+ mod = self
17
+ c.instance_eval do
18
+ include mod
19
+ end
20
+ c.class_eval(&block)
21
+ c
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+ def persister
27
+ Splash::Saveable::EmbedPersister
28
+ end
29
+ end
30
+
31
+ def initialize(args={})
32
+ self.attributes.load(args)
33
+ end
34
+ def to_saveable
35
+ attributes.raw
36
+ end
37
+ end