document_record 0.0.14 → 0.0.17

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.
@@ -1,28 +1,67 @@
1
1
  require 'document_hash'
2
+ require 'bson'
2
3
 
3
4
  module DocumentRecord
4
5
  module Serializer
5
- def self.dump object
6
- Base64.encode64 Marshal.dump object
6
+ MARSHALL_VERSION = 0
7
+ MESSAGEPACK_VERSION = 1
8
+ DEFAULT_VERSION = 1
9
+
10
+ def self.dump object, options = {}
11
+ version = DEFAULT_VERSION
12
+ version = options[:force_version] if options.has_key? :force_version
13
+
14
+ binary_dump =
15
+ case version
16
+ when 0 then
17
+ Marshal.dump object
18
+ when 1 then
19
+ object.to_hash.to_bson
20
+ else
21
+ raise "No serialization version found: #{ version }"
22
+ end
23
+
24
+ unless options.has_key? :no_version and options[:no_version]
25
+ stamp = [68, 82, version].pack 'c2S' # DR<version> In 4 bits
26
+ binary_dump.insert( 0, stamp )
27
+ end
28
+
29
+ Base64.encode64 binary_dump
7
30
  end
8
31
  def self.load data
9
- Marshal.load Base64.decode64 data rescue nil
32
+ decoded = Base64.decode64 data rescue nil
33
+ version = 0
34
+
35
+ if decoded.start_with? "DR" # Has version Stamp
36
+ version = decoded[2,2].unpack('S').pop # Gets the Version
37
+ decoded[0...4] = '' # Removes version stamp
38
+ end
39
+
40
+ case version
41
+ when 0 then
42
+ Marshal.load decoded rescue nil
43
+ when 1 then
44
+ Hash.from_bson( StringIO.new( decoded ) )
45
+ else
46
+ raise "Unrecognized version #{version}"
47
+ end
10
48
  end
11
49
  end
12
50
 
13
51
  module Base
14
52
  extend ActiveSupport::Concern
15
53
 
16
- def document_field name
54
+ def document_field name, options = {}
17
55
  raise "Field must exist in record in order to become a document field" unless column_names.include? name.to_s
18
- @@_document_field_name = name
19
- @@_index_fields ||= []
20
-
21
56
  class_eval do
22
57
  alias_method :regular_assign_attributes, :assign_attributes
23
58
  alias_method :regular_method_missing, :method_missing
24
59
  alias_method :regular_save, :save
25
60
 
61
+ @@_document_field_name = name
62
+ @@_schema_fields = options[:schema_fields] || []
63
+ @@_index_fields ||= []
64
+
26
65
  def read_serialized_hash_attribute field_name
27
66
  raw = read_attribute field_name
28
67
  raw && Serializer.load( raw ) || {}
@@ -61,7 +100,7 @@ module DocumentRecord
61
100
  end
62
101
 
63
102
  def touch!
64
- document.touch!
103
+ self.document.touch!
65
104
  save
66
105
  end
67
106
 
@@ -71,15 +110,37 @@ module DocumentRecord
71
110
 
72
111
  def assign_attributes new_attributes, options
73
112
  new_attributes.each do | key, value |
74
- self.send "#{key}=".to_sym, value
113
+ assign_key = :"#{key}="
114
+ method_missing assign_key, value
115
+ self.send assign_key, value if self.respond_to? assign_key
75
116
  end
76
117
  end
77
118
 
78
119
  def method_missing method, *args
79
120
  if method =~ /(.*)=$/
80
- document[$1] = args.shift
121
+ write_document $1, args.shift
122
+ else
123
+ read_document method.to_s
124
+ end
125
+ end
126
+
127
+ def is_schema_field? attribute
128
+ @@_schema_fields.include? attribute.to_sym
129
+ end
130
+
131
+ def read_document attribute
132
+ if is_schema_field? attribute
133
+ read_attribute attribute
134
+ else
135
+ document[attribute] || read_attribute(attribute)
136
+ end
137
+ end
138
+
139
+ def write_document attribute, value
140
+ if is_schema_field? attribute
141
+ write_attribute attribute, value
81
142
  else
82
- document[method.to_s]
143
+ document[attribute] = value
83
144
  end
84
145
  end
85
146
 
@@ -88,17 +149,61 @@ module DocumentRecord
88
149
  end
89
150
 
90
151
  def as_json options = {}
91
- ( read_serialized_hash_attribute(@@_document_field_name) || {} ).merge(super.reject{ |k, v| k === @@_document_field_name.to_s })
152
+ included_fields = super.select{ |k, v|
153
+ @@_schema_fields.include?( k.to_sym )
154
+ }.stringify_keys!
155
+
156
+ document.to_hash( stringify_keys: true ).
157
+ merge( included_fields ).
158
+ merge( method_values(options) )
159
+ end
160
+
161
+ def method_values options
162
+ {}.tap do | result |
163
+ return result unless options[:methods].is_a? Array
164
+ options[:methods].each do | method |
165
+ result[method] = self.__send__(method)
166
+ end
167
+ end
168
+ end
169
+
170
+
171
+ def _deep_key_values hash = nil, path = []
172
+ hash = document.to_hash unless hash
173
+ result = []
174
+
175
+ hash.each do | k, v |
176
+ current = path.dup
177
+
178
+ current << k
179
+ if v.is_a? Hash
180
+ result += _deep_key_values hash[ k ], current
181
+ else
182
+ result += [ current.join("_"), v ]
183
+ end
184
+ end
185
+ result
186
+ end
187
+
188
+ def deep_key_values
189
+ Hash[*_deep_key_values]
92
190
  end
93
- end
191
+
192
+ def deep_keys
193
+ deep_key_values.keys
194
+ end
195
+ end
94
196
 
95
197
  column_names.each do |column|
96
198
  class_eval <<-METHOD
97
199
  def #{column}
98
- document["#{column}"] || read_attribute("#{column}")
200
+ # document["#{column}"] || read_attribute("#{column}")
201
+ read_document "#{ column }"
99
202
  end
203
+
100
204
  def #{column}= value
101
- document["#{column}"] = value
205
+ # document["#{column}"] = value
206
+ write_document "#{ column }", value
102
207
  end
103
208
  METHOD
104
209
  end
@@ -1,3 +1,3 @@
1
1
  module DocumentRecord
2
- VERSION = "0.0.14"
2
+ VERSION = "0.0.17"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: document_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.17
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-08 00:00:00.000000000 Z
12
+ date: 2015-05-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: document_hash
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.0.13
21
+ version: 0.0.15
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 0.0.13
29
+ version: 0.0.15
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rails
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  version: 3.2.11
46
+ - !ruby/object:Gem::Dependency
47
+ name: bson
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 3.0.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.1
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: sqlite3
48
64
  requirement: !ruby/object:Gem::Requirement