chill 8 → 8.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/benchmark.rb +20 -0
- data/examples/bulk-commit.rb +17 -0
- data/examples/find-app.rb +118 -0
- data/examples/kittens-app.rb +48 -0
- data/{library → lib}/chill.rb +66 -18
- data/license.txt +24 -0
- data/readme.txt +61 -0
- metadata +14 -22
@@ -0,0 +1,20 @@
|
|
1
|
+
require '../lib/chill'
|
2
|
+
require 'benchmark'
|
3
|
+
# A little benchmark to illustrate the performance difference between a bulk commit and individual commits
|
4
|
+
ChillDB.goes :BulkCommitBenchmark
|
5
|
+
Documents = 1000 # benchmark 1000 documents
|
6
|
+
|
7
|
+
puts "Bulk Commit of #{Documents}"
|
8
|
+
puts(bulk = Benchmark.realtime {
|
9
|
+
BulkCommitBenchmark.commit! Documents.times.map { { random_number: rand(50) } }
|
10
|
+
})
|
11
|
+
|
12
|
+
puts "Single Commit of #{Documents}"
|
13
|
+
puts(single = Benchmark.realtime {
|
14
|
+
Documents.times do
|
15
|
+
{ random_number: rand(50) }
|
16
|
+
BulkCommitBenchmark.document( random_number: rand(50) ).commit!
|
17
|
+
end
|
18
|
+
})
|
19
|
+
|
20
|
+
puts "Bulk Commit was #{ ((single / bulk) * 100).round(2) }% faster!"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require '../lib/chill.rb'
|
2
|
+
# A simple test to check the new bulk commit api works as intended
|
3
|
+
# by Bluebie
|
4
|
+
|
5
|
+
ChillDB.goes :BulkBag
|
6
|
+
|
7
|
+
BulkBag.delete! BulkBag.everything # clear out our test database, using new bulk delete api
|
8
|
+
|
9
|
+
BulkBag.commit!(
|
10
|
+
{ _id: 'brother1', name: "Lucky" },
|
11
|
+
{ _id: 'brother2', name: "Fyr" }
|
12
|
+
);
|
13
|
+
|
14
|
+
raise "fail" unless BulkBag['brother1'].name == 'Lucky'
|
15
|
+
raise "fail" unless BulkBag['brother2'].name == 'Fyr'
|
16
|
+
|
17
|
+
puts "Success! Brother1's name is #{ BulkBag['brother1'].name }"
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# Find App is a simple little fulltext search engine, to lookup documents containing words
|
2
|
+
require '../lib/chill.rb'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
ChillDB.goes :FindApp
|
6
|
+
|
7
|
+
# delete everything in the database so we have a nice fresh start while experimenting
|
8
|
+
FindApp.everything.delete!
|
9
|
+
|
10
|
+
# a view which will list all the words in our stories
|
11
|
+
FindApp.design(:search).views(
|
12
|
+
# words view splits up all the words then adds them as keys to this document
|
13
|
+
words: %q(
|
14
|
+
function(doc) {
|
15
|
+
if (doc.kind != "story") return;
|
16
|
+
var words = doc.text.split(/[^a-z0-9\']+/i);
|
17
|
+
for (id in words) {
|
18
|
+
emit(words[id].toLowerCase(), {_rev: doc._rev, word: words[id]})
|
19
|
+
}
|
20
|
+
}
|
21
|
+
)
|
22
|
+
).commit!
|
23
|
+
|
24
|
+
# a little template for stories
|
25
|
+
FindApp.templates(
|
26
|
+
story: {
|
27
|
+
text: "",
|
28
|
+
name: "no name"
|
29
|
+
}
|
30
|
+
)
|
31
|
+
|
32
|
+
# add in some stories
|
33
|
+
FindApp.template(:story).merge(
|
34
|
+
name: "Charlotte and the Penguin Exhibit",
|
35
|
+
text: %(Charlotte was a computer hacker. Legendary in the scene. She was one of the few people ever to find an SSH vulnerability. Of course, being a girl she was often ignored by the other hackers, which usually worked out to her advantage. And so begins the tale of Charlotte's Big Hack. It was a sunny friday evening in antarctica, where the days are pitch black and the nights are bright as snow. Charlotte was just getting back from a whale riding expedition when she heard the familliar sound of digitized raindrops falling on sheets of glass. Someone was sending her a message!
|
36
|
+
|
37
|
+
She ran inside, throwing her big wooly coat away rushing to her computer. Dit dit dit! Each letter suspensfully appeared on her screen. "Wake up neo...". "Blargh" she announced. "This looser keeps bugging me, and I don't even know who this Neo guy is!"
|
38
|
+
|
39
|
+
After carefully typing in a sentence so masterfully cutting it best not be repeated, she sighed and flopped back on her fluffy bed with a squeak.
|
40
|
+
|
41
|
+
...
|
42
|
+
)
|
43
|
+
).commit!
|
44
|
+
|
45
|
+
FindApp.template(:story).merge(
|
46
|
+
name: "The origin of life",
|
47
|
+
text: "The cats said let there be life, and so there was life, and it was good."
|
48
|
+
).commit!
|
49
|
+
|
50
|
+
FindApp.template(:story).merge(
|
51
|
+
name: "Dearest Fiona",
|
52
|
+
text: "Dearest Fiona,
|
53
|
+
|
54
|
+
Mary Pebblesworth was an unusual child. Born of parents who fled to Siam, escaping conscription in The Great War. She was never the same after returning. Insisting on eating the most horrifying of foods. Thought to be unwell from the stress of her childhood. Something unusual occurred with this patient. When placed under the care of Sir Pennyworth's Halfway House, it was noted several of her peers began craving and demanding these terrible concoctions just as she had.
|
55
|
+
|
56
|
+
At first it was thought there were some terrible joke being played, however it soon became clear we were dealing with the beginnings of a truly terrifying disease on par with childhood legends of African Zombies craving flesh and brain! In a panic Mary was brought by carriage to our estate and provided a room. We were all terribly careful of the risk of infection, and thankfully, we were fine this night.
|
57
|
+
|
58
|
+
Two weeks and three days in to my investigation, I foolishly decided on an experiment. I provided the woman with the fishes she had requested, along with exotic beans at no short expense. Carefully observing her 'cooking', so convinced of my immunity to her infectiveity, I witnessed her truly horrifying ritual. Whole fish liquefied before my very eyes, exotic beans ground to a seemingly worthless paste, then set as if by witchcraft in to what I can only describe as cheese. The smells, oh-how they defy words...
|
59
|
+
|
60
|
+
We couldn't help ourselves.
|
61
|
+
|
62
|
+
I'm terribly sorry.
|
63
|
+
|
64
|
+
Yours Faithfully,
|
65
|
+
Joseph South"
|
66
|
+
).commit!
|
67
|
+
|
68
|
+
# brightens text in terminals which do ANSI codes
|
69
|
+
def highlight text
|
70
|
+
color_code = 7
|
71
|
+
"\e[#{color_code}m#{text}\e[0m"
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# find a story with the word 'it' in it, or a word you specify when calling
|
76
|
+
# the program
|
77
|
+
if ARGV.empty?
|
78
|
+
print "Search: "
|
79
|
+
words = gets.split(/[^a-z0-9']+/i)
|
80
|
+
raise "No words entered" if words.empty?
|
81
|
+
else
|
82
|
+
words = ARGV
|
83
|
+
end
|
84
|
+
|
85
|
+
puts "Searching for #{ words.map { |w| highlight(w.capitalize) }.join ' ' }:\n\n"
|
86
|
+
|
87
|
+
stories = []
|
88
|
+
|
89
|
+
# lookup each word and add the stories to our collection
|
90
|
+
first_word = true
|
91
|
+
words.each do |word|
|
92
|
+
# you could make this faster by doing a single request using 'keys' instead
|
93
|
+
# of looping through each word doing a bunch of queries.
|
94
|
+
found = FindApp.design(:search).query(:words, key: word.downcase, include_docs: true)
|
95
|
+
|
96
|
+
if first_word
|
97
|
+
stories += found.docs # add all the stories we found
|
98
|
+
else
|
99
|
+
stories &= found.docs # remove stories which don't also have this word!
|
100
|
+
end
|
101
|
+
|
102
|
+
first_word = false # done being the first word now.
|
103
|
+
end
|
104
|
+
|
105
|
+
stories.uniq.each do |story|
|
106
|
+
puts "{ #{story.name.upcase} }".center(`tput cols`.to_i, '~')
|
107
|
+
|
108
|
+
text = story.text
|
109
|
+
# create a regexp which finds any of the words we're after
|
110
|
+
searcher = Regexp.new("\\b(#{words.map { |word| Regexp.escape(word)}.join('|')})\\b", 'i')
|
111
|
+
text.gsub!(searcher) { |found| highlight(found) } # underline all the search words
|
112
|
+
|
113
|
+
# underline all the search words
|
114
|
+
puts text
|
115
|
+
puts "\n\n" # blank lines
|
116
|
+
end
|
117
|
+
|
118
|
+
puts "[ SEARCH FINISHED ]".center(`tput cols`.to_i, '=')
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require '../lib/chill.rb'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
# make a database or connect to one
|
5
|
+
ChillDB.goes :KittensApp
|
6
|
+
|
7
|
+
# delete everything and start fresh
|
8
|
+
KittensApp.everything.delete!
|
9
|
+
|
10
|
+
# add a template (just in ruby instance)
|
11
|
+
KittensApp.templates(
|
12
|
+
cat: {
|
13
|
+
color: 'invisible',
|
14
|
+
softness: 5,
|
15
|
+
likes: %w{water food flying spaceships sunlight tictacs hugs exploding},
|
16
|
+
dislikes: %w{mysql}
|
17
|
+
}
|
18
|
+
)
|
19
|
+
|
20
|
+
# add a view
|
21
|
+
KittensApp.design(:lists).views(
|
22
|
+
soft_cats: 'function(doc) {
|
23
|
+
if (doc.kind == "cat" && doc.softness > 1) emit(doc._id, null);
|
24
|
+
}'
|
25
|
+
).commit!
|
26
|
+
|
27
|
+
# add kittens
|
28
|
+
KittensApp.template(:cat).merge(_id: 'fredrick', softness: 16, dislikes: ['silly business']).commit!
|
29
|
+
KittensApp.template(:cat).merge(_id: 'bobby', softness: 2, dislikes: ['mice']).commit!
|
30
|
+
KittensApp.template(:cat).merge(_id: 'cheezly', softness: 1, dislikes: ['soy cheese products']).commit!
|
31
|
+
|
32
|
+
# use the view to get a list of non-hard cats
|
33
|
+
puts "Kitten Database lookup - soft cats:"
|
34
|
+
soft_ones = KittensApp.design(:lists).query(:soft_cats, include_docs: true)
|
35
|
+
soft_ones.docs.each do |cat|
|
36
|
+
puts "#{cat['_id']} is #{cat['softness']} soft"
|
37
|
+
end
|
38
|
+
|
39
|
+
# just load fredrick
|
40
|
+
fredrick = KittensApp['fredrick']
|
41
|
+
puts "Fredrick's stats:"
|
42
|
+
fredrick.each do |item, value|
|
43
|
+
puts "#{item.rjust(10)}- #{value}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# get the nonsoft cats the slow way - in ruby instead of with a view
|
47
|
+
nonsofties = (KittensApp.everything.docs - soft_ones.docs).select { |i| i['kind'] == 'cat' }
|
48
|
+
puts "Nonsoft cats: #{nonsofties.map { |cat| cat['_id'] }.join(', ')}"
|
data/{library → lib}/chill.rb
RENAMED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Bluebie's silly little CouchDB abstraction
|
2
|
-
|
3
|
-
|
4
|
-
require '
|
2
|
+
#
|
3
|
+
# :include:../readme.txt
|
4
|
+
require 'json' # gem dependancy
|
5
|
+
require 'rest-client' # gem dependancy
|
6
|
+
require 'securerandom'
|
5
7
|
require 'uri'
|
6
8
|
|
7
9
|
# The main ChillDB module - This is where it all starts
|
@@ -28,10 +30,23 @@ module ChillDB
|
|
28
30
|
# # load 'frederick' from the KittensApp database
|
29
31
|
# # on the locally installed couch server
|
30
32
|
# KittensApp['frederick'] #=> <ChillDB::Document>
|
31
|
-
|
33
|
+
#
|
34
|
+
# Options:
|
35
|
+
# user: 'couchdb_user'
|
36
|
+
# pass: 'couchdb_password'
|
37
|
+
# host: 'my-couch-server.com'
|
38
|
+
# port: 5984
|
39
|
+
# path: '/my-database/'
|
40
|
+
#
|
41
|
+
# Default options: ChillDB connects to
|
42
|
+
# http://localhost:5984/db-name-hyphenated/. When couch is freshly
|
43
|
+
# installed on a server, defaults will will work without any extra setup.
|
44
|
+
# You might want to add authentication if your server has multiple users,
|
45
|
+
# or you maybe allowing remote web access to couchdb.
|
46
|
+
def self.goes database_name, options = {}
|
32
47
|
submod = Module.new do
|
33
48
|
extend ChillDB
|
34
|
-
@@database = ChillDB::Database.new database_name,
|
49
|
+
@@database = ChillDB::Database.new database_name, options
|
35
50
|
@@templates = {}
|
36
51
|
end
|
37
52
|
self.constants(false).each do |const|
|
@@ -85,8 +100,21 @@ module ChillDB
|
|
85
100
|
end
|
86
101
|
|
87
102
|
# Loads or creates a document with a specified _id. If no _id is specified
|
88
|
-
# a new blank document is created which will be assigned a fresh UUID
|
89
|
-
#
|
103
|
+
# a new blank document is created which will be assigned a fresh UUID when
|
104
|
+
# unless you specify one before committing it. You can optionally provide values
|
105
|
+
# for a new document as a hash argument. Note that documents created in this
|
106
|
+
# way are not saved to the database unless you use ChillDB::Document#commit!
|
107
|
+
# or pass them to #commit!
|
108
|
+
#
|
109
|
+
# Example:
|
110
|
+
# KittensApp['fredrick']
|
111
|
+
# #=> {"_id"=>"cheezly", "color"=>"invisible", "dislikes"=>["silly business"], ... }
|
112
|
+
# KittensApp[['fredrick', 'cheezly']]
|
113
|
+
# #=> [{"_id"=>"fredrick", ... }, {"_id"=>"cheezly", ... }]
|
114
|
+
# KittensApp[]
|
115
|
+
# #=> {}
|
116
|
+
# KittensApp[billy: 'cool', margret: 'not cool']
|
117
|
+
# #=> {"billy"=>"cool", "margret"=>"not cool", "_id"=>"df2c3d11-d50a-4db9-8f57-04fd4d511ded"}
|
90
118
|
#
|
91
119
|
# Returns a ChillDB::Document
|
92
120
|
def document id = false
|
@@ -96,7 +124,9 @@ module ChillDB
|
|
96
124
|
ChillDB::List.load(JSON.parse(response), database: @@database)
|
97
125
|
elsif id.respond_to? :to_str
|
98
126
|
ChillDB::Document.load(@@database, id.to_str)
|
99
|
-
|
127
|
+
elsif id.respond_to? :to_hash
|
128
|
+
ChillDB::Document.new(@@database).reset(id)
|
129
|
+
else # just make a new blank document
|
100
130
|
ChillDB::Document.new(@@database)
|
101
131
|
end
|
102
132
|
end
|
@@ -126,7 +156,7 @@ module ChillDB
|
|
126
156
|
# time. All documents which can be committed will be, and any which cause
|
127
157
|
# errors will be reported via a raised ChillDB::BulkUpdateErrors.
|
128
158
|
def commit! *documents
|
129
|
-
list(documents.flatten).commit!
|
159
|
+
list(documents.map { |arg| arg.respond_to?(:docs)? arg.docs : arg }.flatten(1)).commit!
|
130
160
|
end
|
131
161
|
|
132
162
|
# A shortcut for #commit! which marks the documents for deletion before
|
@@ -134,7 +164,7 @@ module ChillDB
|
|
134
164
|
# a ChillDB::BulkUpdateErrors will be raised with info. All deletions which
|
135
165
|
# can succeed, will.
|
136
166
|
def delete! *documents
|
137
|
-
list(documents.flatten).delete!
|
167
|
+
list(documents.map { |arg| arg.respond_to?(:docs)? arg.docs : arg }.flatten(1)).delete!
|
138
168
|
end
|
139
169
|
|
140
170
|
# creates a new ChillDB::List from an array of ChillDB::Documents and
|
@@ -197,11 +227,15 @@ class ChillDB::Database
|
|
197
227
|
# ChillDB.goes, and shouldn't be used directly
|
198
228
|
def initialize name, settings = {} # :nodoc:
|
199
229
|
@meta = {} # little place to store our things
|
230
|
+
# a magical constant you can define to change the defaults for magical web hosting
|
231
|
+
# where the web server wants to configure an app's chill connection details
|
232
|
+
# dynamically without bothering the user with such things
|
233
|
+
settings = ChillDBConnectionDefaults.merge(settings) if Kernel.const_defined? :ChillDBConnectionDefaults
|
200
234
|
@url = URI::HTTP.build(
|
201
235
|
host: settings[:host] || 'localhost',
|
202
236
|
port: settings[:port] || 5984,
|
203
237
|
userinfo: [settings[:user], settings[:pass]],
|
204
|
-
path: "/#{URI.escape hyphenate(name)}/"
|
238
|
+
path: settings[:path] || "/#{settings[:database_name_prefix]}#{URI.escape hyphenate(name)}/"
|
205
239
|
)
|
206
240
|
|
207
241
|
# make this database if it doesn't exist yet
|
@@ -357,7 +391,8 @@ class ChillDB::Document < ChillDB::IndifferentHash
|
|
357
391
|
def reset values
|
358
392
|
raise "Argument must be a Hash" unless values.respond_to? :to_hash
|
359
393
|
self.replace values.to_hash
|
360
|
-
self['_id'] ||=
|
394
|
+
self['_id'] ||= SecureRandom.uuid # generate an _id if we don't have one already
|
395
|
+
self
|
361
396
|
end
|
362
397
|
|
363
398
|
# load a documet from a ChillDB::Database, with a specific document id, and
|
@@ -509,9 +544,9 @@ class ChillDB::List < Array
|
|
509
544
|
# to make a list from a simple array (not a couchdb response...)
|
510
545
|
def self.from_array array # :nodoc:
|
511
546
|
new_list = self.new
|
512
|
-
new_list.replace
|
513
|
-
{ 'id'=> item['_id'], 'key'=> item['_id'], 'value'=> item, 'doc'=> item }
|
514
|
-
|
547
|
+
new_list.replace(array.map { |item|
|
548
|
+
{ 'id'=> item['_id'] || item[:_id], 'key'=> item['_id'] || item[:_id], 'value'=> item, 'doc'=> item }
|
549
|
+
})
|
515
550
|
end
|
516
551
|
|
517
552
|
# store rows nicely in mah belleh
|
@@ -653,11 +688,21 @@ class ChillDB::List < Array
|
|
653
688
|
# get the list, with any non-ChillDB::Document's converted in to those
|
654
689
|
def convert
|
655
690
|
map do |item|
|
656
|
-
|
691
|
+
if item['doc']
|
692
|
+
document = item['doc']
|
693
|
+
elsif item['id']
|
694
|
+
document = { _id: item['id'] }
|
695
|
+
revision = item['value']['rev'] || item['value']['_rev']
|
696
|
+
document['_rev'] ||= revision if revision
|
697
|
+
else
|
698
|
+
raise "Couldn't find _id for document in list #{item.inspect}"
|
699
|
+
end
|
700
|
+
|
657
701
|
if document.is_a? ChillDB::Document
|
658
702
|
document
|
659
703
|
elsif document.respond_to? :to_hash
|
660
|
-
|
704
|
+
revision = item['value']['_rev'] || item['value']['rev'] || item['doc']['_rev']
|
705
|
+
document['_rev'] ||= revision if revision
|
661
706
|
document = ChillDB::Document.new(@database, document.to_hash)
|
662
707
|
else
|
663
708
|
raise "Cannot convert #{document.inspect}"
|
@@ -667,7 +712,9 @@ class ChillDB::List < Array
|
|
667
712
|
|
668
713
|
# commit an array of documents to the server
|
669
714
|
def commit_documents! documents
|
670
|
-
|
715
|
+
return if documents.empty?
|
716
|
+
body = JSON.generate(docs: documents.to_a)
|
717
|
+
response = @database.http('_bulk_docs').post(body)
|
671
718
|
raise response.body unless (200..299).include? response.code
|
672
719
|
json = JSON.parse(response.body)
|
673
720
|
errors = []
|
@@ -675,6 +722,7 @@ class ChillDB::List < Array
|
|
675
722
|
documents.each_index do |index|
|
676
723
|
self[index]['id'] = json[index]['id']
|
677
724
|
self[index]['value']['rev'] = json[index]['rev'] if json[index]['rev']
|
725
|
+
self[index]['doc']['_rev'] = json[index]['rev'] if json[index]['rev'] and self[index]['doc']
|
678
726
|
errors.push [self[index], json[index]] if json[index]['error']
|
679
727
|
end
|
680
728
|
|
data/license.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2012, Jenna Fox
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the chilldb nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/readme.txt
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
.oOo. .oOo. .oOo. chill .oOo. .oOo. .oOo.
|
2
|
+
|
3
|
+
chill plugs ruby code in to CouchDB
|
4
|
+
|
5
|
+
|
6
|
+
~~~ USAGE ~~~
|
7
|
+
require 'pp'
|
8
|
+
require 'chill'
|
9
|
+
|
10
|
+
# make a database or connect to one
|
11
|
+
ChillDB.goes :KittensApp
|
12
|
+
|
13
|
+
# add a template (just in ruby instance)
|
14
|
+
KittensApp.templates(
|
15
|
+
cat: {
|
16
|
+
color: 'invisible',
|
17
|
+
softness: 5,
|
18
|
+
likes: %w{water food flying spaceships sunlight tictacs hugs exploding},
|
19
|
+
dislikes: %w{mysql}
|
20
|
+
}
|
21
|
+
)
|
22
|
+
|
23
|
+
# get a copy of a template, change some things, and save it
|
24
|
+
KittensApp.template(:cat).merge(
|
25
|
+
color: 'green',
|
26
|
+
softness: 8,
|
27
|
+
dislikes: %w{stylesheets},
|
28
|
+
_id: 'fredrick'
|
29
|
+
)
|
30
|
+
|
31
|
+
# add a view
|
32
|
+
KittensApp.design(:lists).views(
|
33
|
+
soft_cats: 'function(doc) {
|
34
|
+
if (doc.kind == "cat" && doc.softness > 1) emit(doc._id, null);
|
35
|
+
}'
|
36
|
+
).commit!
|
37
|
+
|
38
|
+
# add a kitten
|
39
|
+
KittensApp.template(:cat).merge(
|
40
|
+
_id: 'fredrick',
|
41
|
+
softness: 16,
|
42
|
+
dislikes: ['silly business']
|
43
|
+
).commit!
|
44
|
+
|
45
|
+
# use the view to get a list of non-hard cats
|
46
|
+
soft_ones = KittensApp.design(:lists).query(:soft_cats)
|
47
|
+
soft_ones.each do |cat|
|
48
|
+
pp cat
|
49
|
+
end
|
50
|
+
|
51
|
+
# just load fredrick
|
52
|
+
fredrick = KittensApp['fredrick']
|
53
|
+
|
54
|
+
|
55
|
+
~~~ MORE INFORMATION THAN YOU REQUIRE ~~~
|
56
|
+
You can see a more fully baked version of the KittensApp database in
|
57
|
+
examples/kittens-app.rb. There you will see how to do all sorts of things.
|
58
|
+
It's the start of a really great kitten database you could use to keep
|
59
|
+
track of your cats. It's web scale and cloud ready.
|
60
|
+
|
61
|
+
--- <3 Bluebie
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 8.1.0
|
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: 2012-
|
12
|
+
date: 2012-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -43,22 +43,6 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 1.6.7
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: uuid
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 2.3.4
|
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: 2.3.4
|
62
46
|
description: A little library to talk to a couchdb. I made it skinny, because couchdb
|
63
47
|
is very simple. I think that's a good thing.
|
64
48
|
email: a@creativepony.com
|
@@ -66,13 +50,21 @@ executables: []
|
|
66
50
|
extensions: []
|
67
51
|
extra_rdoc_files: []
|
68
52
|
files:
|
69
|
-
-
|
70
|
-
|
53
|
+
- lib/chill.rb
|
54
|
+
- readme.txt
|
55
|
+
- license.txt
|
56
|
+
- examples/benchmark.rb
|
57
|
+
- examples/bulk-commit.rb
|
58
|
+
- examples/find-app.rb
|
59
|
+
- examples/kittens-app.rb
|
60
|
+
homepage: http://creativepony.com/chill/
|
71
61
|
licenses: []
|
72
62
|
post_install_message:
|
73
|
-
rdoc_options:
|
63
|
+
rdoc_options:
|
64
|
+
- --main
|
65
|
+
- lib/chill.rb
|
74
66
|
require_paths:
|
75
|
-
-
|
67
|
+
- lib
|
76
68
|
required_ruby_version: !ruby/object:Gem::Requirement
|
77
69
|
none: false
|
78
70
|
requirements:
|