splash 0.0.1.alpha → 0.0.1.beta

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