moped_mapping 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +14 -0
- data/README.md +51 -0
- data/Rakefile +4 -0
- data/lib/moped_mapping/indexes_ext.rb +19 -0
- data/lib/moped_mapping/node_ext.rb +18 -0
- data/lib/moped_mapping/session_context_ext.rb +104 -0
- data/lib/moped_mapping/version.rb +3 -0
- data/lib/moped_mapping.rb +80 -0
- data/moped_mapping.gemspec +25 -0
- data/spec/moped.config.yml +6 -0
- data/spec/moped_mapping/geospatial_spec.rb +136 -0
- data/spec/moped_mapping/thread_safe_spec.rb +112 -0
- data/spec/moped_mapping_spec.rb +581 -0
- data/spec/spec_helper.rb +8 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTEwYmI1N2E2MGM0MjJkYTk3YTY0MjQ3YWNiNmNlYTRjMTAxNzA4MA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NmI3OWU0N2E5YTM3ZDhhZTY2ZDExNmMzMDI2ZDg5NzA5ZTBjNzg5Mw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGU5MTRhZGUzZjQwZGQ3NzUxYmE3Yjk1MTgwYzU0MTVhM2RkYmY3YjljYzdm
|
10
|
+
NDUwYzdmNWVmZTZlYjNjMGVhZjA2ODY4MDgyMzQyMDAwZGNmNjI5NWVhMzhm
|
11
|
+
YzRmZjAxNDc3MDQxMDhmODg3M2E2MTEzYTAxNGM1NGE1OTM4NDA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NmE3OTk4MzZiOWMzZGU5YTdlZGI1ZDkwN2M1NDQwMGNiOTZhYWIxN2ZhMTU3
|
14
|
+
MmYwZDYzYzBjYzQ1MjU5ZmE5NDczNDViNDQ2YjkyYWJhODE3NTdiMTQxMzU0
|
15
|
+
ZDRlMWUwODRhYzY0NWY0NmIzZWE2ZTQ4MzU2ODY3ZjgxZmI5ZjM=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright (C) 2013 Groovenauts, inc.
|
2
|
+
|
3
|
+
This program is free software: you can redistribute it and/or modify
|
4
|
+
it under the terms of the GNU General Public License as published by
|
5
|
+
the Free Software Foundation; either version 3 of the License, or
|
6
|
+
(at your option) any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU General Public License for more details.
|
12
|
+
|
13
|
+
You should have received a copy of the GNU General Public License
|
14
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# MopedMapping
|
2
|
+
|
3
|
+
moped extension library to switch collection.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'moped_mapping'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install moped_mapping
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Global switch
|
22
|
+
|
23
|
+
#### configuration
|
24
|
+
|
25
|
+
```
|
26
|
+
MopedMapping.enable
|
27
|
+
```
|
28
|
+
|
29
|
+
#### each action
|
30
|
+
|
31
|
+
```
|
32
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
33
|
+
# actually this document will be inserted into items@3
|
34
|
+
session["items"].insert({some: "document"})
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
## Contributing
|
40
|
+
|
41
|
+
1. Fork it
|
42
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
43
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
44
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
45
|
+
5. Create new Pull Request
|
46
|
+
|
47
|
+
## License
|
48
|
+
|
49
|
+
GPLv3
|
50
|
+
|
51
|
+
Copyright (C) 2013 Groovenauts, inc.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'moped_mapping'
|
3
|
+
|
4
|
+
module MopedMapping
|
5
|
+
module IndexesExt
|
6
|
+
def self.included(klass)
|
7
|
+
klass.module_eval do
|
8
|
+
alias_method :namespace_without_mapping, :namespace
|
9
|
+
alias_method :namespace, :namespace_with_mapping
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def namespace_with_mapping
|
14
|
+
return @namespace unless MopedMapping.enabled
|
15
|
+
col_name = MopedMapping.mapped_name(database.name, collection_name)
|
16
|
+
"#{database.name}.#{col_name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'moped_mapping'
|
3
|
+
|
4
|
+
module MopedMapping
|
5
|
+
module NodeExt
|
6
|
+
def self.included(klass)
|
7
|
+
klass.module_eval do
|
8
|
+
alias_method :query_without_mapping, :query
|
9
|
+
alias_method :query, :query_with_mapping
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def query_with_mapping(database, collection, selector, options = {}, &block)
|
14
|
+
collection = MopedMapping.mapped_name(database, collection)
|
15
|
+
return query_without_mapping(database, collection, selector, options, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'moped_mapping'
|
3
|
+
|
4
|
+
module MopedMapping
|
5
|
+
module SessionContextExt
|
6
|
+
def self.included(klass)
|
7
|
+
klass.module_eval do
|
8
|
+
%w[query insert update remove command].each do |m|
|
9
|
+
alias_method :"#{m}_without_mapping", m.to_sym
|
10
|
+
alias_method m.to_sym, :"#{m}_with_mapping"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def query_with_mapping(database, collection, selector, options = {}, &block)
|
16
|
+
collection = MopedMapping.mapped_name(database, collection)
|
17
|
+
return query_without_mapping(database, collection, selector, options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def insert_with_mapping(database, collection, documents, options = {}, &block)
|
21
|
+
collection = MopedMapping.mapped_name(database, collection)
|
22
|
+
return insert_without_mapping(database, collection, documents, options, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def update_with_mapping(database, collection, selector, change, options = {}, &block)
|
26
|
+
collection = MopedMapping.mapped_name(database, collection)
|
27
|
+
return update_without_mapping(database, collection, selector, change, options, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_with_mapping(database, collection, selector, options = {}, &block)
|
31
|
+
collection = MopedMapping.mapped_name(database, collection)
|
32
|
+
return remove_without_mapping(database, collection, selector, options, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
# MongoDBのコマンド一覧
|
36
|
+
# http://docs.mongodb.org/manual/reference/command/
|
37
|
+
|
38
|
+
# MongoDBのコマンドのうち、コレクションを対象としたコマンド名
|
39
|
+
collection_command_names = [
|
40
|
+
# #aggregation-commands
|
41
|
+
:count, :aggregate, :distinct, # group # mapReduce
|
42
|
+
# #geospatial-commands
|
43
|
+
:geoNear, :geoSearch, # :geoWalk,
|
44
|
+
# #query-and-write-operation-commands
|
45
|
+
:findAndModify, # text
|
46
|
+
# #replication-commands
|
47
|
+
# #sharding-commands
|
48
|
+
:shardCollection,
|
49
|
+
# #instance-administration-commands
|
50
|
+
:drop, :create, # :convertToCapped,
|
51
|
+
:dropIndexes, :compact, :collMod, :reIndex,
|
52
|
+
:deleteIndexes,
|
53
|
+
|
54
|
+
# #diagnostic-commands
|
55
|
+
:collStats, :validate
|
56
|
+
].freeze
|
57
|
+
|
58
|
+
COLLECTION_COMMAND_NAMES = (collection_command_names + collection_command_names.map(&:to_s).map(&:freeze)).freeze
|
59
|
+
|
60
|
+
command_args_array = [
|
61
|
+
# [:cloneCollection, :from], # このfromはホスト名を指定するので、対象外
|
62
|
+
[:cloneCollectionAsCapped, :toCollection],
|
63
|
+
].map(&:freeze).freeze
|
64
|
+
|
65
|
+
COMMAND_ARGS_ARRAY = (
|
66
|
+
command_args_array +
|
67
|
+
command_args_array.map{|args| args.map(&:to_s).map(&:freeze).freeze }
|
68
|
+
).freeze
|
69
|
+
|
70
|
+
full_name_command_names = [
|
71
|
+
:renameCollection, :to
|
72
|
+
].freeze
|
73
|
+
|
74
|
+
FULL_NAME_COMMAND_NAMES = (full_name_command_names + full_name_command_names.map(&:to_s).map(&:freeze)).freeze
|
75
|
+
|
76
|
+
def command_with_mapping(database, command, &block)
|
77
|
+
done = false
|
78
|
+
COLLECTION_COMMAND_NAMES.each do |name|
|
79
|
+
next unless command.key?(name)
|
80
|
+
command[name] = MopedMapping.mapped_name(database, command[name])
|
81
|
+
done = true
|
82
|
+
break
|
83
|
+
end
|
84
|
+
unless done
|
85
|
+
COMMAND_ARGS_ARRAY.each do |args|
|
86
|
+
next unless command.key?(args.first)
|
87
|
+
args.each do |arg|
|
88
|
+
command[arg] = MopedMapping.mapped_name(database, command[arg])
|
89
|
+
end
|
90
|
+
done = true
|
91
|
+
break
|
92
|
+
end
|
93
|
+
end
|
94
|
+
unless done
|
95
|
+
FULL_NAME_COMMAND_NAMES.each do |name|
|
96
|
+
next unless command.key?(name)
|
97
|
+
command[name] = MopedMapping.mapped_full_name(database, command[name])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return command_without_mapping(database, command, &block)
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "moped_mapping/version"
|
2
|
+
|
3
|
+
require 'moped'
|
4
|
+
|
5
|
+
module MopedMapping
|
6
|
+
extend self
|
7
|
+
|
8
|
+
attr_reader :enabled
|
9
|
+
|
10
|
+
def enable(&block) ; set_enabled(true , &block); end
|
11
|
+
def disable(&block); set_enabled(false, &block); end
|
12
|
+
|
13
|
+
def set_enabled(value)
|
14
|
+
if block_given?
|
15
|
+
bak, @enabled = @enabled, value
|
16
|
+
begin
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
@enabled = bak
|
20
|
+
end
|
21
|
+
else
|
22
|
+
@enabled = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
private :set_enabled
|
26
|
+
|
27
|
+
|
28
|
+
def db_collection_map
|
29
|
+
t = Thread.current
|
30
|
+
result = t[:MopedMapping_db_collection_map]
|
31
|
+
unless result
|
32
|
+
result = nil
|
33
|
+
result = Thread.main[:MopedMapping_db_collection_map] unless t == Thread.main
|
34
|
+
result = result.dup if result
|
35
|
+
result ||= {}
|
36
|
+
t[:MopedMapping_db_collection_map] = result
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def mapped_name(database, collection)
|
42
|
+
return collection unless MopedMapping.enabled
|
43
|
+
mapping = db_collection_map[database]
|
44
|
+
return collection unless mapping
|
45
|
+
return mapping[collection] || collection
|
46
|
+
end
|
47
|
+
|
48
|
+
def mapped_full_name(database, collection)
|
49
|
+
return collection unless MopedMapping.enabled
|
50
|
+
db, col = collection.split(/\./, 2)
|
51
|
+
return collection unless col
|
52
|
+
mapping = db_collection_map[db]
|
53
|
+
return collection unless mapping
|
54
|
+
mapped = mapping[col]
|
55
|
+
mapped ? "#{db}.#{mapped}" : collection
|
56
|
+
end
|
57
|
+
|
58
|
+
def collection_map(db_name, mapping)
|
59
|
+
if block_given?
|
60
|
+
bak, db_collection_map[db_name] = db_collection_map[db_name], mapping
|
61
|
+
begin
|
62
|
+
yield
|
63
|
+
ensure
|
64
|
+
db_collection_map[db_name] = bak
|
65
|
+
end
|
66
|
+
else
|
67
|
+
db_collection_map[db_name] = mapping
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
require "moped_mapping/session_context_ext"
|
75
|
+
require "moped_mapping/indexes_ext"
|
76
|
+
require "moped_mapping/node_ext"
|
77
|
+
|
78
|
+
Moped::Session::Context.send(:include, MopedMapping::SessionContextExt)
|
79
|
+
Moped::Indexes.send(:include, MopedMapping::IndexesExt)
|
80
|
+
Moped::Node.send(:include, MopedMapping::NodeExt)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'moped_mapping/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "moped_mapping"
|
8
|
+
spec.version = MopedMapping::VERSION
|
9
|
+
spec.authors = ["akima"]
|
10
|
+
spec.email = ["akm2000@gmail.com"]
|
11
|
+
spec.description = %q{make mapping from moped collection object to MongoDB actual collection by using Hash}
|
12
|
+
spec.summary = %q{make mapping from moped collection object to MongoDB actual collection by using Hash}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
spec.add_dependency "moped", "~> 1.5.0"
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "tengine_support"
|
25
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
require 'tengine/support/yaml_with_erb'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
|
7
|
+
describe MopedMapping do
|
8
|
+
|
9
|
+
let(:config) do
|
10
|
+
YAML.load_file(File.expand_path("../../moped.config.yml", __FILE__))["test"].with_indifferent_access
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "2d" do
|
14
|
+
|
15
|
+
before do
|
16
|
+
MopedMapping.disable
|
17
|
+
@session = Moped::Session.new(config[:sessions][:default][:hosts])
|
18
|
+
@database_name = config[:sessions][:default][:database]
|
19
|
+
@session.use(@database_name)
|
20
|
+
@session.tap do |s|
|
21
|
+
# コレクションの削除
|
22
|
+
s.collection_names.each{|col| s[col].drop }
|
23
|
+
# テスト用のデータの追加
|
24
|
+
s["points@1"].tap do |c|
|
25
|
+
c.insert(num: 1, loc: [ 0, 0])
|
26
|
+
c.insert(num: 2, loc: [10, 10])
|
27
|
+
c.insert(num: 3, loc: [20, 10])
|
28
|
+
c.insert(num: 4, loc: [10, 30])
|
29
|
+
c.indexes.create({loc: "2d"})
|
30
|
+
end
|
31
|
+
s["points@2"].tap do |c|
|
32
|
+
c.insert(num: 1, loc: [ 0, 0])
|
33
|
+
c.insert(num: 2, loc: [10, 10])
|
34
|
+
c.insert(num: 3, loc: [15, 5])
|
35
|
+
c.insert(num: 4, loc: [10, 20])
|
36
|
+
c.indexes.create({loc: "2d"})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "geoNear" do
|
42
|
+
it do
|
43
|
+
MopedMapping.collection_map(@database_name,{"points" => "points@1" })
|
44
|
+
MopedMapping.enable
|
45
|
+
# {
|
46
|
+
# "ns"=>"moped_mapping_test.points@1", "near"=>"1100000010010011010011111010100010010011010011111010",
|
47
|
+
# "results"=>[
|
48
|
+
# {"dis"=>3.605551275463989 , "obj"=>{"_id"=>"51ebfa5a73b7f70994b28e99", "num"=>2, "loc"=>[10, 10] } },
|
49
|
+
# {"dis"=>7.280109889280518 , "obj"=>{"_id"=>"51ebfa5a73b7f70994b28e9a", "num"=>3, "loc"=>[20, 10] } },
|
50
|
+
# {"dis"=>15.264337522473747, "obj"=>{"_id"=>"51ebfa5a73b7f70994b28e98", "num"=>1, "loc"=>[ 0, 0] } },
|
51
|
+
# {"dis"=>22.20360331117452 , "obj"=>{"_id"=>"51ebfa5a73b7f70994b28e9b", "num"=>4, "loc"=>[10, 30] } }
|
52
|
+
# ],
|
53
|
+
# "stats"=>{"time"=>2, "btreelocs"=>0, "nscanned"=>4, "objectsLoaded"=>4, "avgDistance"=>12.088400499598194, "maxDistance"=>22.203616792998975},
|
54
|
+
# "ok"=>1.0
|
55
|
+
# }
|
56
|
+
target = [14, 8]
|
57
|
+
r = @session.command("geoNear" => "points", "near" => target)
|
58
|
+
r["ok"].should == 1
|
59
|
+
r["results"].map{|d| d["obj"]["num"]}.should == [2,3,1,4]
|
60
|
+
MopedMapping.collection_map(@database_name,{"points" => "points@2" }) do
|
61
|
+
r = @session.command("geoNear" => "points", "near" => target)
|
62
|
+
r["ok"].should == 1
|
63
|
+
r["results"].map{|d| d["obj"]["num"]}.should == [3,2,4,1]
|
64
|
+
end
|
65
|
+
r = @session.command("geoNear" => "points", "near" => target)
|
66
|
+
r["ok"].should == 1
|
67
|
+
r["results"].map{|d| d["obj"]["num"]}.should == [2,3,1,4]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "Haystack index" do
|
73
|
+
|
74
|
+
# see http://docs.mongodb.org/manual/core/geohaystack/
|
75
|
+
before do
|
76
|
+
MopedMapping.disable
|
77
|
+
@session = Moped::Session.new(config[:sessions][:default][:hosts])
|
78
|
+
@database_name = config[:sessions][:default][:database]
|
79
|
+
@session.use(@database_name)
|
80
|
+
@session.tap do |s|
|
81
|
+
# コレクションの削除
|
82
|
+
s.collection_names.each{|col| s[col].drop }
|
83
|
+
# テスト用のデータの追加
|
84
|
+
s["places@1"].tap do |c|
|
85
|
+
c.insert({ _id: 100, pos: { lng: 126.9, lat: 35.2 } , type: "restaurant"})
|
86
|
+
c.insert({ _id: 200, pos: { lng: 127.5, lat: 36.1 } , type: "restaurant"})
|
87
|
+
c.insert({ _id: 300, pos: { lng: 128.0, lat: 36.7 } , type: "national park"})
|
88
|
+
c.indexes.create({pos: "geoHaystack", type: 1}, { bucketSize: 1 } )
|
89
|
+
end
|
90
|
+
s["places@2"].tap do |c|
|
91
|
+
c.insert({ _id: 100, pos: { lng: 106.9, lat: 25.2 } , type: "restaurant"})
|
92
|
+
c.insert({ _id: 200, pos: { lng: 127.5, lat: 36.1 } , type: "restaurant"})
|
93
|
+
c.insert({ _id: 300, pos: { lng: 128.0, lat: 36.7 } , type: "national park"})
|
94
|
+
c.indexes.create({pos: "geoHaystack", type: 1}, { bucketSize: 1 } )
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe :geoSearch do
|
100
|
+
it do
|
101
|
+
MopedMapping.collection_map(@database_name,{"places" => "places@1" })
|
102
|
+
MopedMapping.enable
|
103
|
+
target = [127.1, 35.6]
|
104
|
+
# {
|
105
|
+
# "results"=>[
|
106
|
+
# {"_id"=>100, "pos"=>{"lng"=>126.9, "lat"=>35.2}, "type"=>"restaurant"},
|
107
|
+
# {"_id"=>200, "pos"=>{"lng"=>127.5, "lat"=>36.1}, "type"=>"restaurant"}
|
108
|
+
# ],
|
109
|
+
# "stats"=>{"time"=>3, "btreeMatches"=>2, "n"=>2},
|
110
|
+
# "ok"=>1.0
|
111
|
+
# }
|
112
|
+
r = @session.command({geoSearch: "places",
|
113
|
+
search: { type: "restaurant" },
|
114
|
+
near: target,
|
115
|
+
maxDistance: 10 })
|
116
|
+
r["ok"].should == 1
|
117
|
+
r["results"].map{|d| d["_id"]}.should == [100, 200]
|
118
|
+
MopedMapping.collection_map(@database_name,{"places" => "places@2" }) do
|
119
|
+
r = @session.command({geoSearch: "places",
|
120
|
+
search: { type: "restaurant" },
|
121
|
+
near: target,
|
122
|
+
maxDistance: 10 })
|
123
|
+
r["ok"].should == 1
|
124
|
+
r["results"].map{|d| d["_id"]}.should == [200]
|
125
|
+
end
|
126
|
+
r = @session.command({geoSearch: "places",
|
127
|
+
search: { type: "restaurant" },
|
128
|
+
near: target,
|
129
|
+
maxDistance: 10 })
|
130
|
+
r["ok"].should == 1
|
131
|
+
r["results"].map{|d| d["_id"]}.should == [100, 200]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
require 'tengine/support/yaml_with_erb'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
|
7
|
+
describe MopedMapping do
|
8
|
+
|
9
|
+
let(:config) do
|
10
|
+
YAML.load_file(File.expand_path("../../moped.config.yml", __FILE__))["test"].with_indifferent_access
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "thread safe" do
|
14
|
+
before do
|
15
|
+
MopedMapping.disable
|
16
|
+
@session = Moped::Session.new(config[:sessions][:default][:hosts])
|
17
|
+
@database_name = config[:sessions][:default][:database]
|
18
|
+
@session.use(@database_name)
|
19
|
+
@session.tap do |s|
|
20
|
+
# コレクションの削除
|
21
|
+
s.collection_names.each{|col| s[col].drop }
|
22
|
+
# テスト用のデータの追加
|
23
|
+
s["test_logs@1"].tap do |c|
|
24
|
+
c.insert(num: 1)
|
25
|
+
c.insert(num: 2)
|
26
|
+
c.insert(num: 3)
|
27
|
+
c.insert(num: 4)
|
28
|
+
end
|
29
|
+
s["test_logs@2"].tap do |c|
|
30
|
+
c.insert(num: 1)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "query@1 and insert@2 parallel" do
|
36
|
+
MopedMapping.enable
|
37
|
+
database_name = config[:sessions][:default][:database]
|
38
|
+
run_insert = true
|
39
|
+
query_thread = Thread.new do
|
40
|
+
MopedMapping.collection_map(@database_name,{"test_logs" => "test_logs@1" }) do
|
41
|
+
session1 = Moped::Session.new(config[:sessions][:default][:hosts])
|
42
|
+
session1.use(database_name)
|
43
|
+
1000.times do
|
44
|
+
Thread.pass
|
45
|
+
begin
|
46
|
+
col = session1["test_logs"]
|
47
|
+
r = col.find.count
|
48
|
+
r.should == 4
|
49
|
+
rescue
|
50
|
+
run_insert = false
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
insert_thread = Thread.new do
|
58
|
+
MopedMapping.collection_map(@database_name,{"test_logs" => "test_logs@2" }) do
|
59
|
+
session2 = Moped::Session.new(config[:sessions][:default][:hosts])
|
60
|
+
session2.use(database_name)
|
61
|
+
1000.times do |idx|
|
62
|
+
Thread.pass
|
63
|
+
break unless run_insert
|
64
|
+
col = session2["test_logs"]
|
65
|
+
col.insert(num: idx + 2)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
query_thread.join
|
70
|
+
insert_thread.join
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
it "query@1 and insert@2 parallel with default collection_map defined in main thread" do
|
75
|
+
MopedMapping.collection_map(@database_name,{"test_logs" => "test_logs@1" })
|
76
|
+
MopedMapping.enable
|
77
|
+
database_name = config[:sessions][:default][:database]
|
78
|
+
run_insert = true
|
79
|
+
query_thread = Thread.new do
|
80
|
+
session1 = Moped::Session.new(config[:sessions][:default][:hosts])
|
81
|
+
session1.use(database_name)
|
82
|
+
1000.times do
|
83
|
+
Thread.pass
|
84
|
+
begin
|
85
|
+
col = session1["test_logs"]
|
86
|
+
r = col.find.count
|
87
|
+
r.should == 4
|
88
|
+
rescue
|
89
|
+
run_insert = false
|
90
|
+
raise
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
insert_thread = Thread.new do
|
96
|
+
MopedMapping.collection_map(@database_name,{"test_logs" => "test_logs@2" }) do
|
97
|
+
session2 = Moped::Session.new(config[:sessions][:default][:hosts])
|
98
|
+
session2.use(database_name)
|
99
|
+
1000.times do |idx|
|
100
|
+
Thread.pass
|
101
|
+
break unless run_insert
|
102
|
+
col = session2["test_logs"]
|
103
|
+
col.insert(num: idx + 2)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
query_thread.join
|
108
|
+
insert_thread.join
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,581 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
require 'tengine/support/yaml_with_erb'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
|
7
|
+
describe MopedMapping do
|
8
|
+
|
9
|
+
let(:config) do
|
10
|
+
YAML.load_file(File.expand_path("../moped.config.yml", __FILE__))["test"].with_indifferent_access
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
MopedMapping.disable
|
15
|
+
@session = Moped::Session.new(config[:sessions][:default][:hosts])
|
16
|
+
@database_name = config[:sessions][:default][:database]
|
17
|
+
@session.use(@database_name)
|
18
|
+
@session.tap do |s|
|
19
|
+
# コレクションの削除
|
20
|
+
s.collection_names.each{|col| s[col].drop }
|
21
|
+
# テスト用のデータの追加
|
22
|
+
s["items"].tap do |c|
|
23
|
+
c.insert(name: "foo", price: 100)
|
24
|
+
end
|
25
|
+
s["items@1"].tap do |c|
|
26
|
+
c.insert(name: "foo", price: 90)
|
27
|
+
c.insert(name: "bar", price: 200)
|
28
|
+
c.insert(name: "baz", price: 400)
|
29
|
+
end
|
30
|
+
s["items@2"].tap do |c|
|
31
|
+
c.insert(name: "foo", price: 80)
|
32
|
+
c.insert(name: "bar", price: 180)
|
33
|
+
c.insert(name: "baz", price: 350)
|
34
|
+
c.insert(name: "qux", price: 150)
|
35
|
+
end
|
36
|
+
s["items@3"].tap do |c|
|
37
|
+
c.insert(name: "bar", price: 180)
|
38
|
+
c.insert(name: "baz", price: 350)
|
39
|
+
c.insert(name: "qux", price: 400)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe :enable do
|
45
|
+
it "with block" do
|
46
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" })
|
47
|
+
col = @session["items"]
|
48
|
+
col.find.sort(price: -1).one["name"].should == "foo"
|
49
|
+
col.find.count.should == 1
|
50
|
+
MopedMapping.enable do
|
51
|
+
col.find.sort(price: -1).one["name"].should == "baz"
|
52
|
+
col.find.count.should == 3
|
53
|
+
end
|
54
|
+
col.find.sort(price: -1).one["name"].should == "foo"
|
55
|
+
col.find.count.should == 1
|
56
|
+
end
|
57
|
+
|
58
|
+
it "without block" do
|
59
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" })
|
60
|
+
col = @session["items"]
|
61
|
+
col.find.sort(price: -1).one["name"].should == "foo"
|
62
|
+
col.find.count.should == 1
|
63
|
+
MopedMapping.enable
|
64
|
+
col.find.sort(price: -1).one["name"].should == "baz"
|
65
|
+
col.find.count.should == 3
|
66
|
+
MopedMapping.disable
|
67
|
+
col.find.sort(price: -1).one["name"].should == "foo"
|
68
|
+
col.find.count.should == 1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
describe :collection_map do
|
74
|
+
it "actual usage" do
|
75
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
76
|
+
MopedMapping.enable
|
77
|
+
col = @session["items"]
|
78
|
+
col.find.sort(price: -1).one["name"].should == "baz"
|
79
|
+
col.find.count.should == 4
|
80
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
81
|
+
col.find.sort(price: -1).one["name"].should == "qux"
|
82
|
+
col.find.count.should == 3
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe :create do
|
88
|
+
it "actual usage" do
|
89
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@4" })
|
90
|
+
MopedMapping.enable
|
91
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3]
|
92
|
+
@session.command("create" => "items")
|
93
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3 items@4]
|
94
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@5" }) do
|
95
|
+
@session.command("create" => "items")
|
96
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3 items@4 items@5]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe :drop do
|
102
|
+
it "actual usage" do
|
103
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
104
|
+
MopedMapping.enable
|
105
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3]
|
106
|
+
col = @session["items"]
|
107
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
108
|
+
col.drop
|
109
|
+
@session.collection_names.should =~ %w[items items@1 items@2]
|
110
|
+
end
|
111
|
+
col.drop
|
112
|
+
@session.collection_names.should =~ %w[items items@1]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
describe :renameCollection do
|
118
|
+
it "actual usage" do
|
119
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2", "products" => "products@2" })
|
120
|
+
MopedMapping.enable
|
121
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3]
|
122
|
+
# renameCollection では単なるコレクション名ではなく、 <ネームスペース名>.<コレクション名> を指定する必要があります
|
123
|
+
@session.with(database: :admin).command("renameCollection" => "#{@database_name}.items", "to" => "#{@database_name}.products")
|
124
|
+
@session.collection_names.should =~ %w[items items@1 products@2 items@3]
|
125
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3", "products" => "products@3" }) do
|
126
|
+
@session.with(database: :admin).command("renameCollection" => "#{@database_name}.items", "to" => "#{@database_name}.products")
|
127
|
+
@session.collection_names.should =~ %w[items items@1 products@2 products@3]
|
128
|
+
end
|
129
|
+
@session.collection_names.should =~ %w[items items@1 products@2 products@3]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe :cloneCollectionAsCapped do
|
134
|
+
it "actual usage" do
|
135
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2", "products" => "products@2" })
|
136
|
+
MopedMapping.enable
|
137
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3]
|
138
|
+
@session.command("cloneCollectionAsCapped" => "items", "toCollection" => "products", "size" => 1024 * 1024)
|
139
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3 products@2]
|
140
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3", "products" => "products@3" }) do
|
141
|
+
@session.command("cloneCollectionAsCapped" => "items", "toCollection" => "products", "size" => 1024 * 1024)
|
142
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3 products@2 products@3]
|
143
|
+
end
|
144
|
+
@session.collection_names.should =~ %w[items items@1 items@2 items@3 products@2 products@3]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
describe :distinct do
|
150
|
+
it "actual usage" do
|
151
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
152
|
+
MopedMapping.enable
|
153
|
+
col = @session["items"]
|
154
|
+
col.find.distinct(:name).should =~ %w[foo bar baz qux]
|
155
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
156
|
+
col.find.distinct(:name).should =~ %w[bar baz qux]
|
157
|
+
end
|
158
|
+
col.find.distinct(:name).should =~ %w[foo bar baz qux]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe :findAndModify do
|
163
|
+
it "actual usage" do
|
164
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
165
|
+
MopedMapping.enable
|
166
|
+
col = @session["items"]
|
167
|
+
col.find(name: "bar").modify({"$set" => {price: 190}})
|
168
|
+
col.find(name: "bar").one["price"].should == 190
|
169
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
170
|
+
col.find(name: "bar").modify({"$set" => {price: 200}})
|
171
|
+
col.find(name: "bar").one["price"].should == 200
|
172
|
+
end
|
173
|
+
col.find(name: "bar").one["price"].should == 190
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
describe :create_index do
|
181
|
+
it "actual usage" do
|
182
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
183
|
+
MopedMapping.enable
|
184
|
+
col = @session["items"]
|
185
|
+
col.indexes.create({name: 1}, {name: "items_2_name"})
|
186
|
+
%w[items items@2].each do |col_name|
|
187
|
+
col.indexes[{"name" => 1}]["name"].should == "items_2_name"
|
188
|
+
end
|
189
|
+
|
190
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
191
|
+
col.indexes.create({"name" => 1}, {name: "items_3_name"})
|
192
|
+
%w[items items@2].each do |col_name|
|
193
|
+
col.indexes[{"name" => 1}]["name"].should == "items_3_name"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
%w[items items@2].each do |col_name|
|
198
|
+
col.indexes[{"name" => 1}]["name"].should == "items_2_name"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe :drop_index do
|
204
|
+
it "actual usage" do
|
205
|
+
%w[items items@1 items@2 items@3].each do |col_name|
|
206
|
+
col = @session[col_name]
|
207
|
+
col.indexes.create({name: 1}, {name: "#{col_name}_name"})
|
208
|
+
col.indexes.create({price: 1}, {name: "#{col_name}_price"})
|
209
|
+
end
|
210
|
+
|
211
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
212
|
+
MopedMapping.enable
|
213
|
+
col = @session["items"]
|
214
|
+
col.indexes.drop({"name" => 1})
|
215
|
+
%w[items items@2].each do |col_name|
|
216
|
+
col.indexes.to_a.map{|idx| idx["name"]}.should =~ ["_id_", "items@2_price"]
|
217
|
+
end
|
218
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
219
|
+
col = @session["items"]
|
220
|
+
col.indexes.drop({"price" => 1})
|
221
|
+
%w[items items@3].each do |col_name|
|
222
|
+
col.indexes.to_a.map{|idx| idx["name"]}.should =~ ["_id_", "items@3_name"]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe :insert do
|
229
|
+
it do
|
230
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" })
|
231
|
+
MopedMapping.disable do
|
232
|
+
@session["items"].find.count.should == 1
|
233
|
+
@session["items@2"].find.count.should == 4
|
234
|
+
@session["items@3"].find.count.should == 3
|
235
|
+
end
|
236
|
+
MopedMapping.enable
|
237
|
+
col = @session["items"]
|
238
|
+
col.find.count.should == 4
|
239
|
+
col.insert({name: "quux", price: 500})
|
240
|
+
col.find.count.should == 5
|
241
|
+
@session["items"].find.count.should == 5
|
242
|
+
MopedMapping.disable do
|
243
|
+
@session["items"].find.count.should == 1
|
244
|
+
@session["items@2"].find.count.should == 5
|
245
|
+
@session["items@3"].find.count.should == 3
|
246
|
+
end
|
247
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
248
|
+
@session["items"].find.count.should == 3
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
describe :find_one do
|
255
|
+
it do
|
256
|
+
MopedMapping.disable do
|
257
|
+
@session["items" ].find(name: "foo").one["price"].should == 100
|
258
|
+
@session["items@1"].find(name: "foo").one["price"].should == 90
|
259
|
+
@session["items@2"].find(name: "foo").one["price"].should == 80
|
260
|
+
@session["items@3"].find(name: "foo").one.should == nil
|
261
|
+
end
|
262
|
+
MopedMapping.enable
|
263
|
+
col = @session["items"]
|
264
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
265
|
+
col.find(name: "foo").one["price"].should == 90
|
266
|
+
end
|
267
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
268
|
+
col.find(name: "foo").one["price"].should == 80
|
269
|
+
end
|
270
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
271
|
+
col.find(name: "foo").one.should == nil
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def assert_item_prices(col, name_to_prices)
|
277
|
+
name_to_prices.each do |k,v|
|
278
|
+
begin
|
279
|
+
@session[col].find(name: k).one["price"].should == v
|
280
|
+
rescue
|
281
|
+
puts "[#{col}] #{k} => #{v}"
|
282
|
+
raise
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe :find_with_cursor do
|
288
|
+
it do
|
289
|
+
MopedMapping.enable
|
290
|
+
col = @session["items"]
|
291
|
+
cond = { price: {"$gte" => 100, "$lte" => 350} }
|
292
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
293
|
+
col.find(cond).sort(price: 1).map{|r| r["name"]}.should == %w[bar]
|
294
|
+
end
|
295
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
296
|
+
col.find(cond).sort(price: 1).map{|r| r["name"]}.should == %w[qux bar baz]
|
297
|
+
end
|
298
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
299
|
+
col.find(cond).sort(price: 1).map{|r| r["name"]}.should == %w[bar baz]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
describe :update do
|
306
|
+
it "match just one" do
|
307
|
+
MopedMapping.enable
|
308
|
+
col = @session["items"]
|
309
|
+
change = {"$inc" => {price: 30}}
|
310
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
311
|
+
col.find(name: "foo").update(change)
|
312
|
+
end
|
313
|
+
MopedMapping.disable do
|
314
|
+
@session["items" ].find(name: "foo").one["price"].should == 100
|
315
|
+
@session["items@1"].find(name: "foo").one["price"].should == 120
|
316
|
+
@session["items@2"].find(name: "foo").one["price"].should == 80
|
317
|
+
@session["items@3"].find(name: "foo").one.should == nil
|
318
|
+
end
|
319
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
320
|
+
col.find(name: "foo").update(change)
|
321
|
+
end
|
322
|
+
MopedMapping.disable do
|
323
|
+
@session["items" ].find(name: "foo").one["price"].should == 100
|
324
|
+
@session["items@1"].find(name: "foo").one["price"].should == 120
|
325
|
+
@session["items@2"].find(name: "foo").one["price"].should == 110
|
326
|
+
@session["items@3"].find(name: "foo").one.should == nil
|
327
|
+
end
|
328
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
329
|
+
col.find(name: "foo").update(change)
|
330
|
+
end
|
331
|
+
MopedMapping.disable do
|
332
|
+
@session["items" ].find(name: "foo").one["price"].should == 100
|
333
|
+
@session["items@1"].find(name: "foo").one["price"].should == 120
|
334
|
+
@session["items@2"].find(name: "foo").one["price"].should == 110
|
335
|
+
@session["items@3"].find(name: "foo").one.should == nil
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
it "match some documents and does not use update_all but update" do
|
340
|
+
MopedMapping.disable do
|
341
|
+
{
|
342
|
+
"items@1" => {"foo" => 90, "bar" => 200, "baz" => 400},
|
343
|
+
"items@2" => {"foo" => 80, "bar" => 180, "baz" => 350, "qux" => 150},
|
344
|
+
"items@3" => { "bar" => 180, "baz" => 350, "qux" => 400},
|
345
|
+
}.each do |col, hash|
|
346
|
+
hash.each do |k,v|
|
347
|
+
@session[col].find(name: k).one["price"].should == v
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
MopedMapping.enable
|
352
|
+
col = @session["items"]
|
353
|
+
cond = { price: {"$gte" => 100, "$lte" => 350} }
|
354
|
+
change = {"$inc" => {price: 30}}
|
355
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
356
|
+
col.find(cond).update(change)
|
357
|
+
end
|
358
|
+
MopedMapping.disable do
|
359
|
+
{
|
360
|
+
"items@1" => {"foo" => 90, "bar" => 230, "baz" => 400},
|
361
|
+
"items@2" => {"foo" => 80, "bar" => 180, "baz" => 350, "qux" => 150},
|
362
|
+
"items@3" => { "bar" => 180, "baz" => 350, "qux" => 400},
|
363
|
+
}.each do |col, hash|
|
364
|
+
hash.each do |k,v|
|
365
|
+
@session[col].find(name: k).one["price"].should == v
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
370
|
+
col.find(cond).update(change)
|
371
|
+
end
|
372
|
+
MopedMapping.disable do
|
373
|
+
{
|
374
|
+
"items@1" => {"foo" => 90, "bar" => 230, "baz" => 400},
|
375
|
+
"items@2" => {"foo" => 80, "bar" => 210, "baz" => 350, "qux" => 150},
|
376
|
+
"items@3" => { "bar" => 180, "baz" => 350, "qux" => 400},
|
377
|
+
}.each do |col, hash|
|
378
|
+
hash.each do |k,v|
|
379
|
+
@session[col].find(name: k).one["price"].should == v
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
384
|
+
col.find(cond).update(change)
|
385
|
+
end
|
386
|
+
MopedMapping.disable do
|
387
|
+
{
|
388
|
+
"items@1" => {"foo" => 90, "bar" => 230, "baz" => 400},
|
389
|
+
"items@2" => {"foo" => 80, "bar" => 210, "baz" => 350, "qux" => 150},
|
390
|
+
"items@3" => { "bar" => 210, "baz" => 350, "qux" => 400},
|
391
|
+
}.each do |col, hash|
|
392
|
+
hash.each do |k,v|
|
393
|
+
@session[col].find(name: k).one["price"].should == v
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
it "match some documents and use update_all" do
|
400
|
+
MopedMapping.disable do
|
401
|
+
assert_item_prices "items@1", {"foo" => 90, "bar" => 200, "baz" => 400}
|
402
|
+
assert_item_prices "items@2", {"foo" => 80, "bar" => 180, "baz" => 350, "qux" => 150}
|
403
|
+
assert_item_prices "items@3", { "bar" => 180, "baz" => 350, "qux" => 400}
|
404
|
+
end
|
405
|
+
MopedMapping.enable
|
406
|
+
col = @session["items"]
|
407
|
+
cond = { price: {"$gte" => 100, "$lte" => 350} }
|
408
|
+
change = {"$inc" => {price: 30}}
|
409
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
410
|
+
col.find(cond).update_all(change)
|
411
|
+
end
|
412
|
+
MopedMapping.disable do
|
413
|
+
assert_item_prices "items@1", {"foo" => 90, "bar" => 230, "baz" => 400}
|
414
|
+
assert_item_prices "items@2", {"foo" => 80, "bar" => 180, "baz" => 350, "qux" => 150}
|
415
|
+
assert_item_prices "items@3", { "bar" => 180, "baz" => 350, "qux" => 400}
|
416
|
+
end
|
417
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
418
|
+
col.find(cond).update_all(change)
|
419
|
+
end
|
420
|
+
MopedMapping.disable do
|
421
|
+
assert_item_prices "items@1", {"foo" => 90, "bar" => 230, "baz" => 400}
|
422
|
+
assert_item_prices "items@2", {"foo" => 80, "bar" => 210, "baz" => 380, "qux" => 180}
|
423
|
+
assert_item_prices "items@3", { "bar" => 180, "baz" => 350, "qux" => 400}
|
424
|
+
end
|
425
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
426
|
+
col.find(cond).update_all(change)
|
427
|
+
end
|
428
|
+
MopedMapping.disable do
|
429
|
+
assert_item_prices "items@1", {"foo" => 90, "bar" => 230, "baz" => 400}
|
430
|
+
assert_item_prices "items@2", {"foo" => 80, "bar" => 210, "baz" => 380, "qux" => 180}
|
431
|
+
assert_item_prices "items@3", { "bar" => 210, "baz" => 380, "qux" => 400}
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
it "match just one and upsert" do
|
436
|
+
MopedMapping.enable
|
437
|
+
col = @session["items"]
|
438
|
+
change = {name: "foo", price: 60}
|
439
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
440
|
+
col.find(name: "foo").upsert(change)
|
441
|
+
end
|
442
|
+
MopedMapping.disable do
|
443
|
+
assert_item_prices "items@1", {"foo" => 60, "bar" => 200, "baz" => 400}
|
444
|
+
assert_item_prices "items@2", {"foo" => 80, "bar" => 180, "baz" => 350, "qux" => 150}
|
445
|
+
assert_item_prices "items@3", { "bar" => 180, "baz" => 350, "qux" => 400}
|
446
|
+
end
|
447
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
448
|
+
col.find(name: "foo").upsert(change)
|
449
|
+
end
|
450
|
+
MopedMapping.disable do
|
451
|
+
assert_item_prices "items@1", {"foo" => 60, "bar" => 200, "baz" => 400}
|
452
|
+
assert_item_prices "items@2", {"foo" => 60, "bar" => 180, "baz" => 350, "qux" => 150}
|
453
|
+
assert_item_prices "items@3", { "bar" => 180, "baz" => 350, "qux" => 400}
|
454
|
+
end
|
455
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
456
|
+
col.find(name: "foo").upsert(change)
|
457
|
+
end
|
458
|
+
MopedMapping.disable do
|
459
|
+
assert_item_prices "items@1", {"foo" => 60, "bar" => 200, "baz" => 400}
|
460
|
+
assert_item_prices "items@2", {"foo" => 60, "bar" => 180, "baz" => 350, "qux" => 150}
|
461
|
+
assert_item_prices "items@3", {"foo" => 60, "bar" => 180, "baz" => 350, "qux" => 400}
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
end
|
466
|
+
|
467
|
+
|
468
|
+
describe :remove do
|
469
|
+
it "match just one" do
|
470
|
+
MopedMapping.enable
|
471
|
+
col = @session["items"]
|
472
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
473
|
+
col.find(name: "foo").remove
|
474
|
+
end
|
475
|
+
MopedMapping.disable do
|
476
|
+
@session["items" ].find.count.should == 1
|
477
|
+
@session["items@1"].find.count.should == 2
|
478
|
+
@session["items@2"].find.count.should == 4
|
479
|
+
@session["items@3"].find.count.should == 3
|
480
|
+
end
|
481
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
482
|
+
col.find(name: "foo").remove
|
483
|
+
end
|
484
|
+
MopedMapping.disable do
|
485
|
+
@session["items" ].find.count.should == 1
|
486
|
+
@session["items@1"].find.count.should == 2
|
487
|
+
@session["items@2"].find.count.should == 3
|
488
|
+
@session["items@3"].find.count.should == 3
|
489
|
+
end
|
490
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
491
|
+
col.find(name: "foo").remove
|
492
|
+
end
|
493
|
+
MopedMapping.disable do
|
494
|
+
@session["items" ].find.count.should == 1
|
495
|
+
@session["items@1"].find.count.should == 2
|
496
|
+
@session["items@2"].find.count.should == 3
|
497
|
+
@session["items@3"].find.count.should == 3
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
it "match some documents and does not use remove_all but remove" do
|
502
|
+
MopedMapping.disable do
|
503
|
+
@session["items" ].find.count.should == 1
|
504
|
+
@session["items@1"].find.count.should == 3
|
505
|
+
@session["items@2"].find.count.should == 4
|
506
|
+
@session["items@3"].find.count.should == 3
|
507
|
+
end
|
508
|
+
MopedMapping.enable
|
509
|
+
col = @session["items"]
|
510
|
+
cond = { price: {"$gte" => 100, "$lte" => 350} }
|
511
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
512
|
+
col.find(cond).remove
|
513
|
+
end
|
514
|
+
MopedMapping.disable do
|
515
|
+
@session["items" ].find.count.should == 1
|
516
|
+
@session["items@1"].find.count.should == 2
|
517
|
+
@session["items@2"].find.count.should == 4
|
518
|
+
@session["items@3"].find.count.should == 3
|
519
|
+
end
|
520
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
521
|
+
col.find(cond).remove
|
522
|
+
end
|
523
|
+
MopedMapping.disable do
|
524
|
+
@session["items" ].find.count.should == 1
|
525
|
+
@session["items@1"].find.count.should == 2
|
526
|
+
@session["items@2"].find.count.should == 3
|
527
|
+
@session["items@3"].find.count.should == 3
|
528
|
+
end
|
529
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
530
|
+
col.find(cond).remove
|
531
|
+
end
|
532
|
+
MopedMapping.disable do
|
533
|
+
@session["items" ].find.count.should == 1
|
534
|
+
@session["items@1"].find.count.should == 2
|
535
|
+
@session["items@2"].find.count.should == 3
|
536
|
+
@session["items@3"].find.count.should == 2
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
it "match some documents and use remove_all" do
|
541
|
+
MopedMapping.disable do
|
542
|
+
@session["items" ].find.count.should == 1
|
543
|
+
@session["items@1"].find.count.should == 3
|
544
|
+
@session["items@2"].find.count.should == 4
|
545
|
+
@session["items@3"].find.count.should == 3
|
546
|
+
end
|
547
|
+
MopedMapping.enable
|
548
|
+
col = @session["items"]
|
549
|
+
cond = { price: {"$gte" => 100, "$lte" => 350} }
|
550
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@1" }) do
|
551
|
+
col.find(cond).remove_all
|
552
|
+
end
|
553
|
+
MopedMapping.disable do
|
554
|
+
@session["items" ].find.count.should == 1
|
555
|
+
@session["items@1"].find.count.should == 2
|
556
|
+
@session["items@2"].find.count.should == 4
|
557
|
+
@session["items@3"].find.count.should == 3
|
558
|
+
end
|
559
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@2" }) do
|
560
|
+
col.find(cond).remove_all
|
561
|
+
end
|
562
|
+
MopedMapping.disable do
|
563
|
+
@session["items" ].find.count.should == 1
|
564
|
+
@session["items@1"].find.count.should == 2
|
565
|
+
@session["items@2"].find.count.should == 1
|
566
|
+
@session["items@3"].find.count.should == 3
|
567
|
+
end
|
568
|
+
MopedMapping.collection_map(@database_name,{"items" => "items@3" }) do
|
569
|
+
col.find(cond).remove_all
|
570
|
+
end
|
571
|
+
MopedMapping.disable do
|
572
|
+
@session["items" ].find.count.should == 1
|
573
|
+
@session["items@1"].find.count.should == 2
|
574
|
+
@session["items@2"].find.count.should == 1
|
575
|
+
@session["items@3"].find.count.should == 1
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
end
|
580
|
+
|
581
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: moped_mapping
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- akima
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: moped
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.5.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tengine_support
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: make mapping from moped collection object to MongoDB actual collection
|
70
|
+
by using Hash
|
71
|
+
email:
|
72
|
+
- akm2000@gmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/moped_mapping.rb
|
83
|
+
- lib/moped_mapping/indexes_ext.rb
|
84
|
+
- lib/moped_mapping/node_ext.rb
|
85
|
+
- lib/moped_mapping/session_context_ext.rb
|
86
|
+
- lib/moped_mapping/version.rb
|
87
|
+
- moped_mapping.gemspec
|
88
|
+
- spec/moped.config.yml
|
89
|
+
- spec/moped_mapping/geospatial_spec.rb
|
90
|
+
- spec/moped_mapping/thread_safe_spec.rb
|
91
|
+
- spec/moped_mapping_spec.rb
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
homepage: ''
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.0.3
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: make mapping from moped collection object to MongoDB actual collection by
|
117
|
+
using Hash
|
118
|
+
test_files:
|
119
|
+
- spec/moped.config.yml
|
120
|
+
- spec/moped_mapping/geospatial_spec.rb
|
121
|
+
- spec/moped_mapping/thread_safe_spec.rb
|
122
|
+
- spec/moped_mapping_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
has_rdoc:
|