splash 0.0.1.alpha

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.
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