splash 0.0.1.alpha → 0.0.1.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/Gemfile +5 -0
  2. data/lib/splash.rb +22 -26
  3. data/lib/splash/acts_as_collection.rb +3 -2
  4. data/lib/splash/acts_as_scope.rb +97 -33
  5. data/lib/splash/acts_as_scope_root.rb +2 -1
  6. data/lib/splash/annotated.rb +2 -1
  7. data/lib/splash/application.rb +2 -1
  8. data/lib/splash/attribute.rb +39 -21
  9. data/lib/splash/attributed_struct.rb +2 -1
  10. data/lib/splash/callbacks.rb +37 -0
  11. data/lib/splash/collection.rb +14 -11
  12. data/lib/splash/connection.rb +2 -1
  13. data/lib/splash/constraint.rb +3 -5
  14. data/lib/splash/constraint/all.rb +2 -1
  15. data/lib/splash/constraint/any.rb +2 -1
  16. data/lib/splash/constraint/in.rb +2 -1
  17. data/lib/splash/constraint/not_nil.rb +2 -1
  18. data/lib/splash/created_at.rb +16 -0
  19. data/lib/splash/document.rb +43 -15
  20. data/lib/splash/embed.rb +29 -9
  21. data/lib/splash/has_attributes.rb +68 -37
  22. data/lib/splash/has_collection.rb +79 -0
  23. data/lib/splash/has_constraint.rb +2 -1
  24. data/lib/splash/map_reduce.rb +124 -0
  25. data/lib/splash/matcher.rb +160 -0
  26. data/lib/splash/namespace.rb +149 -15
  27. data/lib/splash/password.rb +2 -1
  28. data/lib/splash/persister.rb +22 -62
  29. data/lib/splash/query_interface.rb +28 -6
  30. data/lib/splash/saveable.rb +5 -104
  31. data/lib/splash/scope.rb +16 -3
  32. data/lib/splash/scope/map_reduce_interface.rb +33 -0
  33. data/lib/splash/scope/options.rb +16 -6
  34. data/lib/splash/updated_at.rb +15 -0
  35. data/lib/splash/validates.rb +3 -1
  36. data/lib/splash/validator.rb +2 -1
  37. data/lib/splash/writeback.rb +46 -0
  38. data/lib/standart_extensions/array.rb +9 -0
  39. data/lib/standart_extensions/bson.rb +122 -0
  40. data/lib/standart_extensions/class.rb +11 -0
  41. data/lib/{splash/standart_extensions → standart_extensions}/hash.rb +6 -1
  42. data/lib/{splash/standart_extensions → standart_extensions}/module.rb +17 -3
  43. data/lib/standart_extensions/object.rb +13 -0
  44. data/splash.gemspec +17 -0
  45. metadata +20 -16
  46. data/lib/splash/scope_delegator.rb +0 -14
  47. data/lib/splash/scope_options.rb +0 -31
  48. data/lib/splash/standart_extensions/object.rb +0 -11
  49. data/lib/splash/standart_extensions/string.rb +0 -5
  50. data/spec/helper.rb +0 -15
  51. data/spec/lib/annotated_spec.rb +0 -87
  52. data/spec/lib/collection_spec.rb +0 -64
  53. data/spec/lib/has_attributes_spec.rb +0 -43
  54. data/spec/lib/has_constraints_spec.rb +0 -53
  55. data/spec/lib/inheritance_spec.rb +0 -69
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'digest/sha1'
2
3
  require 'securerandom'
3
4
 
@@ -28,4 +29,4 @@ class Splash::Password
28
29
  end
29
30
 
30
31
 
31
- end
32
+ end
@@ -1,66 +1,26 @@
1
- class Splash::Persister
1
+ # -*- encoding : utf-8 -*-
2
+ module Splash
3
+ module Persister
2
4
 
3
- RAW_TYPES=[String,NilClass,Numeric,FalseClass,TrueClass,BSON::ObjectID,Time]
4
-
5
- attr_reader :persisted_class
6
-
7
- def read(value)
8
- return value
9
- end
10
-
11
- def write(value)
12
- return value
13
- end
14
-
15
- def self.raw?(value)
16
- return true if RAW_TYPES.any? do |type| value.class == type end
17
- if value.kind_of?(Hash) || value.kind_of?(Array)
18
- value.each do |key,val|
19
- return false unless self.raw?(key)
20
- return false unless self.raw?(val)
21
- end
22
- return true
23
- elsif value.kind_of?(Array)
24
- value.each do |sub|
25
- return false unless self.raw?(sub)
5
+ RAW_TYPES=[String,NilClass,Numeric,FalseClass,TrueClass,BSON::ObjectId,Time,BSON::Code,BSON::DBRef,Symbol]
6
+
7
+ def self.raw?(value)
8
+ return true if RAW_TYPES.any? do |type| value.class == type end
9
+ if value.kind_of?(Hash) || value.kind_of?(Array)
10
+ value.each do |key,val|
11
+ return false unless self.raw?(key)
12
+ return false unless self.raw?(val)
13
+ end
14
+ return true
15
+ elsif value.kind_of?(Array)
16
+ value.each do |sub|
17
+ return false unless self.raw?(sub)
18
+ end
19
+ return true
26
20
  end
27
- return true
28
- end
29
- return false
30
- end
31
-
32
- def initialize(config={},&block)
33
- self.config= default_config.merge(config)
34
- if block_given?
35
- instance_eval &block
21
+ return false
36
22
  end
23
+
37
24
  end
38
-
39
- def persist_class(klass)
40
- @persisted_class=klass
41
- end
42
-
43
- def persisted_class()
44
- @persisted_class
45
- end
46
-
47
- def bind_to(klass)
48
-
49
- end
50
-
51
- def default(object)
52
- @config[:default]
53
- end
54
-
55
- def missing(object)
56
- nil
57
- end
58
-
59
- protected
60
- def default_config
61
- {:default=>nil,:read=>nil,:write=>nil}
62
- end
63
- def config=(conf)
64
- @config=conf
65
- end
66
- end
25
+
26
+ end
@@ -1,7 +1,8 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Splash
2
3
  module QueryInterface
3
4
 
4
- %w(preload nopreload limit conditions fieldmode with_id extend_scoped sort).each do |fct|
5
+ %w(preload nopreload limit conditions fieldmode with_id extend_scoped sort writeback where).each do |fct|
5
6
  class_eval <<-CODE, __FILE__,__LINE__
6
7
  def #{fct}(*args,&block)
7
8
  query(query_#{fct}(*args,&block))
@@ -36,7 +37,7 @@ CODE
36
37
  end
37
38
 
38
39
  def query_conditions(conditions)
39
- return {:selector=>conditions}
40
+ return {:query=>conditions}
40
41
  end
41
42
 
42
43
  def query_default_attributes(values)
@@ -44,13 +45,22 @@ CODE
44
45
  end
45
46
 
46
47
  def query_with_id(*args)
47
- ids=args.flatten.map &:to_bson
48
+ ids=args.flatten.map do |id|
49
+ if id.kind_of? BSON::ObjectId
50
+ id
51
+ elsif id.kind_of? Hash and id['$oid']
52
+ BSON::ObjectId(id['$oid'])
53
+ else
54
+ BSON::ObjectId(id)
55
+ end
56
+ end
48
57
  if ids.size == 1
49
- return {:selector=>{"_id"=>ids.first}}
58
+ return {:query=>{"_id"=>ids.first}}
50
59
  else
51
- return {:selector=>{"_id"=>{"$in"=>ids}}}
60
+ return {:query=>{"_id"=>{"$in"=>ids}}}
52
61
  end
53
62
  end
63
+
54
64
  def query_fieldmode(type)
55
65
  return {:fieldmode=>type}
56
66
  end
@@ -80,5 +90,17 @@ CODE
80
90
 
81
91
  return {:extend_scoped => modules}
82
92
  end
93
+
94
+ def query_where(conditions)
95
+ return (query_conditions(conditions) + query_writeback(conditions))
96
+ end
97
+
98
+ def query_writeback(args=nil,&block)
99
+ if args
100
+ return {:writeback=>Splash::Writeback.cast(args)}
101
+ elsif block_given?
102
+ return {:writeback=>Splash::Writeback.cast(block)}
103
+ end
104
+ end
83
105
  end
84
- end
106
+ end
@@ -1,77 +1,28 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Splash
2
3
  module Saveable
3
- class Persister < Splash::Persister
4
- def write(value)
5
- return nil if value.nil?
6
- return value._id
7
- end
8
-
9
- def read(value)
10
- return nil if value.nil?
11
- return persisted_class.with_id(value).first
12
- end
13
- end
14
-
15
- class MultiPersister < Splash::Persister
16
- def write(value)
17
- return nil if value.nil?
18
- return BSON::DBRef.new(value.class.collection.name,value._id)
19
- end
20
-
21
- def read(value)
22
- return nil if value.nil?
23
- return @persisted_class.namespace.dereference(value)
24
- end
25
- end
26
-
27
- class EmbedPersister < Splash::Persister
28
- def write(value)
29
- return nil if value.nil?
30
- return Saveable.wrap(value)
31
- end
32
-
33
- def read(value)
34
- return nil if value.nil?
35
- return Saveable.load(value,persisted_class)
36
- end
37
- end
38
-
39
- self.persister= MultiPersister
40
-
41
4
 
42
5
  UPPERCASE=65..90
43
6
 
44
7
  class << self
45
- def included(base)
46
- base.extend(ClassMethods)
47
- base.persister=Splash::Saveable::Persister
48
- end
49
8
 
50
9
  def unwrap(keys)
51
10
  keys.inject({}) do |hsh,(key,val)| hsh[key]=val unless UPPERCASE.include? key[0]; hsh end
52
11
  end
53
12
 
54
13
  def wrap(object)
55
- object.to_saveable.merge("Type"=>Saveable.get_class_hierachie(object.class).map(&:to_s))
14
+ object.to_raw.merge("Type"=>Saveable.get_class_hierachie(object.class).map(&:to_s))
56
15
  end
57
16
 
58
17
  def load(keys,klass=Hash)
59
18
  if keys.nil?
60
19
  keys={}
61
20
  end
21
+ #puts klass
62
22
  if keys["Type"]
63
23
  klass = Kernel.eval(keys["Type"].first)
64
24
  end
65
- k = klass.new()
66
- k.attributes.load_raw(self.unwrap(keys))
67
- return k
68
- end
69
-
70
- def to_saveable(obj)
71
- if obj.respond_to? :to_saveable
72
- return obj.to_saveable
73
- end
74
- return obj
25
+ return klass.from_raw(self.unwrap(keys))
75
26
  end
76
27
 
77
28
  def get_class_hierachie(klass)
@@ -87,55 +38,5 @@ module Splash
87
38
  end
88
39
  end
89
40
 
90
- def namespace
91
- self.class.namespace
92
- end
93
-
94
- def storable_id
95
- self.attributes["_id"]
96
- end
97
-
98
- def store!
99
- self.attributes["_id"]=self.class.store!(self)
100
- return self
101
- end
102
-
103
- def remove!
104
- return self.class.collection.remove('_id'=>self._id)
105
- end
106
-
107
- def stored?
108
- return !storable_id.nil?
109
- end
110
-
111
- def find_self
112
- self.class.with_id(self.storable_id)
113
- end
114
-
115
- module ClassMethods
116
-
117
- def store!(object)
118
- return self.collection.save(
119
- Saveable.wrap(object)
120
- );
121
- end
122
-
123
- def namespace
124
- @namespace ||= Splash::NameSpace.default
125
- end
126
-
127
- def collection
128
- @collection ||= namespace.collection_for(self)
129
- end
130
-
131
- def [](*args)
132
- a=args.flatten
133
- if a.length == 1
134
- return with_id(a).first
135
- else
136
- return with_id(a).finish!
137
- end
138
- end
139
- end
140
41
  end
141
- end
42
+ end
data/lib/splash/scope.rb CHANGED
@@ -1,8 +1,8 @@
1
- require "delegate"
1
+ # -*- encoding : utf-8 -*-
2
2
  module Splash
3
3
  class Scope
4
4
 
5
- autoload :Options,Splash::DIR+"/splash/scope/options"
5
+ autoload_all File.join(File.dirname(__FILE__),'scope')
6
6
 
7
7
  include Splash::ActsAsScope
8
8
 
@@ -24,6 +24,19 @@ module Splash
24
24
  super
25
25
  end
26
26
 
27
+ def new(*args,&block)
28
+ obj = scope_root.new(*args,&block)
29
+ @scope_options.writeback(obj)
30
+ return obj
31
+ end
32
+
33
+ def create(*args,&block)
34
+ obj = scope_root.new(*args,&block)
35
+ @scope_options.writeback(obj)
36
+ obj.store!
37
+ return obj
38
+ end
39
+
27
40
  private
28
41
  def load_scope_extensions!
29
42
  unless @scope_extesions_loaded
@@ -43,4 +56,4 @@ module Splash
43
56
  end
44
57
 
45
58
  end
46
- end
59
+ end
@@ -0,0 +1,33 @@
1
+ module Splash
2
+
3
+ module Scope::MapReduceInterface
4
+
5
+ MAP_REDUCE_QUERY_KEYS = [:query,:sort,:limit].to_set
6
+
7
+
8
+ def map_reduce(map=nil,reduce=nil,opts={},&block)
9
+ if MAP_REDUCE_QUERY_KEYS.any?{|k| opts.key? k }
10
+ return self.query(opts.only(MAP_REDUCE_QUERY_KEYS)).map_reduce(map,reduce,opts.except(MAP_REDUCE_QUERY_KEYS))
11
+ end
12
+
13
+ if( opts[:out] || opts[:keeptemp] )
14
+ return Splash::MapReduce::Permanent.from_callback(self.method(:_map_reduce), map, reduce, opts, &block)
15
+ else
16
+ return Splash::MapReduce::Temporary.from_callback(self.method(:_map_reduce), map, reduce, opts, &block)
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def _map_reduce(map,reduce,opts)
23
+ opts = opts.dup
24
+ query, options = self.find_options
25
+ opts[:query] = query
26
+
27
+ return self.scope_root.collection.map_reduce(map,reduce,opts)
28
+ end
29
+
30
+ end
31
+
32
+
33
+ end
@@ -1,6 +1,7 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  class Splash::Scope::Options
2
3
 
3
- OPTION_KEYS=[:fields,:limit,:sort]
4
+ OPTION_KEYS=[:fields,:limit,:sort, :skip]
4
5
  def self.cast(hsh)
5
6
  if hsh.kind_of? self
6
7
  return hsh
@@ -9,7 +10,7 @@ class Splash::Scope::Options
9
10
  end
10
11
 
11
12
  def initialize(hsh=nil)
12
- @options={:selector=>{},:fieldmode=>:exclude,:extend_scoped=>[],:limit=>0,:sort=>[]}
13
+ @options={:query=>nil,:fieldmode=>:exclude,:extend_scoped=>[],:limit=>nil,:sort=>[],:writeback=>nil,:skip=>nil}
13
14
  @options.merge! hsh if hsh
14
15
  @options.freeze
15
16
  end
@@ -20,11 +21,13 @@ class Splash::Scope::Options
20
21
 
21
22
  def self.merge_options(a,b)
22
23
  return {
23
- :selector => a[:selector].deep_merge(b[:selector]),
24
+ :query => Splash::Matcher.and(a[:query],b[:query]),
24
25
  :fieldmode => (b[:fieldmode] || a[:fieldmode]),
25
26
  :extend_scoped => (a[:extend_scoped] + (b[:extend_scoped] || [])),
26
27
  :limit => (b[:limit] || a[:limit]),
27
- :sort => (a[:sort] + (b[:sort] || []))
28
+ :sort => (a[:sort] + (b[:sort] || [])),
29
+ :writeback => Splash::Writeback.merge(a[:writeback],b[:writeback]),
30
+ :skip => (b[:skip] || a[:skip])
28
31
  }
29
32
  end
30
33
 
@@ -37,7 +40,14 @@ class Splash::Scope::Options
37
40
  end
38
41
 
39
42
  def selector
40
- @options[:selector]
43
+ @options[:query] || Splash::Matcher.new
44
+ end
45
+
46
+ def writeback(to)
47
+ if @options[:writeback]
48
+ @options[:writeback].writeback(to)
49
+ end
50
+ return to
41
51
  end
42
52
 
43
53
  def options
@@ -55,4 +65,4 @@ class Splash::Scope::Options
55
65
  end
56
66
  return opt
57
67
  end
58
- end
68
+ end
@@ -0,0 +1,15 @@
1
+ module Splash
2
+
3
+ class UpdatedAt < Time
4
+
5
+ def self.initial_value
6
+ return Time.now
7
+ end
8
+
9
+ def self.before_write(value)
10
+ return Time.now
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require "set"
2
3
  module Splash::Validates
3
4
 
@@ -15,6 +16,7 @@ module Splash::Validates
15
16
 
16
17
  class << self
17
18
  def included(base)
19
+ super(base)
18
20
  base.instance_eval do
19
21
  merged_inheritable_attr :validators,Set.new
20
22
  end
@@ -72,4 +74,4 @@ module Splash::Validates
72
74
  end
73
75
 
74
76
 
75
- end
77
+ end