ShyCouch 0.1.0 → 0.2.0
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.
- data/ShyCouch.gemspec +4 -2
- data/VERSION +1 -1
- data/lib/ShyCouch/data.rb +107 -0
- data/lib/ShyCouch/fields.rb +22 -0
- data/lib/ShyCouch.rb +18 -126
- metadata +19 -17
data/ShyCouch.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ShyCouch}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Shy Inc.}, %q{Daniel Bryan}, %q{Cerales}]
|
12
|
-
s.date = %q{2011-08-
|
12
|
+
s.date = %q{2011-08-20}
|
13
13
|
s.description = %q{Ruby API for CouchDB, designed to work with the Camping micro-framework.}
|
14
14
|
s.email = %q{danbryan@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,8 @@ Gem::Specification.new do |s|
|
|
26
26
|
"ShyCouch.gemspec",
|
27
27
|
"VERSION",
|
28
28
|
"lib/ShyCouch.rb",
|
29
|
+
"lib/ShyCouch/data.rb",
|
30
|
+
"lib/ShyCouch/fields.rb",
|
29
31
|
"test/helper.rb",
|
30
32
|
"test/old-test.rb",
|
31
33
|
"test/old-tests.rb",
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module ShyCouch
|
2
|
+
|
3
|
+
module Data
|
4
|
+
|
5
|
+
class CouchDocument < Hash
|
6
|
+
class << self
|
7
|
+
# allows instance.class.requirements to be called
|
8
|
+
attr_accessor :requirements
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(hash={})
|
12
|
+
# Assumes that the "kind" is the class name unless explicitly stated otherwise
|
13
|
+
# TODO - maybe just force it to be the class name no matter what tbh
|
14
|
+
hash["kind"] = self.class.to_s unless hash["kind"]
|
15
|
+
merge!(hash)
|
16
|
+
raise TypeError unless valid?
|
17
|
+
# super(hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
# def initialize(hash=nil, requirements)
|
21
|
+
# @requirements = requirements
|
22
|
+
# merge!(hash) if hash
|
23
|
+
# raise TypeError unless valid? #TODO - should raise a more specific and useful error
|
24
|
+
# end
|
25
|
+
|
26
|
+
def self.all
|
27
|
+
database = CouchDatabase.new($settings)
|
28
|
+
database.get()
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.requires(*requirements)
|
32
|
+
@requirements = requirements
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_key(key, value=nil)
|
36
|
+
# The attr value assignment operator has been overriden, but it checks for the existence of a key.
|
37
|
+
# And therefore the user has to explicitly call this method first.
|
38
|
+
self[key] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
def attr_keys
|
42
|
+
# returns the keys for all the attrs that aren't the id or rev
|
43
|
+
attr_keys = []
|
44
|
+
self.map { |k,v|
|
45
|
+
attr_keys << k unless k == "_id" or k == "_rev"
|
46
|
+
}
|
47
|
+
return attr_keys
|
48
|
+
end
|
49
|
+
|
50
|
+
def _requirements
|
51
|
+
#TODO - hm
|
52
|
+
return self.class.requirements
|
53
|
+
end
|
54
|
+
|
55
|
+
def pull(database=nil)
|
56
|
+
database = $database unless database
|
57
|
+
new_doc = database.pull_document(self)
|
58
|
+
if new_doc
|
59
|
+
self.clear
|
60
|
+
self.merge! new_doc
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def push(database = nil)
|
65
|
+
# assumes $database unless it receives a database argument
|
66
|
+
database = $database unless database
|
67
|
+
res = database.push_document(self)
|
68
|
+
self["_id"] = res["id"]
|
69
|
+
self["_rev"] = res["rev"]
|
70
|
+
return res
|
71
|
+
end
|
72
|
+
|
73
|
+
def valid?; to_json ? true : false; end
|
74
|
+
|
75
|
+
def to_json
|
76
|
+
JSON::generate(self)
|
77
|
+
rescue JSON::GeneratorError
|
78
|
+
false
|
79
|
+
end
|
80
|
+
|
81
|
+
def method_missing(m, *a)
|
82
|
+
# Makes the object behave as if the hash keys are instance properties with attr_accessors
|
83
|
+
# Had a dozen lines or so for this and found a one-line implementation of the same thing in Camping.
|
84
|
+
m.to_s =~ /=$/ ? self[$`] = a[0] : a == [] ? self[m.to_s] : super
|
85
|
+
end
|
86
|
+
|
87
|
+
def respond_to?(method)
|
88
|
+
# so that testing for whether it responds to a method is equivalent to testing for the existence of a key
|
89
|
+
self.key?(method.to_s) ? true : super
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
class Design < CouchDocument
|
95
|
+
# this is used to manage design documents
|
96
|
+
# In practise, the Controllers should be a list of classes corresponding to design documents
|
97
|
+
|
98
|
+
def map(&block);end
|
99
|
+
|
100
|
+
def reduce(&block);end
|
101
|
+
|
102
|
+
def push;end #must override push in order to set the ID
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ShyCouch
|
2
|
+
module Fields
|
3
|
+
#TODO - lightweight validation framework
|
4
|
+
|
5
|
+
class Email_Addr < String
|
6
|
+
def valid?
|
7
|
+
# Valid if: one and only one '@'; at least one "." after the '@'; an mx record can be resolved at the domain
|
8
|
+
valid_address? and valid_domain?
|
9
|
+
end
|
10
|
+
def valid_address?
|
11
|
+
self.split("@").length == 2 and self.split("@")[1].split(".").length >= 2
|
12
|
+
|
13
|
+
end
|
14
|
+
def valid_domain?
|
15
|
+
domain = self.match(/\@(.+)/)[1]
|
16
|
+
Resolv::DNS.open { |dns| dns.getresources(domain, Resolv::DNS::Resource::IN::MX) }.size > 0 ? true : false
|
17
|
+
rescue Resolv::ResolvError
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/ShyCouch.rb
CHANGED
@@ -3,22 +3,40 @@
|
|
3
3
|
# Built primarily to allow Camping apps to use CouchDB for data persistence
|
4
4
|
# ShyRubyJS is library used to build map and reduce functions from Ruby blocks
|
5
5
|
|
6
|
+
# Add the directory containing this file to the start of the load path if it
|
7
|
+
# isn't there already.
|
8
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
9
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
10
|
+
|
6
11
|
require 'net/http'
|
7
12
|
require 'json'
|
8
13
|
require 'resolv'
|
9
14
|
require 'shyrubyjs'
|
15
|
+
# require everything from the 'ShyCouch' subdirectory
|
16
|
+
Dir.new(File.dirname(__FILE__)+'/ShyCouch').each { |f| require 'shycouch/' + f.split('.')[0] unless f == '.' or f == '..' }
|
10
17
|
|
11
18
|
module Kernel
|
12
19
|
def shycouch
|
13
20
|
$database = ShyCouch::Connection.Create
|
14
21
|
end
|
22
|
+
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
module Camping
|
27
|
+
module Models
|
28
|
+
CouchDocument = ShyCouch::Data::CouchDocument
|
29
|
+
end
|
15
30
|
end
|
16
31
|
|
32
|
+
|
17
33
|
module ShyCouch
|
18
34
|
|
19
35
|
attr_accessor :database
|
20
36
|
|
21
37
|
class Connection
|
38
|
+
# Test that the database is accessible and give back a CouchDBAPI object if so.
|
39
|
+
# Doesn't actually gets instantiated - is just here to allow nice ShyCouch::Connection.Create syntax
|
22
40
|
def self.Create(settings=nil)
|
23
41
|
settings = $settings unless settings
|
24
42
|
database = CouchDBAPI.new(settings["db"]["host"], settings["db"]["port"], settings["db"]["name"], settings["db"]["user"], settings["db"]["password"])
|
@@ -32,132 +50,6 @@ module ShyCouch
|
|
32
50
|
end
|
33
51
|
end
|
34
52
|
|
35
|
-
module Data
|
36
|
-
|
37
|
-
class CouchDocument < Hash
|
38
|
-
class << self
|
39
|
-
# allows instance.class.requirements to be called
|
40
|
-
attr_accessor :requirements
|
41
|
-
end
|
42
|
-
|
43
|
-
def initialize(hash={})
|
44
|
-
# Assumes that the "kind" is the class name unless explicitly stated otherwise
|
45
|
-
# TODO - maybe just force it to be the class name no matter what tbh
|
46
|
-
hash["kind"] = self.class.to_s unless hash["kind"]
|
47
|
-
merge!(hash)
|
48
|
-
raise TypeError unless valid?
|
49
|
-
# super(hash)
|
50
|
-
end
|
51
|
-
|
52
|
-
# def initialize(hash=nil, requirements)
|
53
|
-
# @requirements = requirements
|
54
|
-
# merge!(hash) if hash
|
55
|
-
# raise TypeError unless valid? #TODO - should raise a more specific and useful error
|
56
|
-
# end
|
57
|
-
|
58
|
-
def self.all
|
59
|
-
database = CouchDatabase.new($settings)
|
60
|
-
database.get()
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.requires(*requirements)
|
64
|
-
@requirements = requirements
|
65
|
-
end
|
66
|
-
|
67
|
-
def add_key(key, value=nil)
|
68
|
-
# The attr value assignment operator has been overriden, but it checks for the existence of a key.
|
69
|
-
# And therefore the user has to explicitly call this method first.
|
70
|
-
self[key] = value
|
71
|
-
end
|
72
|
-
|
73
|
-
def attr_keys
|
74
|
-
# returns the keys for all the attrs that aren't the id or rev
|
75
|
-
attr_keys = []
|
76
|
-
self.map { |k,v|
|
77
|
-
attr_keys << k unless k == "_id" or k == "_rev"
|
78
|
-
}
|
79
|
-
return attr_keys
|
80
|
-
end
|
81
|
-
|
82
|
-
def _requirements
|
83
|
-
#TODO - hm
|
84
|
-
return self.class.requirements
|
85
|
-
end
|
86
|
-
|
87
|
-
def pull(database=nil)
|
88
|
-
database = $database unless database
|
89
|
-
new_doc = database.pull_document(self)
|
90
|
-
if new_doc
|
91
|
-
self.clear
|
92
|
-
self.merge! new_doc
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def push(database = nil)
|
97
|
-
# assumes $database unless it receives a database argument
|
98
|
-
database = $database unless database
|
99
|
-
res = database.push_document(self)
|
100
|
-
self["_id"] = res["id"]
|
101
|
-
self["_rev"] = res["rev"]
|
102
|
-
return res
|
103
|
-
end
|
104
|
-
|
105
|
-
def valid?; to_json ? true : false; end
|
106
|
-
|
107
|
-
def to_json
|
108
|
-
JSON::generate(self)
|
109
|
-
rescue JSON::GeneratorError
|
110
|
-
false
|
111
|
-
end
|
112
|
-
|
113
|
-
def method_missing(m, *a)
|
114
|
-
# Makes the object behave as if the hash keys are instance properties with attr_accessors
|
115
|
-
# Had a dozen lines or so for this and found a one-line implementation of the same thing in Camping.
|
116
|
-
m.to_s =~ /=$/ ? self[$`] = a[0] : a == [] ? self[m.to_s] : super
|
117
|
-
end
|
118
|
-
|
119
|
-
def respond_to?(method)
|
120
|
-
# so that testing for whether it responds to a method is equivalent to testing for the existence of a key
|
121
|
-
self.key?(method.to_s) ? true : super
|
122
|
-
end
|
123
|
-
|
124
|
-
end
|
125
|
-
|
126
|
-
class Design < CouchDocument
|
127
|
-
# this is used to manage design documents
|
128
|
-
# In practise, the Controllers should be a list of classes corresponding to design documents
|
129
|
-
|
130
|
-
def map(&block);end
|
131
|
-
|
132
|
-
def reduce(&block);end
|
133
|
-
|
134
|
-
def push;end #must override push in order to set the ID
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
module Fields
|
140
|
-
#TODO - lightweight validation framework
|
141
|
-
|
142
|
-
class Email_Addr < String
|
143
|
-
def valid?
|
144
|
-
# Valid if: one and only one '@'; at least one "." after the '@'; an mx record can be resolved at the domain
|
145
|
-
valid_address? and valid_domain?
|
146
|
-
end
|
147
|
-
def valid_address?
|
148
|
-
self.split("@").length == 2 and self.split("@")[1].split(".").length >= 2
|
149
|
-
|
150
|
-
end
|
151
|
-
def valid_domain?
|
152
|
-
domain = self.match(/\@(.+)/)[1]
|
153
|
-
Resolv::DNS.open { |dns| dns.getresources(domain, Resolv::DNS::Resource::IN::MX) }.size > 0 ? true : false
|
154
|
-
rescue Resolv::ResolvError
|
155
|
-
false
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
#TODO - split this stuff into modules too
|
161
53
|
class CouchDBAPI
|
162
54
|
def initialize(host, port, name, user, password)
|
163
55
|
@host, @port, @name, @user, @password = host, port, name, user, password
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ShyCouch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2011-08-
|
14
|
+
date: 2011-08-20 00:00:00.000000000Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
18
|
-
requirement: &
|
18
|
+
requirement: &70277019101960 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: 1.0.0
|
24
24
|
type: :development
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *70277019101960
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: jeweler
|
29
|
-
requirement: &
|
29
|
+
requirement: &70277019099720 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: 1.6.4
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *70277019099720
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: rcov
|
40
|
-
requirement: &
|
40
|
+
requirement: &70277019097000 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *70277019097000
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: sourcify
|
51
|
-
requirement: &
|
51
|
+
requirement: &70277019094280 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ~>
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: 0.5.0
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *70277019094280
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: ShyRubyJS
|
62
|
-
requirement: &
|
62
|
+
requirement: &70277019091840 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ! '>='
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '0'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *70277019091840
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: ShyRubyJS
|
73
|
-
requirement: &
|
73
|
+
requirement: &70277019089840 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *70277019089840
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: sourcify
|
84
|
-
requirement: &
|
84
|
+
requirement: &70277019088080 !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
87
87
|
- - ! '>='
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
version: '0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
|
-
version_requirements: *
|
92
|
+
version_requirements: *70277019088080
|
93
93
|
description: Ruby API for CouchDB, designed to work with the Camping micro-framework.
|
94
94
|
email: danbryan@gmail.com
|
95
95
|
executables: []
|
@@ -107,6 +107,8 @@ files:
|
|
107
107
|
- ShyCouch.gemspec
|
108
108
|
- VERSION
|
109
109
|
- lib/ShyCouch.rb
|
110
|
+
- lib/ShyCouch/data.rb
|
111
|
+
- lib/ShyCouch/fields.rb
|
110
112
|
- test/helper.rb
|
111
113
|
- test/old-test.rb
|
112
114
|
- test/old-tests.rb
|
@@ -132,7 +134,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
134
|
version: '0'
|
133
135
|
segments:
|
134
136
|
- 0
|
135
|
-
hash:
|
137
|
+
hash: 366040615116575159
|
136
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
139
|
none: false
|
138
140
|
requirements:
|