bigbertha 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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ Nzk1YTdiNTBlYTE1NDlmMzVlZWI4MTA0MDQzODU3ZDRlYzQ1NzAyZA==
5
+ data.tar.gz: !binary |-
6
+ ZGVlNjFkMDQxZGZjOGEwYmM2OTQxMjBhZjEwYzRhMmVjOWExZGFhNQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MDU1YzFmYzJiNjNkNTk0MmFlMjU2ZTFjMjQyYTMzZTQ3OTEwNDliMTZiZTI4
10
+ N2NkZDlhMzEwNmRlZmUwZjk4ZGMzZGFmNGVmOGNjMWZkNzMxMTIxNTZkNjIw
11
+ ZTI5NjM2ZDQxMDVhNWIwYWZiYmQ3MDM3NTUyYzc4NDE3YzE3ZjA=
12
+ data.tar.gz: !binary |-
13
+ YWU5YTQyNGI2YTAzZDI3NWFkMjM5NjQwZGU3NmM3MTBkYzAzMDA1YjNhODM0
14
+ ZjAzMjZiNzRmMzNmZjBmOGU5MWZkYTdmYmFiNmMwOTU0M2MzOTg3MDI5YzE0
15
+ ZGQ1ODM3NTE3MjE1NTkzOTUzMzNjMDM3N2UxYmE3ZDZkNThjYjE=
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'map'
4
+ gem 'typhoeus'
5
+ gem 'values'
6
+
7
+ group 'test' do
8
+ gem "autotest"
9
+ gem "autotest-growl"
10
+ gem 'rspec'
11
+ gem 'simplecov'
12
+ end
@@ -0,0 +1,42 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ ZenTest (4.9.0)
5
+ autotest (4.4.6)
6
+ ZenTest (>= 4.4.1)
7
+ autotest-growl (0.2.16)
8
+ diff-lcs (1.2.1)
9
+ ethon (0.5.10)
10
+ ffi (~> 1.3.0)
11
+ mime-types (~> 1.18)
12
+ ffi (1.3.1)
13
+ map (6.3.0)
14
+ mime-types (1.21)
15
+ multi_json (1.7.2)
16
+ rspec (2.13.0)
17
+ rspec-core (~> 2.13.0)
18
+ rspec-expectations (~> 2.13.0)
19
+ rspec-mocks (~> 2.13.0)
20
+ rspec-core (2.13.1)
21
+ rspec-expectations (2.13.0)
22
+ diff-lcs (>= 1.1.3, < 2.0)
23
+ rspec-mocks (2.13.0)
24
+ simplecov (0.7.1)
25
+ multi_json (~> 1.0)
26
+ simplecov-html (~> 0.7.1)
27
+ simplecov-html (0.7.1)
28
+ typhoeus (0.6.2)
29
+ ethon (~> 0.5.10)
30
+ values (1.5.0)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ autotest
37
+ autotest-growl
38
+ map
39
+ rspec
40
+ simplecov
41
+ typhoeus
42
+ values
@@ -0,0 +1,322 @@
1
+ # BigBertha - Ruby firepower for your Firebase battery
2
+
3
+ Firebase is a real-time backend that allows one to store key-value pairs in a hierarchical fashion, without
4
+ having to manage additional servers. Firebase offers api's for a variety of client libs such as javascript,
5
+ REST, IOS and now Ruby ;-). A cool feature of firebase is that it allows disparate clients to broadcast updates and
6
+ sync up across the wire. Checkout http://firebase.com for the firehose...
7
+
8
+
9
+ ## Requirements
10
+
11
+ - Ruby >= 1.9
12
+ - Map
13
+ - Typhoeus
14
+
15
+ ## Getting Started
16
+
17
+ $ gem install bigbertha
18
+
19
+ ## Usage
20
+
21
+ ### Setup your Firebase
22
+
23
+ Sign up for a firebase account and create a new firebase of your liking.
24
+ In the following code samples, we will use the following as our base url:
25
+
26
+ + https://zerodarkthirty.firebaseio.com
27
+
28
+ Then you can specify an entry point into the data using the following call:
29
+
30
+ ```ruby
31
+ ref = Bigbertha::Load.new( 'https://zerodarkthirty.firebaseio.com' )
32
+ ```
33
+
34
+ NOTE: You don't have to start a the root, but usually a good idea since this api
35
+ offers ways to traverse the hierarchy up or down. But more on this later...
36
+
37
+
38
+ ### Populating firebase
39
+
40
+ Firebase supports the following data types:
41
+
42
+ + String
43
+ + Number
44
+ + Boolean
45
+ + Array
46
+ + Hash
47
+
48
+ #### Adding primitive types
49
+
50
+ ```ruby
51
+ data = {
52
+ a: 0,
53
+ b: %s(Hello World),
54
+ c: 10.5
55
+ }
56
+ ref.set( data )
57
+ ```
58
+
59
+ Yields:
60
+
61
+ + a:0
62
+ + b:"Hello World"
63
+ + c:10.5
64
+
65
+ NOTE: Set is a destructive operation and will replace the previous content for the reference it is
66
+ called from.
67
+
68
+ Thus
69
+
70
+ ```ruby
71
+ data = {
72
+ a: 0
73
+ }
74
+ ref.set( data )
75
+ ```
76
+
77
+ Yields
78
+ + a:0
79
+
80
+ Hence replacing the previously assigned content.
81
+
82
+
83
+ #### Adding arrays
84
+
85
+ ```ruby
86
+ ref.set( %w(Hello World) )
87
+ ```
88
+
89
+ Yields:
90
+
91
+ + 0:"Hello"
92
+ + 1:"World"
93
+
94
+
95
+ #### Adding arrays (ordered data)
96
+
97
+ The preferred method to construct lists in your firebase is to use the push operation, which
98
+ will automatically provide ordering to your list.
99
+
100
+ ```ruby
101
+ ref.push( "BumbleBee" )
102
+ ref.push( "Tuna" )
103
+ ```
104
+
105
+ Yields:
106
+
107
+ + -IrMr3Yp1mozVNzDePKy: "BumbleBee"
108
+ + -IrMr3cM6XjTpNebsYRh: "Tuna"
109
+
110
+ NOTE: The list indexes will be autogenerated by firebase to ensure correct ordering on retrieval.
111
+
112
+
113
+ #### Adding hashes
114
+
115
+ ```ruby
116
+ data = {
117
+ a: {
118
+ a_1: %s(Hello World),
119
+ a_2: 10.5
120
+ },
121
+ b: {
122
+ b_1: 10,
123
+ b_2: true
124
+ }
125
+ }
126
+ ref.set( data )
127
+ ```
128
+
129
+ Yields:
130
+
131
+ + a:
132
+ + a_1:"Hello World"
133
+ + a_2_:10.5
134
+ + b:
135
+ + b_1:10
136
+ + b_2:true
137
+
138
+
139
+ ### Reading data
140
+
141
+ Fetching data in the hierarchy is done via the read operation.
142
+
143
+ ```ruby
144
+ # Setup...
145
+ data = {
146
+ a: {
147
+ a_1: %s(Hello World),
148
+ a_2: 10.5
149
+ },
150
+ b: {
151
+ b_1: 10,
152
+ b_2: true
153
+ }
154
+ }
155
+ ref.set( data )
156
+ ```
157
+
158
+ ```ruby
159
+ ref.child( 'a/a_2' ).read # => 10.5
160
+ a_val = ref.child( :a ).read
161
+ a_val.a_1 # => 'Hello World'
162
+ a_val[:a_1] # => 'Hello World' or use hash indexing...
163
+ a_val.a_2 # => 10.5
164
+ ```
165
+
166
+ ### Updating data
167
+
168
+ You can use the #update on a reference to modify nodes in the hierarchy
169
+
170
+ ```ruby
171
+ # Setup...
172
+ data = {
173
+ a: {
174
+ a_1: %s(Hello World),
175
+ a_2: {
176
+ a_2_1: 10.5,
177
+ a_2_2: "Word!"
178
+ }
179
+ },
180
+ b: {
181
+ b_1: 10,
182
+ b_2: true
183
+ }
184
+ }
185
+ ref.set( data )
186
+ ```
187
+
188
+ ```ruby
189
+ ref.child( :a ).update( a_1:"BumbleBee Tuna" )
190
+ ref.child( 'a/a_2' ).update( a_2_2:"You bet!" )
191
+ ref.child( 'a' ).child( 'a_3' ).update( a_3_1:"You better!" )
192
+ ```
193
+
194
+ Yields:
195
+
196
+ + a
197
+ + a_1:"BumbleBee Tuna"
198
+ + a_2
199
+ + a_2_1: 10.5
200
+ + a_2_2: "You bet!"
201
+ + a_3
202
+ + a_3_1: "You better!"
203
+
204
+ Note: the last call inserts a branch new node in the hierarchy. We could have use set here as well to
205
+ perform the insert.
206
+
207
+ You can leverage #inc/#dec to increment/decrement counter like data.
208
+
209
+ IMPORTANT! Sadly Firebase currently does not offer transactions using their REST api, hence there is
210
+ no guarantees about the atomicity of read/write operations ;-(
211
+
212
+ ### Deleting data
213
+
214
+ Use the #remove operation to delete nodes at any level in the hierarchy.
215
+
216
+ ```ruby
217
+ # Setup...
218
+ data = {
219
+ a: {
220
+ a_1: %s(Hello World),
221
+ a_2: {
222
+ a_2_1: 10.5,
223
+ a_2_2: "Word!"
224
+ }
225
+ },
226
+ b: {
227
+ b_1: 10,
228
+ b_2: true
229
+ }
230
+ }
231
+ ref.set( data )
232
+ ref.child( 'a/a_2/a_2_2' ).remove
233
+ ref.child( :b ).remove
234
+ ```
235
+
236
+ NOTE: Calling remove on the root ref will delete the entire hierarchy.
237
+
238
+ ### Traversing the data
239
+
240
+ You can traverse the hierarchy using the #child or #parent. These calls can be chained.
241
+
242
+ ```ruby
243
+ data = {
244
+ a: {
245
+ a_1: %s(Hello World),
246
+ a_2: {
247
+ a_2_1: 10.5,
248
+ a_2_2: "Word!"
249
+ }
250
+ },
251
+ b: {
252
+ b_1: 10,
253
+ b_2: true
254
+ }
255
+ }
256
+ ref.set( data )
257
+ ```
258
+
259
+ ```ruby
260
+ a_2_2_ref = ref.child( 'a/a_2/a_2_2' )
261
+ a_2_2_ref = ref.child( :a ).child( :a_2 ).child( :a_2_2 ) # or...
262
+ a_2_2_ref.name #=> 'a_2_2'
263
+
264
+ a_2_ref = a_2_2_ref.parent
265
+ a_2_ref.name # => 'a_2'
266
+
267
+ a_ref = a_2_2_ref.parent.parent
268
+ a_ref.name # => 'a'
269
+ ```
270
+
271
+ ### Priorities
272
+
273
+ Firebase provides for setting priorities on ordered list in order to affect the retrieval. By default priority is null.
274
+ Setting priority affects the retrieval as follows (See firebase web site for details!):
275
+
276
+ + Children with no priority are retrieved first ordered lex asc by name
277
+ + Children with number priority are next, ordered lex asc priority, name
278
+ + Children with a non numeric priority come last, ordered lex asc priority, name
279
+
280
+ ```ruby
281
+ a_ref = ref.push( {a:1, b:2} )
282
+ b_ref = ref.push( {c:1, d:2} )
283
+ a_ref.set_priority( 20 )
284
+ b_ref.set_priority( 10 )
285
+ a_ref.parent.read #=> {-IrNhTASqxqEpNMw8NGq: {c: 1, d: 2}, -IrNhT2vsoQ1WlgSG6op: {a: 1, b: 2} }
286
+ ```
287
+
288
+ ### Auth and rules
289
+
290
+ You can secure you firebase store using a secret token and grant access for permissions on the store using rules.
291
+ Please refer to the firebase docs for details.
292
+
293
+ ```ruby
294
+ ref = Bigbertha::Load.new( 'https://bozo.firebaseio.com', my_secret_token )
295
+ ref.set( tmp: { a: 0, b: 1 } )
296
+ ref.set_rules(
297
+ { '.read' => true, '.write' => false,
298
+ "tmp" => { '.read' => true, '.write' => false }
299
+ }
300
+ )
301
+ res = ref.child(:tmp).read # => { a: 0, b: 1 }
302
+ ref.set( tmp: {d:0} ) } # => Bigbertha::Action::PermissionDeniedError
303
+ ```
304
+
305
+ ## Contact
306
+
307
+ Fernand Galiana
308
+
309
+ - http://github.com/derailed
310
+ - http://twitter.com/kitesurfer
311
+ - <fernand.galiana@gmail.com>
312
+
313
+ ## License
314
+
315
+ Bigbertha is released under the [MIT](http://opensource.org/licenses/MIT) license.
316
+
317
+
318
+ ## History
319
+ + 0.0.1:
320
+ + Initial drop
321
+ + 0.0.2:
322
+ + Clean up and doc updates
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+
3
+ Bundler.require
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
8
+
9
+ require 'rspec/core/rake_task'
10
+ RSpec::Core::RakeTask.new(:spec) do |t|
11
+ t.verbose = false
12
+ t.ruby_opts = "-I./spec"
13
+ end
14
+
15
+ desc 'Cleanup build artifacts'
16
+ task :clean do
17
+ cov = File.expand_path( File.join( %w(.. coverage) ), __FILE__ )
18
+ FileUtils.rm_r( cov ) if File.exists?( cov )
19
+ end
20
+
21
+ task default: :spec
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bigbertha/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bigbertha"
7
+ s.version = Bigbertha::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+
10
+ s.authors = [
11
+ "Fernand Galiana"
12
+ ]
13
+
14
+ s.email = ["fernand.galiana@gmail.com"]
15
+ s.homepage = "http://derailed.github.io/bigbertha"
16
+ s.summary = %q{Ruby implementation for your Firebase battery}
17
+ s.description = "Firebase is a real time backend to allow clients to share" +
18
+ "data on the web. This gem provides a ruby API implementation."
19
+ s.rubyforge_project = "bigbertha"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+
26
+ s.add_dependency 'map' , '~> 6.3.0'
27
+ s.add_dependency 'typhoeus', '~> 0.6.2'
28
+ end
@@ -0,0 +1,10 @@
1
+ require 'bigbertha'
2
+
3
+ ref = Bigbertha::Load.new( ENV['fb_url'] )
4
+ ref.remove
5
+ data = {
6
+ a: 0,
7
+ b: %s(Hello World),
8
+ c: 10.5
9
+ }
10
+ ref.set( data )