low 0.0.2
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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +36 -0
- data/LICENSE +22 -0
- data/README.md +4 -0
- data/Rakefile +2 -0
- data/lib/low/mongo.rb +79 -0
- data/lib/low/subdomain_map.rb +37 -0
- data/lib/low/version.rb +3 -0
- data/lib/low.rb +6 -0
- data/low.gemspec +24 -0
- data/spec/low/mongo_spec.rb +92 -0
- data/spec/low/subdomain_map_spec.rb +32 -0
- data/spec/spec_helper.rb +9 -0
- metadata +137 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
low (0.0.2)
|
5
|
+
rack
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
bson (1.6.4)
|
11
|
+
bson_ext (1.6.4)
|
12
|
+
bson (~> 1.6.4)
|
13
|
+
diff-lcs (1.1.3)
|
14
|
+
mongo (1.6.4)
|
15
|
+
bson (~> 1.6.4)
|
16
|
+
rack (1.4.1)
|
17
|
+
rack-test (0.6.1)
|
18
|
+
rack (>= 1.0)
|
19
|
+
rspec (2.10.0)
|
20
|
+
rspec-core (~> 2.10.0)
|
21
|
+
rspec-expectations (~> 2.10.0)
|
22
|
+
rspec-mocks (~> 2.10.0)
|
23
|
+
rspec-core (2.10.1)
|
24
|
+
rspec-expectations (2.10.0)
|
25
|
+
diff-lcs (~> 1.1.3)
|
26
|
+
rspec-mocks (2.10.1)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bson_ext
|
33
|
+
low!
|
34
|
+
mongo
|
35
|
+
rack-test
|
36
|
+
rspec
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Kevin Hyland
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
data/lib/low/mongo.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
|
3
|
+
module Low
|
4
|
+
# The `Mongo` module defines an interface for a Mongo helper
|
5
|
+
# class. It also includes two basic classes, `Local` and `Remote`.
|
6
|
+
module Mongo
|
7
|
+
# Simple access to a Mongo::Collection instance.
|
8
|
+
def [](collection)
|
9
|
+
db[collection]
|
10
|
+
end
|
11
|
+
|
12
|
+
# The environment's Mongo::DB instance.
|
13
|
+
def db
|
14
|
+
@db ||= connection.db(database)
|
15
|
+
end
|
16
|
+
|
17
|
+
# The environment's Mongo::Grid instance - a file store.
|
18
|
+
def grid
|
19
|
+
@grid ||= ::Mongo::Grid.new(db)
|
20
|
+
end
|
21
|
+
|
22
|
+
# The environment's Mongo::Connection instance.
|
23
|
+
def connection
|
24
|
+
@connection ||= ::Mongo::Connection.new(host)
|
25
|
+
end
|
26
|
+
|
27
|
+
# The host that `#connection` will use - either this or
|
28
|
+
# `#connection` should be overriden.
|
29
|
+
def host
|
30
|
+
end
|
31
|
+
|
32
|
+
# The database `#db` will use - must be overriden.
|
33
|
+
def database
|
34
|
+
end
|
35
|
+
|
36
|
+
# Force a new connection the next time one is needed
|
37
|
+
def reset_connection!
|
38
|
+
@grid = nil
|
39
|
+
@db = nil
|
40
|
+
@connection = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# For connecting to Mongo on localhost.
|
44
|
+
class Local
|
45
|
+
include Mongo
|
46
|
+
|
47
|
+
attr_reader :host, :database
|
48
|
+
|
49
|
+
# Specify the database upon initialization and
|
50
|
+
# assume that the host is localhost (unless told otherwise).
|
51
|
+
def initialize(database, host = nil)
|
52
|
+
@database = database
|
53
|
+
@host = host || 'localhost'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# For connecting to Mongo via a URI.
|
58
|
+
class Remote
|
59
|
+
include Mongo
|
60
|
+
|
61
|
+
attr_reader :uri
|
62
|
+
|
63
|
+
# Specify the remote URI upon initialization
|
64
|
+
def initialize(uri)
|
65
|
+
@uri = uri
|
66
|
+
end
|
67
|
+
|
68
|
+
# and use it to connect.
|
69
|
+
def connection
|
70
|
+
@connection ||= ::Mongo::Connection.from_uri(uri)
|
71
|
+
end
|
72
|
+
|
73
|
+
# The database can be extracted from the URI.
|
74
|
+
def database
|
75
|
+
uri.match(/.*\/(.*)$/)[1]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Low
|
2
|
+
# `SubdomainMap` is Rack middleware that delegates to other Rack apps based
|
3
|
+
# upon subdomain. It takes two arguments upon initialization:
|
4
|
+
#
|
5
|
+
# * `base`, the app to be called if there is no subdomain.
|
6
|
+
# * `map`, a hash that maps subdomain strings to apps.
|
7
|
+
class SubdomainMap
|
8
|
+
def initialize(base, map = {})
|
9
|
+
@base = base
|
10
|
+
@map = map
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
# If the `SERVER_NAME` environment variable has a subdomain
|
15
|
+
if env['SERVER_NAME'] =~ /(.*?)\.(?:.*)\..*/
|
16
|
+
subdomain = $1
|
17
|
+
end
|
18
|
+
|
19
|
+
if subdomain
|
20
|
+
# and we can find a corresponding app,
|
21
|
+
if app = @map[subdomain]
|
22
|
+
# call it and return the result.
|
23
|
+
app.call(env)
|
24
|
+
|
25
|
+
# Otherwise, return 403 Forbidden.
|
26
|
+
else
|
27
|
+
[403, {"Content-Type" => "text/plain"}, []]
|
28
|
+
end
|
29
|
+
|
30
|
+
# If there is no subdomain,
|
31
|
+
else
|
32
|
+
# call the base app and return the result.
|
33
|
+
@base.call(env)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/low/version.rb
ADDED
data/lib/low.rb
ADDED
data/low.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/low/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Kevin Hyland']
|
6
|
+
gem.email = ['khy@me.com']
|
7
|
+
gem.description = 'A low-level utility library.'
|
8
|
+
gem.summary = 'A low-level utility library.'
|
9
|
+
gem.homepage = ''
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = 'low'
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = Low::VERSION
|
17
|
+
|
18
|
+
gem.add_runtime_dependency 'rack'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rspec'
|
21
|
+
gem.add_development_dependency 'rack-test'
|
22
|
+
gem.add_development_dependency 'mongo'
|
23
|
+
gem.add_development_dependency 'bson_ext'
|
24
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Low::Mongo do
|
4
|
+
class MongoTest
|
5
|
+
include Low::Mongo
|
6
|
+
|
7
|
+
def host
|
8
|
+
'localhost'
|
9
|
+
end
|
10
|
+
|
11
|
+
def database
|
12
|
+
'low_test'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#[]' do
|
17
|
+
it 'should be a convenience method for access a db collection' do
|
18
|
+
mongo = MongoTest.new
|
19
|
+
db = double('mongo database')
|
20
|
+
collection = double('mongo collection')
|
21
|
+
db.should_receive('[]').with('low_collection').and_return(collection)
|
22
|
+
mongo.stub db: db
|
23
|
+
mongo['low_collection'].should == collection
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#db' do
|
28
|
+
it 'should retrieve the specified #database from the connection' do
|
29
|
+
mongo = MongoTest.new
|
30
|
+
connection = double('mongo connection')
|
31
|
+
db = double('mongo database')
|
32
|
+
connection.should_receive(:db).with('low_test').and_return(db)
|
33
|
+
mongo.stub connection: connection
|
34
|
+
mongo.db.should == db
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#connection' do
|
39
|
+
it 'should get a new ::Mongo::Connection instance for the specified #host' do
|
40
|
+
mongo = MongoTest.new
|
41
|
+
connection = double('mongo connection')
|
42
|
+
::Mongo::Connection.should_receive(:new).with('localhost').and_return(connection)
|
43
|
+
mongo.connection.should == connection
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe Low::Mongo::Local do
|
49
|
+
describe '#database' do
|
50
|
+
it 'should return the value specified at initialization' do
|
51
|
+
mongo = Low::Mongo::Local.new('low_test')
|
52
|
+
mongo.database.should == 'low_test'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#host' do
|
57
|
+
it 'should return \'localhost\' if none was specified at initialization' do
|
58
|
+
mongo = Low::Mongo::Local.new('low_test')
|
59
|
+
mongo.host.should == 'localhost'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should return the value specified at initialization' do
|
63
|
+
mongo = Low::Mongo::Local.new('low_test', '0.0.0.0')
|
64
|
+
mongo.host.should == '0.0.0.0'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe Low::Mongo::Remote do
|
70
|
+
describe '#uri' do
|
71
|
+
it 'should return the value specified at initialization' do
|
72
|
+
mongo = Low::Mongo::Remote.new('mongodb://mongo.com')
|
73
|
+
mongo.uri.should == 'mongodb://mongo.com'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#database' do
|
78
|
+
it 'should return a value extracted from the URI' do
|
79
|
+
mongo = Low::Mongo::Remote.new('mongodb://khy:secret@mongo.com/low_remote')
|
80
|
+
mongo.database.should == 'low_remote'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#connection' do
|
85
|
+
it 'should pass uri to the ::Mongo::Connection.from_uri method' do
|
86
|
+
connection = double('mongo connection')
|
87
|
+
::Mongo::Connection.should_receive(:from_uri).with('mongodb://mongo.com').and_return(connection)
|
88
|
+
mongo = Low::Mongo::Remote.new('mongodb://mongo.com')
|
89
|
+
mongo.connection.should == connection
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Low::SubdomainMap do
|
4
|
+
def map
|
5
|
+
default_app = lambda do |env|
|
6
|
+
[200, {'Content-Type' => 'text/plain'}, ['Default App']]
|
7
|
+
end
|
8
|
+
|
9
|
+
api_app = lambda do |env|
|
10
|
+
[200, {'Content-Type' => 'text/plain'}, ['API App']]
|
11
|
+
end
|
12
|
+
|
13
|
+
Low::SubdomainMap.new default_app, 'subdomain' => api_app
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should call the default app if no subdomain is specified' do
|
17
|
+
res = Rack::MockRequest.new(map).get('http://useless.info')
|
18
|
+
res.should be_ok
|
19
|
+
res.body.should == 'Default App'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should call the appropriate API app if a subdomain is specified' do
|
23
|
+
res = Rack::MockRequest.new(map).get('http://subdomain.useless.info')
|
24
|
+
res.should be_ok
|
25
|
+
res.body.should == 'API App'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should return a 403 Forbidden if the specified subdomain is not mapped' do
|
29
|
+
res = Rack::MockRequest.new(map).get('http://nonexistant.useless.info')
|
30
|
+
res.should be_forbidden
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: low
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Kevin Hyland
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-08-28 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rack
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: rspec
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :development
|
43
|
+
version_requirements: *id002
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: rack-test
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :development
|
55
|
+
version_requirements: *id003
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: mongo
|
58
|
+
prerelease: false
|
59
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
type: :development
|
67
|
+
version_requirements: *id004
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: bson_ext
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id005
|
80
|
+
description: A low-level utility library.
|
81
|
+
email:
|
82
|
+
- khy@me.com
|
83
|
+
executables: []
|
84
|
+
|
85
|
+
extensions: []
|
86
|
+
|
87
|
+
extra_rdoc_files: []
|
88
|
+
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- Gemfile
|
92
|
+
- Gemfile.lock
|
93
|
+
- LICENSE
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- lib/low.rb
|
97
|
+
- lib/low/mongo.rb
|
98
|
+
- lib/low/subdomain_map.rb
|
99
|
+
- lib/low/version.rb
|
100
|
+
- low.gemspec
|
101
|
+
- spec/low/mongo_spec.rb
|
102
|
+
- spec/low/subdomain_map_spec.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
has_rdoc: true
|
105
|
+
homepage: ""
|
106
|
+
licenses: []
|
107
|
+
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
segments:
|
125
|
+
- 0
|
126
|
+
version: "0"
|
127
|
+
requirements: []
|
128
|
+
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 1.3.6
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: A low-level utility library.
|
134
|
+
test_files:
|
135
|
+
- spec/low/mongo_spec.rb
|
136
|
+
- spec/low/subdomain_map_spec.rb
|
137
|
+
- spec/spec_helper.rb
|