lstoll-bumble 0.0.1

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 (3) hide show
  1. data/lib/bumble.rb +1 -0
  2. data/lib/bumble/bumble.rb +205 -0
  3. metadata +61 -0
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/bumble/bumble'
@@ -0,0 +1,205 @@
1
+ require 'java'
2
+ require 'time'
3
+
4
+ module Bumble
5
+ module DS
6
+ import com.google.appengine.api.datastore.DatastoreServiceFactory
7
+ import com.google.appengine.api.datastore.Entity
8
+ import com.google.appengine.api.datastore.FetchOptions
9
+ import com.google.appengine.api.datastore.KeyFactory
10
+ import com.google.appengine.api.datastore.Key
11
+ import com.google.appengine.api.datastore.EntityNotFoundException
12
+ import com.google.appengine.api.datastore.Query
13
+ import com.google.appengine.api.datastore.Text
14
+ Service = DatastoreServiceFactory.datastore_service
15
+ end
16
+
17
+ module InstanceMethods
18
+ def initialize attrs = {}, *args
19
+ super *args
20
+ @__entity = DS::Entity.new self.class.name
21
+ @new_record = true
22
+ attrs.each do |k,v|
23
+ self.send "#{k}=", v
24
+ end
25
+ end
26
+
27
+ def key
28
+ __ds_key.get_id
29
+ end
30
+
31
+ def to_param
32
+ self.key
33
+ end
34
+
35
+ def save!
36
+ if @new_record
37
+ self.created_at = Time.now if respond_to? :created_at=
38
+ @new_record = false
39
+ end
40
+ self.updated_at = Time.now if respond_to? :updated_at=
41
+ DS::Service.put(@__entity)
42
+ end
43
+
44
+ def delete!
45
+ self.class.delete key
46
+ end
47
+
48
+ def properties
49
+ res = {'key' => key}
50
+ @__entity.get_properties.each do |k,v|
51
+ res[k] = v.is_a?(DS::Text) ? v.value : v
52
+ end
53
+ res
54
+ end
55
+
56
+ def == object
57
+ object.respond_to?(:properties) && object.properties == properties
58
+ end
59
+
60
+ def __ds_key
61
+ @__entity.key
62
+ end
63
+
64
+ def __ds_get name
65
+ name = name.to_s
66
+ if @__entity.has_property(name)
67
+ ret = @__entity.get_property(name)
68
+ return ret.value if ret.is_a? DS::Text
69
+ return Time.parse ret.to_s if ret.is_a? Java::JavaUtil::Date
70
+ ret
71
+ end
72
+ end
73
+
74
+ def __ds_set name, value
75
+ value = DS::Text.new value if value.is_a?(String) && value.length > 499
76
+ @__entity.set_property name.to_s, value
77
+ end
78
+ end
79
+
80
+ module ClassMethods
81
+ def has_many(attr, type, key = nil, options = {})
82
+ key ||= "#{self.to_s.downcase}_id"
83
+ type_name = (type.is_a?(Symbol) || type.is_a?(String)) ? type : type.name
84
+ self.class_eval <<DEF
85
+ def #{attr}
86
+ #{type_name}.all({#{key.inspect} => self.key}, #{options.inspect})
87
+ end
88
+ DEF
89
+ end
90
+
91
+ def belongs_to attr, type = nil
92
+ type ||= attr.to_s.capitalize
93
+ self.ds "#{attr}_id"
94
+ type_name = (type.is_a?(Symbol) || type.is_a?(String)) ? type : type.name
95
+ self.class_eval <<DEF
96
+ def #{attr}
97
+ if defined?(@#{attr})
98
+ @#{attr}
99
+ else
100
+ @#{attr} = if self.#{attr}_id
101
+ #{type_name}.get(self.#{attr}_id)
102
+ else
103
+ nil
104
+ end
105
+ end
106
+ end
107
+
108
+ def #{attr}=(value)
109
+ self.#{attr}_id = value.key
110
+ @#{attr} = value
111
+ end
112
+ DEF
113
+ end
114
+
115
+ # defines zero or more data store attributes - will create attribute accessors for these
116
+ def ds(*names)
117
+ names.each do |name|
118
+ self.class_eval <<DEF
119
+ def #{name}
120
+ if defined?(@#{name})
121
+ @#{name}
122
+ else
123
+ @#{name} = __ds_get(#{name.inspect})
124
+ end
125
+ end
126
+
127
+ def #{name}=(value)
128
+ __ds_set(#{name.inspect}, value)
129
+ @#{name} = value
130
+ end
131
+ DEF
132
+ end
133
+ end
134
+
135
+ def get key
136
+ if key.is_a? Array
137
+ create_from_entities DS::Service.get(key.map{|k| DS::KeyFactory.create_key self.name, k.to_i}).values
138
+ else
139
+ create_from_entity(DS::Service.get(DS::KeyFactory.create_key(self.name, key.to_i)))
140
+ end
141
+ end
142
+ alias :[] :get
143
+
144
+ def delete key
145
+ DS::Service.delete([DS::KeyFactory.create_key(self.name, key.to_i)].to_java(DS::Key))
146
+ end
147
+
148
+ def first conditions = {}
149
+ query = build_query_from_conditions conditions
150
+ result = DS::Service.prepare(query).as_single_entity
151
+ create_from_entity(result) if result
152
+ end
153
+
154
+ def create attrs = {}
155
+ val = new(attrs)
156
+ val.save!
157
+ val
158
+ end
159
+
160
+ def all conditions = {}, options = {}
161
+ q = build_query_from_conditions conditions
162
+ fo = DS::FetchOptions::Builder.with_limit options[:limit] if options[:limit]
163
+ if options[:offset]
164
+ fo ? (fo.offset options[:offset]) : (fo = DS::FetchOptions::Builder.with_offset options[:offset])
165
+ end
166
+ q.add_sort options[:order].to_s if options[:order]
167
+ q.add_sort options[:iorder].to_s, DS::Query::SortDirection::DESCENDING if options[:iorder]
168
+ iter = DS::Service.prepare q
169
+ iter = fo ? (iter.as_iterable fo) : iter.as_iterable
170
+ create_from_entities iter
171
+ end
172
+
173
+ def count
174
+ q = DS::Query.new self.name
175
+ DS::Service.prepare(q).count_entities
176
+ end
177
+
178
+ private
179
+ def create_from_entity ent
180
+ obj = self.new
181
+ obj.instance_variable_set :@__entity, ent
182
+ obj.instance_variable_set :@new_record, false
183
+ obj
184
+ end
185
+
186
+ def create_from_entities collection
187
+ collection.map do |ent|
188
+ create_from_entity ent
189
+ end
190
+ end
191
+
192
+ def build_query_from_conditions conditions
193
+ query = DS::Query.new self.name
194
+ conditions.each do |k, v|
195
+ query.add_filter k.to_s, DS::Query::FilterOperator::EQUAL, v
196
+ end
197
+ query
198
+ end
199
+ end
200
+
201
+ def self.included base
202
+ base.send :include, InstanceMethods
203
+ base.send :extend, ClassMethods
204
+ end
205
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lstoll-bumble
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ola Bini
8
+ - Ivan Schneider
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-05-06 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Wrapper for google app engine's data store
18
+ email: lstoll@lstoll.net
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - lib/bumble.rb
27
+ - lib/bumble/bumble.rb
28
+ has_rdoc: true
29
+ homepage: http://github.com/olabini/buble
30
+ post_install_message:
31
+ rdoc_options:
32
+ - --inline-source
33
+ - --charset=UTF-8
34
+ - --main
35
+ - README.rdoc
36
+ - --title
37
+ - Ruby Goole AppEngine Support
38
+ - lib
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.2.0
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: Wrapper for google app engine's data store
60
+ test_files: []
61
+