relaxo 0.4.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+
2
+ require 'relaxo'
3
+
4
+ RSpec.shared_context "test records" do
5
+ let(:database_path) {File.join(__dir__, 'test')}
6
+ let(:database) {Relaxo.connect(database_path)}
7
+
8
+ let(:prefix) {"records"}
9
+
10
+ before(:each) do
11
+ FileUtils.rm_rf(database_path)
12
+
13
+ database.commit(message: "Create Sample Data") do |dataset|
14
+ 20.times do |i|
15
+ object = dataset.append("good-#{i}")
16
+ dataset.write("#{prefix}/#{i}", object)
17
+ end
18
+
19
+ 10.times do |i|
20
+ object = dataset.append("bad-#{i}")
21
+ dataset.write("#{prefix}/subdirectory/#{i}", object)
22
+ end
23
+ end
24
+ end
25
+ end
metadata CHANGED
@@ -1,31 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaxo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-11 00:00:00.000000000 Z
11
+ date: 2017-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: json
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.8'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.8'
27
- - !ruby/object:Gem::Dependency
28
- name: rest-client
14
+ name: rugged
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - ">="
@@ -92,6 +78,7 @@ extensions: []
92
78
  extra_rdoc_files: []
93
79
  files:
94
80
  - ".gitignore"
81
+ - ".rspec"
95
82
  - ".simplecov"
96
83
  - ".travis.yml"
97
84
  - Gemfile
@@ -100,19 +87,19 @@ files:
100
87
  - bin/relaxo
101
88
  - bin/relaxo-admin
102
89
  - lib/relaxo.rb
103
- - lib/relaxo/attachments.rb
104
- - lib/relaxo/client.rb
105
- - lib/relaxo/connection.rb
90
+ - lib/relaxo/changeset.rb
106
91
  - lib/relaxo/database.rb
107
- - lib/relaxo/json.rb
92
+ - lib/relaxo/dataset.rb
93
+ - lib/relaxo/directory.rb
108
94
  - lib/relaxo/schema.rb
109
- - lib/relaxo/transaction.rb
110
95
  - lib/relaxo/version.rb
111
96
  - relaxo.gemspec
112
- - spec/relaxo/connection_spec.rb
97
+ - spec/relaxo/changeset_spec.rb
98
+ - spec/relaxo/concurrency_spec.rb
113
99
  - spec/relaxo/database_spec.rb
114
- - spec/relaxo/spec_helper.rb
115
- - spec/relaxo/transaction_spec.rb
100
+ - spec/relaxo/enumeration_spec.rb
101
+ - spec/relaxo/performance_spec.rb
102
+ - spec/relaxo/test_records.rb
116
103
  homepage: ''
117
104
  licenses:
118
105
  - MIT
@@ -133,12 +120,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
120
  version: '0'
134
121
  requirements: []
135
122
  rubyforge_project:
136
- rubygems_version: 2.5.1
123
+ rubygems_version: 2.6.10
137
124
  signing_key:
138
125
  specification_version: 4
139
126
  summary: Relaxo is a helper for loading and working with CouchDB.
140
127
  test_files:
141
- - spec/relaxo/connection_spec.rb
128
+ - spec/relaxo/changeset_spec.rb
129
+ - spec/relaxo/concurrency_spec.rb
142
130
  - spec/relaxo/database_spec.rb
143
- - spec/relaxo/spec_helper.rb
144
- - spec/relaxo/transaction_spec.rb
131
+ - spec/relaxo/enumeration_spec.rb
132
+ - spec/relaxo/performance_spec.rb
133
+ - spec/relaxo/test_records.rb
@@ -1,65 +0,0 @@
1
- # Copyright (c) 2012 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'relaxo/database'
22
-
23
- require 'base64'
24
-
25
- module Relaxo
26
- ATTACHMENTS = '_attachments'
27
-
28
- def self.encode_attachments!(document)
29
- return unless document[ATTACHMENTS]
30
-
31
- document[ATTACHMENTS].each do |name,contents|
32
- next if contents.include? 'stub'
33
-
34
- contents['data'] = Base64.strict_encode64(contents['data'])
35
- end
36
- end
37
-
38
- class Database
39
- def attach(document, name, data, options = {})
40
- parameters = {
41
- :rev => Parameter::Raw(document[REV])
42
- }.merge(options[:parameters] || {})
43
-
44
- headers = {}
45
-
46
- if options[:headers]
47
- headers = options[:headers].dup
48
- else
49
- headers = {}
50
- end
51
-
52
- if options[:content_type]
53
- headers[:content_type] = options[:content_type]
54
- end
55
-
56
- Client.attach attachment_url(document[ID], name, parameters), data, headers
57
- end
58
-
59
- private
60
-
61
- def attachment_url(id, name, parameters = {})
62
- Client.encode_url("#{@root}/#{Client.escape_id(id)}/#{Client.escape(name)}", parameters)
63
- end
64
- end
65
- end
@@ -1,168 +0,0 @@
1
- # Copyright (c) 2012 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'relaxo/json'
22
- require 'rest_client'
23
- require 'cgi'
24
-
25
- module Relaxo
26
- # Typically returned from CouchDB when the request was successful:
27
- SUCCESS = {'ok' => true}
28
-
29
- module Parameter
30
- # Raw string parameter.
31
- class Raw
32
- def initialize(value)
33
- @value = value
34
- end
35
-
36
- def to_query_string
37
- @value
38
- end
39
- end
40
-
41
- def self.Raw(value)
42
- Raw.new(value)
43
- end
44
-
45
- # Force JSON serialisation.
46
- class JSON
47
- def initialize(value)
48
- @value = value
49
- end
50
-
51
- def to_query_string
52
- @value.to_json
53
- end
54
- end
55
-
56
- def self.JSON(value)
57
- JSON.new(value)
58
- end
59
- end
60
-
61
- module Client
62
- DEFAULT_GET_HEADERS = {:accept => :json}
63
- DEFAULT_PUT_HEADERS = {:accept => :json, :content_type => :json}
64
-
65
- def self.execute(request)
66
- if request[:method] == :head
67
- begin
68
- response = RestClient::Request.execute(request)
69
- return response.code == 200
70
- rescue RestClient::ResourceNotFound
71
- return false
72
- end
73
- else
74
- response = RestClient::Request.execute(request)
75
- return JSON.parse(response)
76
- end
77
- end
78
-
79
- def self.get(url)
80
- execute({
81
- :method => :get,
82
- :url => url,
83
- :headers => DEFAULT_GET_HEADERS
84
- })
85
- end
86
-
87
- def self.head(url)
88
- execute({
89
- :method => :head,
90
- :url => url,
91
- :headers => DEFAULT_GET_HEADERS
92
- })
93
- end
94
-
95
- def self.attach(url, data, headers = {})
96
- headers = {
97
- :accept => :json
98
- }.merge(headers)
99
-
100
- execute({
101
- :method => :put,
102
- :url => url,
103
- :headers => headers,
104
- :payload => data
105
- })
106
- end
107
-
108
- def self.put(url, document = nil)
109
- execute({
110
- :method => :put,
111
- :url => url,
112
- :headers => DEFAULT_PUT_HEADERS,
113
- :payload => document ? JSON.generate(document) : nil
114
- })
115
- end
116
-
117
- def self.post(url, document)
118
- execute({
119
- :method => :post,
120
- :url => url,
121
- :headers => DEFAULT_PUT_HEADERS,
122
- :payload => JSON.generate(document)
123
- })
124
- end
125
-
126
- def self.delete(url)
127
- execute({
128
- :method => :delete,
129
- :url => url,
130
- :headers => DEFAULT_PUT_HEADERS
131
- })
132
- end
133
-
134
- def self.escape(component)
135
- return CGI.escape(component)
136
- end
137
-
138
- def self.encode_parameters(parameters)
139
- query = []
140
-
141
- parameters.each do |key, value|
142
- key_string = key.to_s
143
-
144
- if value.respond_to? :to_query_string
145
- query << escape(key_string) + '=' + escape(value.to_query_string)
146
- elsif Symbol === value || key_string.end_with?("docid")
147
- query << escape(key_string) + '=' + escape(value.to_s)
148
- else
149
- query << escape(key_string) + '=' + escape(value.to_json)
150
- end
151
- end
152
-
153
- return '?' + query.join('&')
154
- end
155
-
156
- def self.encode_url(url, parameters = {})
157
- if parameters.empty?
158
- url
159
- else
160
- url + encode_parameters(parameters)
161
- end
162
- end
163
-
164
- def self.escape_id(id)
165
- /^_design\/(.*)/ =~ id ? "_design/#{escape($1)}" : escape(id)
166
- end
167
- end
168
- end
@@ -1,116 +0,0 @@
1
- # Copyright (c) 2012 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'relaxo/client'
22
- require 'relaxo/connection'
23
-
24
- module Relaxo
25
-
26
- # We monkey-patch this in as Transaction is basically an optional feature for doing bulk_saves.
27
- class Database
28
- def transaction(klass = nil, metadata = {})
29
- transaction = Transaction.new(self, metadata)
30
-
31
- catch(:abort) do
32
- yield transaction
33
-
34
- changed = transaction.commit!
35
-
36
- if klass
37
- klass.new(self, changed.last)
38
- else
39
- changed
40
- end
41
- end
42
- end
43
- end
44
-
45
- class Transaction
46
- def initialize(database, metadata = {})
47
- @database = database
48
- @metadata = {}
49
-
50
- @documents = []
51
- @uuids = []
52
- end
53
-
54
- def [] key
55
- @metadata[key] || @database[key]
56
- end
57
-
58
- def get(*args)
59
- @database.get(*args)
60
- end
61
-
62
- def delete(document)
63
- @documents << {
64
- ID => document[ID],
65
- REV => document[REV],
66
- DELETED => true
67
- }
68
- end
69
-
70
- def save(document)
71
- @documents << document
72
-
73
- # We assume the save operation will be successful:
74
- unless document.key? ID
75
- @uuids << (document[ID] = @database.connection.next_uuid)
76
- end
77
- end
78
-
79
- def transaction(klass)
80
- yield self
81
-
82
- klass.new(self, @documents.last)
83
- end
84
-
85
- def view(*args)
86
- @database.view(*args)
87
- end
88
-
89
- def commit!
90
- changed = []
91
-
92
- unless @documents.empty?
93
- results = @database.bulk_save @documents
94
-
95
- # Update the documents with revision information:
96
- @documents.each_with_index do |document, index|
97
- status = results[index]
98
-
99
- if status['ok']
100
- document[ID] = status['id']
101
- document[REV] = status['rev']
102
- end
103
- end
104
-
105
- changed = @documents
106
- @documents = []
107
- end
108
-
109
- return changed
110
- end
111
-
112
- def abort!
113
- throw :abort
114
- end
115
- end
116
- end