zeng 0.0.1 → 0.0.2

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 (44) hide show
  1. data/README.md +67 -0
  2. data/Rakefile +21 -19
  3. data/book.rb +23 -0
  4. data/{init.rb → lib/zeng.rb} +5 -1
  5. data/lib/{cute_kv → zeng}/adapters/tokyo_cabinet.rb +7 -6
  6. data/lib/zeng/adapters/tokyo_tyrant.rb +30 -0
  7. data/lib/zeng/connector.rb +28 -0
  8. data/lib/{cute_kv → zeng}/document.rb +7 -12
  9. data/lib/{cute_kv → zeng}/indexer.rb +2 -2
  10. data/spec/case/document_test.rb +174 -174
  11. data/spec/case/indexer_test.rb +31 -31
  12. data/spec/helper.rb +12 -14
  13. data/spec/model/Account.rb +3 -3
  14. data/spec/model/Book.rb +2 -2
  15. data/spec/model/Friend.rb +3 -3
  16. data/spec/model/Icon.rb +3 -3
  17. data/spec/model/Project.rb +2 -2
  18. data/spec/model/User.rb +3 -4
  19. metadata +26 -49
  20. data/README.rdoc +0 -89
  21. data/lib/cute_kv/adapters/light_cloud.rb +0 -22
  22. data/lib/cute_kv/adapters/tokyo_tyrant.rb +0 -22
  23. data/lib/cute_kv/associations.rb +0 -285
  24. data/lib/cute_kv/connector.rb +0 -27
  25. data/lib/cute_kv/ext/string.rb +0 -34
  26. data/lib/cute_kv/ext/symbol.rb +0 -9
  27. data/lib/cute_kv/serialization.rb +0 -95
  28. data/lib/cute_kv/serializers/json_serializer.rb +0 -75
  29. data/lib/cute_kv/serializers/xml_serializer.rb +0 -325
  30. data/lib/cute_kv/timestamp.rb +0 -56
  31. data/lib/cute_kv/validations.rb +0 -68
  32. data/lib/cutekv.rb +0 -17
  33. data/spec/asso.yml +0 -23
  34. data/spec/asso_sin_plural.yml +0 -36
  35. data/spec/case/associations_test.rb +0 -313
  36. data/spec/case/document_docking_test.rb +0 -103
  37. data/spec/case/serialization_test.rb +0 -78
  38. data/spec/case/sin_plu_dic_test.rb +0 -29
  39. data/spec/case/symmetry_test.rb +0 -80
  40. data/spec/case/timestamp_test.rb +0 -65
  41. data/spec/case/validations_test.rb +0 -74
  42. data/spec/light_cloud.yml +0 -9
  43. data/spec/model/Topic.rb +0 -26
  44. data/tags +0 -322
@@ -1,27 +0,0 @@
1
- module CuteKV
2
- class Connector
3
- def self.config(adapter)
4
- case adapter.to_sym
5
- when :TC
6
- require 'cute_kv/adapters/tokyo_cabinet'
7
- include CuteKV::Adapters::TokyoCabinet
8
- when :TT
9
- require 'cute_kv/adapters/tokyo_tyrant'
10
- include CuteKV::Adapters::TokyoTyrant
11
- when :LC
12
- require 'cute_kv/adapters/light_cloud'
13
- include CuteKV::Adapters::TokyoCloud
14
- else
15
- raise ConfigError,'没有指定数据库类型!'
16
- end
17
- end
18
-
19
- def initialize(adapter, conf)
20
- @adapter = adapter
21
- self.class.config(adapter)
22
- establish(conf)
23
- end
24
-
25
- end
26
-
27
- end
@@ -1,34 +0,0 @@
1
- class String
2
-
3
- def plural?
4
- (Dic::PLU_WORDS.include?(self) || self.pluralize == self) && !Dic::SIN_WORDS.include?(self)
5
- end
6
-
7
- def singular?
8
- (Dic::SIN_WORDS.include?(self) || self.singularize == self) && !Dic::PLU_WORDS.include?(self)
9
- end
10
-
11
- end
12
-
13
- module WordAct
14
- def add(words)
15
- if words.is_a? Array
16
- words.each {|w| self.add(w.to_s)}
17
- else
18
- self << words.to_s
19
- Dic::Mirror[self].delete(words.to_s)
20
- self.uniq!
21
- end
22
- end
23
-
24
- def hash
25
- self.object_id
26
- end
27
- end
28
-
29
- module Dic
30
- (SIN_WORDS = []).extend(WordAct)
31
- (PLU_WORDS = []).extend(WordAct)
32
- Mirror = {SIN_WORDS=>PLU_WORDS, PLU_WORDS=>SIN_WORDS}
33
- end
34
-
@@ -1,9 +0,0 @@
1
- class Symbol
2
- def plural?
3
- self.to_s.plural?
4
- end
5
-
6
- def singular?
7
- self.to_s.singular?
8
- end
9
- end
@@ -1,95 +0,0 @@
1
- module CuteKV#:nodoc:
2
- module Serialization
3
- class Serializer #:nodoc:
4
- attr_reader :options
5
-
6
- def initialize(object, options = {})
7
- @object, @options = object, options.dup
8
- end
9
-
10
- # To replicate the behavior in ActiveObject#attributes,
11
- # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
12
- # for a N level model but is set for the N+1 level models,
13
- # then because <tt>:except</tt> is set to a default value, the second
14
- # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
15
- # <tt>:only</tt> is set, always delete <tt>:except</tt>.
16
- def serializable_attribute_names
17
- attribute_names = @object.assigned_attributes.collect {|n| n.to_s} << "id"
18
-
19
- if options[:only]
20
- options.delete(:except)
21
- attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
22
- else
23
- options[:except] = Array(options[:except])
24
- attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
25
- end
26
-
27
- attribute_names
28
- end
29
-
30
- def serializable_method_names
31
- Array(options[:methods]).inject([]) do |method_attributes, name|
32
- method_attributes << name if @object.respond_to?(name.to_s)
33
- method_attributes
34
- end
35
- end
36
-
37
- def serializable_names
38
- serializable_attribute_names + serializable_method_names
39
- end
40
-
41
- # Add associations specified via the <tt>:includes</tt> option.
42
- # Expects a block that takes as arguments:
43
- # +association+ - name of the association
44
- # +objects+ - the association object(s) to be serialized
45
- # +opts+ - options for the association objects
46
- def add_includes(&block)
47
- if include_associations = options.delete(:include)
48
- base_only_or_except = { :except => options[:except],
49
- :only => options[:only] }
50
-
51
- include_has_options = include_associations.is_a?(Hash)
52
- associations = include_has_options ? include_associations.keys : Array(include_associations)
53
-
54
- for association in associations
55
- objects = @object.send association
56
-
57
- unless objects.nil?
58
- association_options = include_has_options ? include_associations[association] : base_only_or_except
59
- opts = options.merge(association_options)
60
- yield(association, objects, opts)
61
- end
62
- end
63
-
64
- options[:include] = include_associations
65
- end
66
- end
67
-
68
- def serializable_object
69
- returning(serializable_object = {}) do
70
- serializable_names.each { |name| serializable_object[name] = @object.send(name) }
71
-
72
- add_includes do |association, objects, opts|
73
- if objects.is_a?(Enumerable)
74
- serializable_object[association] = objects.collect { |r| self.class.new(r, opts).serializable_object }
75
- else
76
- serializable_object[association] = self.class.new(objects, opts).serializable_object
77
- end
78
-
79
- end
80
- end
81
- end
82
-
83
- def serialize
84
- # overwrite to implement
85
- end
86
-
87
- def to_s(&block)
88
- serialize(&block)
89
- end
90
- end
91
- end
92
- end
93
-
94
- require 'cute_kv/serializers/xml_serializer'
95
- require 'cute_kv/serializers/json_serializer'
@@ -1,75 +0,0 @@
1
- module CuteKV#:nodoc:
2
- module Serialization
3
- def self.included(base)
4
- base.cattr_accessor :include_root_in_json, :instance_writer => false
5
- base.extend ClassMethods
6
- end
7
-
8
- # Returns a JSON string representing the model. Some configuration is
9
- # available through +options+.
10
- #
11
- # Without any +options+, the returned JSON string will include all
12
- # the model's attributes. For example:
13
- #
14
- # konata = User.find(1)
15
- # konata.to_json
16
- # # => {"id": 1, "name": "Konata Izumi", "age": 16,
17
- # "created_at": "2006/08/01", "awesome": true}
18
- #
19
- # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
20
- # included, and work similar to the +attributes+ method. For example:
21
- #
22
- # konata.to_json(:only => [ :id, :name ])
23
- # # => {"id": 1, "name": "Konata Izumi"}
24
- #
25
- # konata.to_json(:except => [ :id, :created_at, :age ])
26
- # # => {"name": "Konata Izumi", "awesome": true}
27
- #
28
- # To include any methods on the model, use <tt>:methods</tt>.
29
- #
30
- # konata.to_json(:methods => :permalink)
31
- # # => {"id": 1, "name": "Konata Izumi", "age": 16,
32
- # "created_at": "2006/08/01", "awesome": true,
33
- # "permalink": "1-konata-izumi"}
34
- #
35
- # To include associations, use <tt>:include</tt>.
36
- #
37
- # konata.to_json(:include => :posts)
38
- # # => {"id": 1, "name": "Konata Izumi", "age": 16,
39
- # "created_at": "2006/08/01", "awesome": true,
40
- # "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
41
- # {"id": 2, author_id: 1, "title": "So I was thinking"}]}
42
- #
43
- # 2nd level and higher order associations work as well:
44
- #
45
- # konata.to_json(:include => { :posts => {
46
- # :include => { :comments => {
47
- # :only => :body } },
48
- # :only => :title } })
49
- # # => {"id": 1, "name": "Konata Izumi", "age": 16,
50
- # "created_at": "2006/08/01", "awesome": true,
51
- # "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
52
- # "title": "Welcome to the weblog"},
53
- # {"comments": [{"body": "Don't think too hard"}],
54
- # "title": "So I was thinking"}]}
55
- def to_json(options = {})
56
- if include_root_in_json
57
- "{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
58
- else
59
- JsonSerializer.new(self, options).to_s
60
- end
61
- end
62
-
63
- class JsonSerializer < CuteKV::Serialization::Serializer #:nodoc:
64
- def serialize
65
- serializable_object.to_json
66
- end
67
- end
68
-
69
- module ClassMethods
70
- def json_class_name
71
- @json_class_name ||= name.demodulize.underscore.inspect
72
- end
73
- end
74
- end
75
- end
@@ -1,325 +0,0 @@
1
- module CuteKV#:nodoc:
2
- module Serialization
3
- # Builds an XML document to represent the model. Some configuration is
4
- # available through +options+. However more complicated cases should
5
- # override ActiveObject::Base#to_xml.
6
- #
7
- # By default the generated XML document will include the processing
8
- # instruction and all the object's attributes. For example:
9
- #
10
- # <?xml version="1.0" encoding="UTF-8"?>
11
- # <topic>
12
- # <title>The First Topic</title>
13
- # <author-name>David</author-name>
14
- # <id type="integer">1</id>
15
- # <approved type="boolean">false</approved>
16
- # <replies-count type="integer">0</replies-count>
17
- # <bonus-time type="datetime">2000-01-01T08:28:00+12:00</bonus-time>
18
- # <written-on type="datetime">2003-07-16T09:28:00+1200</written-on>
19
- # <content>Have a nice day</content>
20
- # <author-email-address>david@loudthinking.com</author-email-address>
21
- # <parent-id></parent-id>
22
- # <last-read type="date">2004-04-15</last-read>
23
- # </topic>
24
- #
25
- # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
26
- # <tt>:skip_instruct</tt>, <tt>:skip_types</tt> and <tt>:dasherize</tt>.
27
- # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
28
- # +attributes+ method. The default is to dasherize all column names, but you
29
- # can disable this setting <tt>:dasherize</tt> to +false+. To not have the
30
- # column type included in the XML output set <tt>:skip_types</tt> to +true+.
31
- #
32
- # For instance:
33
- #
34
- # topic.to_xml(:skip_instruct => true, :except => [ :id, :bonus_time, :written_on, :replies_count ])
35
- #
36
- # <topic>
37
- # <title>The First Topic</title>
38
- # <author-name>David</author-name>
39
- # <approved type="boolean">false</approved>
40
- # <content>Have a nice day</content>
41
- # <author-email-address>david@loudthinking.com</author-email-address>
42
- # <parent-id></parent-id>
43
- # <last-read type="date">2004-04-15</last-read>
44
- # </topic>
45
- #
46
- # To include first level associations use <tt>:include</tt>:
47
- #
48
- # firm.to_xml :include => [ :account, :clients ]
49
- #
50
- # <?xml version="1.0" encoding="UTF-8"?>
51
- # <firm>
52
- # <id type="integer">1</id>
53
- # <rating type="integer">1</rating>
54
- # <name>37signals</name>
55
- # <clients type="array">
56
- # <client>
57
- # <rating type="integer">1</rating>
58
- # <name>Summit</name>
59
- # </client>
60
- # <client>
61
- # <rating type="integer">1</rating>
62
- # <name>Microsoft</name>
63
- # </client>
64
- # </clients>
65
- # <account>
66
- # <id type="integer">1</id>
67
- # <credit-limit type="integer">50</credit-limit>
68
- # </account>
69
- # </firm>
70
- #
71
- # To include deeper levels of associations pass a hash like this:
72
- #
73
- # firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
74
- # <?xml version="1.0" encoding="UTF-8"?>
75
- # <firm>
76
- # <id type="integer">1</id>
77
- # <rating type="integer">1</rating>
78
- # <name>37signals</name>
79
- # <clients type="array">
80
- # <client>
81
- # <rating type="integer">1</rating>
82
- # <name>Summit</name>
83
- # <address>
84
- # ...
85
- # </address>
86
- # </client>
87
- # <client>
88
- # <rating type="integer">1</rating>
89
- # <name>Microsoft</name>
90
- # <address>
91
- # ...
92
- # </address>
93
- # </client>
94
- # </clients>
95
- # <account>
96
- # <id type="integer">1</id>
97
- # <credit-limit type="integer">50</credit-limit>
98
- # </account>
99
- # </firm>
100
- #
101
- # To include any methods on the model being called use <tt>:methods</tt>:
102
- #
103
- # firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
104
- #
105
- # <firm>
106
- # # ... normal attributes as shown above ...
107
- # <calculated-earnings>100000000000000000</calculated-earnings>
108
- # <real-earnings>5</real-earnings>
109
- # </firm>
110
- #
111
- # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
112
- # modified version of the options hash that was given to +to_xml+:
113
- #
114
- # proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
115
- # firm.to_xml :procs => [ proc ]
116
- #
117
- # <firm>
118
- # # ... normal attributes as shown above ...
119
- # <abc>def</abc>
120
- # </firm>
121
- #
122
- # Alternatively, you can yield the builder object as part of the +to_xml+ call:
123
- #
124
- # firm.to_xml do |xml|
125
- # xml.creator do
126
- # xml.first_name "David"
127
- # xml.last_name "Heinemeier Hansson"
128
- # end
129
- # end
130
- #
131
- # <firm>
132
- # # ... normal attributes as shown above ...
133
- # <creator>
134
- # <first_name>David</first_name>
135
- # <last_name>Heinemeier Hansson</last_name>
136
- # </creator>
137
- # </firm>
138
- #
139
- # As noted above, you may override +to_xml+ in your ActiveObject::Base
140
- # subclasses to have complete control about what's generated. The general
141
- # form of doing this is:
142
- #
143
- # class IHaveMyOwnXML < ActiveObject::Base
144
- # def to_xml(options = {})
145
- # options[:indent] ||= 2
146
- # xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
147
- # xml.instruct! unless options[:skip_instruct]
148
- # xml.level_one do
149
- # xml.tag!(:second_level, 'content')
150
- # end
151
- # end
152
- # end
153
- def to_xml(options = {}, &block)
154
- serializer = XmlSerializer.new(self, options)
155
- block_given? ? serializer.to_s(&block) : serializer.to_s
156
- end
157
-
158
- end
159
-
160
- class XmlSerializer < CuteKV::Serialization::Serializer #:nodoc:
161
- def builder
162
- @builder ||= begin
163
- options[:indent] ||= 2
164
- builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
165
-
166
- unless options[:skip_instruct]
167
- builder.instruct!
168
- options[:skip_instruct] = true
169
- end
170
-
171
- builder
172
- end
173
- end
174
-
175
- def root
176
- root = (options[:root] || @object.class.to_s.underscore).to_s
177
- dasherize? ? root.dasherize : root
178
- end
179
-
180
- def dasherize?
181
- !options.has_key?(:dasherize) || options[:dasherize]
182
- end
183
-
184
- def serializable_attributes
185
- serializable_attribute_names.collect { |name| Attribute.new(name.to_s, @object) }
186
- end
187
-
188
- def serializable_method_attributes
189
- Array(options[:methods]).inject([]) do |method_attributes, name|
190
- method_attributes << MethodAttribute.new(name.to_s, @object) if @object.respond_to?(name.to_s)
191
- method_attributes
192
- end
193
- end
194
-
195
- def add_attributes
196
- (serializable_attributes + serializable_method_attributes).each do |attribute|
197
- add_tag(attribute)
198
- end
199
- end
200
-
201
- def add_procs
202
- if procs = options.delete(:procs)
203
- [ *procs ].each do |proc|
204
- proc.call(options)
205
- end
206
- end
207
- end
208
-
209
- def add_tag(attribute)
210
- builder.tag!(
211
- dasherize? ? attribute.name.dasherize : attribute.name,
212
- attribute.value.to_s,
213
- attribute.decorations(!options[:skip_types])
214
- )
215
- end
216
-
217
- def add_associations(association, objects, opts)
218
- if objects.is_a?(Enumerable)
219
- tag = association.to_s
220
- tag = tag.dasherize if dasherize?
221
- if objects.empty?
222
- builder.tag!(tag, :type => :array)
223
- else
224
- builder.tag!(tag, :type => :array) do
225
- association_name = association.to_s.singularize
226
- objects.each do |object|
227
- object.to_xml opts.merge(
228
- :root => association_name,
229
- :type => (object.class.to_s.underscore == association_name ? nil : object.class.name)
230
- )
231
- end
232
- end
233
- end
234
- else
235
- if object = @object.send(association)
236
- object.to_xml(opts.merge(:root => association))
237
- end
238
- end
239
- end
240
-
241
- def serialize
242
- args = [root]
243
- if options[:namespace]
244
- args << {:xmlns=>options[:namespace]}
245
- end
246
-
247
- if options[:type]
248
- args << {:type=>options[:type]}
249
- end
250
-
251
- builder.tag!(*args) do
252
- add_attributes
253
- procs = options.delete(:procs)
254
- add_includes { |association, objects, opts| add_associations(association, objects, opts) }
255
- options[:procs] = procs
256
- add_procs
257
- yield builder if block_given?
258
- end
259
- end
260
-
261
- class Attribute #:nodoc:
262
- attr_reader :name, :value, :type
263
-
264
- def initialize(name, object)
265
- @name, @object = name, object
266
-
267
- @type = compute_type
268
- @value = compute_value
269
- end
270
-
271
- # There is a significant speed improvement if the value
272
- # does not need to be escaped, as <tt>tag!</tt> escapes all values
273
- # to ensure that valid XML is generated. For known binary
274
- # values, it is at least an order of magnitude faster to
275
- # Base64 encode binary values and directly put them in the
276
- # output XML than to pass the original value or the Base64
277
- # encoded value to the <tt>tag!</tt> method. It definitely makes
278
- # no sense to Base64 encode the value and then give it to
279
- # <tt>tag!</tt>, since that just adds additional overhead.
280
- def needs_encoding?
281
- ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
282
- end
283
-
284
- def decorations(include_types = true)
285
- decorations = {}
286
-
287
- if type == :binary
288
- decorations[:encoding] = 'base64'
289
- end
290
-
291
- if include_types && type != :string
292
- decorations[:type] = type
293
- end
294
-
295
- if value.nil?
296
- decorations[:nil] = true
297
- end
298
-
299
- decorations
300
- end
301
-
302
- protected
303
- def compute_type
304
- type = @object.send(name).class
305
- end
306
-
307
- def compute_value
308
- value = @object.send(name)
309
-
310
- if formatter = Hash::XML_FORMATTING[type.to_s]
311
- value ? formatter.call(value) : nil
312
- else
313
- value
314
- end
315
- end
316
- end
317
-
318
- class MethodAttribute < Attribute #:nodoc:
319
- protected
320
- def compute_type
321
- Hash::XML_TYPE_NAMES[@object.send(name).class.name] || :string
322
- end
323
- end
324
- end
325
- end