moneta 1.2.0 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +418 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +27 -9
  5. data/CHANGES +28 -0
  6. data/CONTRIBUTORS +4 -2
  7. data/Gemfile +12 -8
  8. data/README.md +20 -18
  9. data/feature_matrix.yaml +2 -11
  10. data/lib/moneta.rb +9 -9
  11. data/lib/moneta/adapters/client.rb +56 -19
  12. data/lib/moneta/adapters/couch.rb +5 -0
  13. data/lib/moneta/adapters/mongo.rb +264 -7
  14. data/lib/moneta/adapters/redis.rb +5 -1
  15. data/lib/moneta/adapters/sequel.rb +45 -464
  16. data/lib/moneta/adapters/sequel/mysql.rb +66 -0
  17. data/lib/moneta/adapters/sequel/postgres.rb +80 -0
  18. data/lib/moneta/adapters/sequel/postgres_hstore.rb +240 -0
  19. data/lib/moneta/adapters/sequel/sqlite.rb +57 -0
  20. data/lib/moneta/adapters/sqlite.rb +7 -7
  21. data/lib/moneta/builder.rb +2 -2
  22. data/lib/moneta/create_support.rb +21 -0
  23. data/lib/moneta/dbm_adapter.rb +31 -0
  24. data/lib/moneta/{mixins.rb → defaults.rb} +1 -302
  25. data/lib/moneta/each_key_support.rb +27 -0
  26. data/lib/moneta/expires_support.rb +60 -0
  27. data/lib/moneta/hash_adapter.rb +68 -0
  28. data/lib/moneta/increment_support.rb +16 -0
  29. data/lib/moneta/lock.rb +6 -1
  30. data/lib/moneta/nil_values.rb +35 -0
  31. data/lib/moneta/option_support.rb +51 -0
  32. data/lib/moneta/pool.rb +38 -6
  33. data/lib/moneta/proxy.rb +1 -1
  34. data/lib/moneta/server.rb +215 -61
  35. data/lib/moneta/shared.rb +13 -7
  36. data/lib/moneta/transformer.rb +50 -8
  37. data/lib/moneta/transformer/config.rb +59 -40
  38. data/lib/moneta/transformer/helper.rb +2 -2
  39. data/lib/moneta/transformer/helper/bson.rb +5 -15
  40. data/lib/moneta/version.rb +1 -1
  41. data/lib/rack/cache/moneta.rb +14 -15
  42. data/moneta.gemspec +14 -8
  43. data/script/benchmarks +7 -3
  44. data/script/contributors +11 -6
  45. data/script/start-couchdb +27 -0
  46. data/script/start-hbase +2 -2
  47. data/script/start-services +3 -3
  48. data/spec/active_support/cache_moneta_store_spec.rb +37 -39
  49. data/spec/features/concurrent_increment.rb +2 -3
  50. data/spec/features/create_expires.rb +15 -15
  51. data/spec/features/default_expires.rb +11 -12
  52. data/spec/features/expires.rb +215 -210
  53. data/spec/features/store.rb +3 -3
  54. data/spec/helper.rb +33 -41
  55. data/spec/moneta/adapters/activerecord/adapter_activerecord_existing_connection_spec.rb +3 -1
  56. data/spec/moneta/adapters/activerecord/adapter_activerecord_spec.rb +15 -7
  57. data/spec/moneta/adapters/activerecord/standard_activerecord_spec.rb +6 -3
  58. data/spec/moneta/adapters/activerecord/standard_activerecord_with_expires_spec.rb +6 -3
  59. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_spec.rb +3 -3
  60. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_with_default_expires_spec.rb +2 -2
  61. data/spec/moneta/adapters/cassandra/standard_cassandra_spec.rb +1 -1
  62. data/spec/moneta/adapters/client/adapter_client_spec.rb +6 -6
  63. data/spec/moneta/adapters/client/client_helper.rb +24 -0
  64. data/spec/moneta/adapters/client/standard_client_tcp_spec.rb +8 -8
  65. data/spec/moneta/adapters/client/standard_client_unix_spec.rb +23 -7
  66. data/spec/moneta/adapters/couch/adapter_couch_spec.rb +1 -1
  67. data/spec/moneta/adapters/couch/standard_couch_spec.rb +2 -2
  68. data/spec/moneta/adapters/couch/standard_couch_with_expires_spec.rb +2 -2
  69. data/spec/moneta/adapters/datamapper/adapter_datamapper_spec.rb +25 -8
  70. data/spec/moneta/adapters/datamapper/standard_datamapper_spec.rb +2 -2
  71. data/spec/moneta/adapters/datamapper/standard_datamapper_with_expires_spec.rb +2 -2
  72. data/spec/moneta/adapters/datamapper/standard_datamapper_with_repository_spec.rb +2 -2
  73. data/spec/moneta/adapters/daybreak/standard_daybreak_spec.rb +1 -1
  74. data/spec/moneta/adapters/daybreak/standard_daybreak_with_expires_spec.rb +1 -1
  75. data/spec/moneta/adapters/dbm/standard_dbm_spec.rb +1 -1
  76. data/spec/moneta/adapters/dbm/standard_dbm_with_expires_spec.rb +1 -1
  77. data/spec/moneta/adapters/file/standard_file_spec.rb +2 -2
  78. data/spec/moneta/adapters/file/standard_file_with_expires_spec.rb +1 -1
  79. data/spec/moneta/adapters/gdbm/standard_gdbm_spec.rb +1 -1
  80. data/spec/moneta/adapters/gdbm/standard_gdbm_with_expires_spec.rb +1 -1
  81. data/spec/moneta/adapters/kyotocabinet/adapter_kyotocabinet_spec.rb +1 -1
  82. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_spec.rb +2 -2
  83. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_with_expires_spec.rb +2 -2
  84. data/spec/moneta/adapters/leveldb/standard_leveldb_spec.rb +1 -1
  85. data/spec/moneta/adapters/leveldb/standard_leveldb_with_expires_spec.rb +1 -1
  86. data/spec/moneta/adapters/lmdb/standard_lmdb_spec.rb +1 -1
  87. data/spec/moneta/adapters/lmdb/standard_lmdb_with_expires_spec.rb +1 -1
  88. data/spec/moneta/adapters/lruhash/standard_lruhash_spec.rb +1 -1
  89. data/spec/moneta/adapters/lruhash/standard_lruhash_with_expires_spec.rb +1 -1
  90. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_spec.rb +13 -3
  91. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_spec.rb +13 -3
  92. data/spec/moneta/adapters/memory/standard_memory_spec.rb +1 -1
  93. data/spec/moneta/adapters/memory/standard_memory_with_compress_spec.rb +1 -1
  94. data/spec/moneta/adapters/memory/standard_memory_with_expires_spec.rb +1 -1
  95. data/spec/moneta/adapters/memory/standard_memory_with_json_key_serializer_spec.rb +1 -1
  96. data/spec/moneta/adapters/memory/standard_memory_with_json_serializer_spec.rb +1 -1
  97. data/spec/moneta/adapters/memory/standard_memory_with_json_value_serializer_spec.rb +2 -2
  98. data/spec/moneta/adapters/memory/standard_memory_with_prefix_spec.rb +39 -2
  99. data/spec/moneta/adapters/memory/standard_memory_with_snappy_compress_spec.rb +2 -2
  100. data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +32 -2
  101. data/spec/moneta/adapters/mongo/adapter_mongo_with_default_expires_spec.rb +6 -4
  102. data/spec/moneta/adapters/mongo/standard_mongo_spec.rb +2 -2
  103. data/spec/moneta/adapters/pstore/standard_pstore_spec.rb +1 -1
  104. data/spec/moneta/adapters/pstore/standard_pstore_with_expires_spec.rb +1 -1
  105. data/spec/moneta/adapters/redis/adapter_redis_spec.rb +13 -3
  106. data/spec/moneta/adapters/redis/standard_redis_spec.rb +9 -2
  107. data/spec/moneta/adapters/sdbm/standard_sdbm_spec.rb +1 -1
  108. data/spec/moneta/adapters/sdbm/standard_sdbm_with_expires_spec.rb +1 -1
  109. data/spec/moneta/adapters/sequel/adapter_sequel_spec.rb +11 -38
  110. data/spec/moneta/adapters/sequel/helper.rb +42 -0
  111. data/spec/moneta/adapters/sequel/standard_sequel_spec.rb +6 -12
  112. data/spec/moneta/adapters/sequel/standard_sequel_with_expires_spec.rb +9 -10
  113. data/spec/moneta/adapters/sqlite/adapter_sqlite_spec.rb +1 -1
  114. data/spec/moneta/adapters/sqlite/standard_sqlite_spec.rb +2 -2
  115. data/spec/moneta/adapters/sqlite/standard_sqlite_with_expires_spec.rb +2 -2
  116. data/spec/moneta/adapters/tdb/standard_tdb_spec.rb +1 -1
  117. data/spec/moneta/adapters/tdb/standard_tdb_with_expires_spec.rb +1 -1
  118. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_spec.rb +1 -1
  119. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_with_expires_spec.rb +1 -1
  120. data/spec/moneta/adapters/yaml/standard_yaml_spec.rb +1 -1
  121. data/spec/moneta/adapters/yaml/standard_yaml_with_expires_spec.rb +1 -1
  122. data/spec/moneta/builder_spec.rb +22 -0
  123. data/spec/moneta/proxies/expires/expires_file_spec.rb +1 -1
  124. data/spec/moneta/proxies/pool/pool_spec.rb +31 -3
  125. data/spec/moneta/proxies/shared/shared_tcp_spec.rb +14 -4
  126. data/spec/moneta/proxies/shared/shared_unix_spec.rb +14 -4
  127. data/spec/moneta/proxies/transformer/transformer_bencode_spec.rb +1 -1
  128. data/spec/moneta/proxies/transformer/transformer_bert_spec.rb +3 -3
  129. data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +2 -2
  130. data/spec/moneta/proxies/transformer/transformer_json_spec.rb +1 -1
  131. data/spec/moneta/proxies/transformer/transformer_key_marshal_spec.rb +1 -1
  132. data/spec/moneta/proxies/transformer/transformer_key_yaml_spec.rb +1 -1
  133. data/spec/moneta/proxies/transformer/transformer_marshal_base64_spec.rb +1 -1
  134. data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +8 -4
  135. data/spec/moneta/proxies/transformer/transformer_marshal_hex_spec.rb +1 -1
  136. data/spec/moneta/proxies/transformer/transformer_marshal_hmac_spec.rb +1 -1
  137. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_base64_spec.rb +33 -0
  138. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_spec.rb +1 -1
  139. data/spec/moneta/proxies/transformer/transformer_marshal_qp_spec.rb +1 -1
  140. data/spec/moneta/proxies/transformer/transformer_marshal_spec.rb +1 -1
  141. data/spec/moneta/proxies/transformer/transformer_marshal_urlsafe_base64_spec.rb +1 -1
  142. data/spec/moneta/proxies/transformer/transformer_marshal_uuencode_spec.rb +1 -1
  143. data/spec/moneta/proxies/transformer/transformer_msgpack_spec.rb +1 -1
  144. data/spec/moneta/proxies/transformer/transformer_ox_spec.rb +1 -1
  145. data/spec/moneta/proxies/transformer/transformer_php_spec.rb +1 -1
  146. data/spec/moneta/proxies/transformer/transformer_tnet_spec.rb +1 -1
  147. data/spec/moneta/proxies/transformer/transformer_yaml_spec.rb +2 -2
  148. data/spec/moneta/proxies/weak_each_key/weak_each_key_spec.rb +0 -2
  149. data/spec/restserver.rb +15 -0
  150. metadata +47 -66
  151. data/.travis.yml +0 -140
  152. data/lib/moneta/adapters/mongo/base.rb +0 -103
  153. data/lib/moneta/adapters/mongo/moped.rb +0 -163
  154. data/lib/moneta/adapters/mongo/official.rb +0 -156
  155. data/script/reconfigure-couchdb +0 -13
  156. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_with_default_expires_spec.rb +0 -15
  157. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_with_default_expires_spec.rb +0 -15
  158. data/spec/moneta/adapters/mongo/adapter_mongo_moped_spec.rb +0 -25
  159. data/spec/moneta/adapters/mongo/adapter_mongo_moped_with_default_expires_spec.rb +0 -12
  160. data/spec/moneta/adapters/mongo/adapter_mongo_official_spec.rb +0 -25
  161. data/spec/moneta/adapters/mongo/adapter_mongo_official_with_default_expires_spec.rb +0 -12
  162. data/spec/moneta/adapters/mongo/standard_mongo_moped_spec.rb +0 -7
  163. data/spec/moneta/adapters/mongo/standard_mongo_official_spec.rb +0 -7
  164. data/spec/moneta/adapters/redis/adapter_redis_with_default_expires_spec.rb +0 -10
  165. data/spec/moneta/proxies/proxy/proxy_redis_spec.rb +0 -13
  166. data/spec/quality_spec.rb +0 -51
data/.travis.yml DELETED
@@ -1,140 +0,0 @@
1
- dist: xenial
2
- language: ruby
3
- rvm:
4
- - 2.6
5
- - 2.5
6
- - 2.4
7
- - 2.3
8
- - 2.2
9
- - jruby-9.2
10
- - rbx-3
11
- services:
12
- - mysql
13
- - riak
14
- - redis
15
- - cassandra
16
- - memcached
17
- - mongodb
18
- - postgresql
19
- addons:
20
- apt:
21
- sources:
22
- - cassandra
23
- - sourceline: "deb https://apache.bintray.com/couchdb-deb xenial main"
24
- key_url: https://couchdb.apache.org/repo/bintray-pubkey.asc
25
- - sourceline: "deb https://packagecloud.io/basho/riak/ubuntu/ xenial main"
26
- key_url: https://packagecloud.io/basho/riak/gpgkey
27
- packages:
28
- - cassandra
29
- - couchdb
30
- - libkyotocabinet-dev
31
- - libleveldb-dev
32
- - liblzo2-dev
33
- - libtdb-dev
34
- - libtokyocabinet-dev
35
- - tokyotyrant
36
- - riak
37
- postgresql: '9.6'
38
- before_install:
39
- - script/start-services
40
- cache:
41
- bundler: true
42
- directories:
43
- - downloads
44
- before_script:
45
- - mysql -e 'create database moneta;'
46
- - mysql -e 'create database moneta2;'
47
- - psql -c 'create database moneta1;' -U postgres
48
- - psql -c 'create extension hstore;' -U postgres moneta1
49
- - psql -c 'create database moneta2;' -U postgres
50
- env:
51
- matrix:
52
- - SCRIPT='script/parallel-tests ~unstable --
53
- test/action_dispatch/session_moneta_store_test.rb
54
- spec/moneta/adapters/activerecord
55
- spec/moneta/adapters/localmemcache
56
- spec/moneta/adapters/activesupportcache
57
- spec/moneta/adapters/lruhash
58
- spec/moneta/adapters/gdbm
59
- spec/moneta/adapters/null
60
- spec/moneta/adapters/datamapper
61
- spec/moneta/adapters/pstore
62
- spec/moneta/adapters/daybreak
63
- spec/moneta/adapters/redis
64
- spec/moneta/adapters/dbm
65
- spec/moneta/adapters/restclient
66
- spec/moneta/adapters/file
67
- spec/moneta/adapters/fog
68
- spec/moneta/adapters/sdbm
69
- spec/moneta/adapters/tokyocabinet
70
- spec/moneta/adapters/leveldb
71
- spec/moneta/adapters/tokyotyrant
72
- spec/moneta/adapters/lmdb
73
- spec/moneta/adapters/yaml
74
- '
75
- - SCRIPT='script/parallel-tests ~unstable --
76
- spec/moneta/adapters/client
77
- spec/moneta/adapters/memory
78
- spec/moneta/adapters/cookie
79
- spec/moneta/adapters/mongo
80
- spec/moneta/adapters/tdb
81
- spec/moneta/adapters/kyotocabinet
82
- '
83
- - SCRIPT='script/parallel-tests ~unstable --
84
- spec/moneta/adapters/couch/standard_couch_spec.rb
85
- '
86
- - SCRIPT='script/parallel-tests ~unstable --
87
- spec/moneta/adapters/couch/standard_couch_with_expires_spec.rb
88
- '
89
- - SCRIPT='script/parallel-tests ~unstable --
90
- spec/moneta/adapters/memcached/dalli
91
- '
92
- - SCRIPT='script/parallel-tests ~unstable --
93
- spec/moneta/adapters/memcached/native
94
- spec/moneta/adapters/couch/adapter_couch_spec.rb
95
- '
96
- - SCRIPT='script/parallel-tests ~unstable --
97
- spec/moneta/adapters/cassandra/adapter_cassandra_spec.rb
98
- spec/moneta/adapters/cassandra/standard_cassandra_spec.rb
99
- '
100
- - SCRIPT='script/parallel-tests ~unstable --
101
- spec/moneta/adapters/cassandra/adapter_cassandra_with_default_expires_spec.rb
102
- spec/moneta/adapters/hashfile
103
- spec/moneta/adapters/sqlite
104
- spec/moneta/adapters/sequel
105
- '
106
- - SCRIPT='script/parallel-tests ~unstable --
107
- spec/moneta/proxies
108
- '
109
- - SCRIPT='script/parallel-tests ~unstable --remainder'
110
- - SCRIPT='script/parallel-tests unstable'
111
- - SCRIPT='script/benchmarks uniform_small'
112
- - SCRIPT='script/benchmarks uniform_medium'
113
- - SCRIPT='script/benchmarks uniform_large'
114
- - SCRIPT='script/benchmarks normal_small'
115
- - SCRIPT='script/benchmarks normal_medium'
116
- - SCRIPT='script/benchmarks normal_large'
117
- - SCRIPT='rubocop lib'
118
- matrix:
119
- allow_failures:
120
- - rvm: rbx-3
121
- - env: SCRIPT='script/parallel-tests unstable'
122
- exclude:
123
- - rvm: 2.5
124
- env: SCRIPT='rubocop lib'
125
- - rvm: 2.4
126
- env: SCRIPT='rubocop lib'
127
- - rvm: 2.3
128
- env: SCRIPT='rubocop lib'
129
- - rvm: 2.2
130
- env: SCRIPT='rubocop lib'
131
- - rvm: jruby-9.2
132
- env: SCRIPT='rubocop lib'
133
- - rvm: rbx-3
134
- env: SCRIPT='rubocop lib'
135
-
136
- script: "bundle exec $SCRIPT"
137
- branches:
138
- only:
139
- - master
140
- - travis
@@ -1,103 +0,0 @@
1
- require 'bson'
2
-
3
- module Moneta
4
- module Adapters
5
- # @api private
6
- class MongoBase
7
- include Defaults
8
- include ExpiresSupport
9
-
10
- supports :each_key, :create, :increment
11
- attr_reader :backend
12
-
13
- DEFAULT_PORT = 27017
14
-
15
- def initialize(options = {})
16
- self.default_expires = options.delete(:expires)
17
- @expires_field = options.delete(:expires_field) || 'expiresAt'
18
- @value_field = options.delete(:value_field) || 'value'
19
- @type_field = options.delete(:type_field) || 'type'
20
- end
21
-
22
- # (see Proxy#fetch_values)
23
- def fetch_values(*keys, **options)
24
- return values_at(*keys, **options) unless block_given?
25
- hash = Hash[slice(*keys, **options)]
26
- keys.map do |key|
27
- if hash.key?(key)
28
- hash[key]
29
- else
30
- yield key
31
- end
32
- end
33
- end
34
-
35
- # (see Proxy#values_at)
36
- def values_at(*keys, **options)
37
- hash = Hash[slice(*keys, **options)]
38
- keys.map { |key| hash[key] }
39
- end
40
-
41
- protected
42
-
43
- def doc_to_value(doc)
44
- case doc[@type_field]
45
- when 'Hash'
46
- doc = doc.dup
47
- doc.delete('_id')
48
- doc.delete(@type_field)
49
- doc.delete(@expires_field)
50
- doc
51
- when 'Number'
52
- doc[@value_field]
53
- else
54
- # In ruby_bson version 2 (and probably up), #to_s no longer returns the binary data
55
- from_binary(doc[@value_field])
56
- end
57
- end
58
-
59
- def value_to_doc(key, value, options)
60
- case value
61
- when Hash
62
- value.merge('_id' => key,
63
- @type_field => 'Hash',
64
- # @expires_field must be a Time object (BSON date datatype)
65
- @expires_field => expires_at(options) || nil)
66
- when Float, Integer
67
- { '_id' => key,
68
- @type_field => 'Number',
69
- @value_field => value,
70
- # @expires_field must be a Time object (BSON date datatype)
71
- @expires_field => expires_at(options) || nil }
72
- when String
73
- intvalue = value.to_i
74
- { '_id' => key,
75
- @type_field => 'String',
76
- @value_field => intvalue.to_s == value ? intvalue : to_binary(value),
77
- # @expires_field must be a Time object (BSON date datatype)
78
- @expires_field => expires_at(options) || nil }
79
- else
80
- raise ArgumentError, "Invalid value type: #{value.class}"
81
- end
82
- end
83
-
84
- # BSON will use String#force_encoding to make the string 8-bit
85
- # ASCII. This could break unicode text so we should dup in this
86
- # case, and it also fails with frozen strings.
87
- def to_binary(str)
88
- str = str.dup if str.frozen? || str.encoding != Encoding::ASCII_8BIT
89
- ::BSON::Binary.new(str)
90
- end
91
-
92
- if defined?(::BSON::VERSION) and ::BSON::VERSION[0].to_i >= 2
93
- def from_binary(binary)
94
- binary.is_a?(::BSON::Binary) ? binary.data : binary.to_s
95
- end
96
- else
97
- def from_binary(binary)
98
- binary.to_s
99
- end
100
- end
101
- end
102
- end
103
- end
@@ -1,163 +0,0 @@
1
- require 'moneta/adapters/mongo/base'
2
- require 'moped'
3
-
4
- module Moneta
5
- module Adapters
6
- # MongoDB backend
7
- #
8
- # Supports expiration, documents will be automatically removed starting
9
- # with mongodb >= 2.2 (see {http://docs.mongodb.org/manual/tutorial/expire-data/}).
10
- #
11
- # You can store hashes directly using this adapter.
12
- #
13
- # @example Store hashes
14
- # db = Moneta::Adapters::MongoMoped.new
15
- # db['key'] = {a: 1, b: 2}
16
- #
17
- # @api public
18
- class MongoMoped < MongoBase
19
- # @param [Hash] options
20
- # @option options [String] :collection ('moneta') MongoDB collection name
21
- # @option options [String] :host ('127.0.0.1') MongoDB server host
22
- # @option options [String] :user Username used to authenticate
23
- # @option options [String] :password Password used to authenticate
24
- # @option options [Integer] :port (MongoDB default port) MongoDB server port
25
- # @option options [String] :db ('moneta') MongoDB database
26
- # @option options [Integer] :expires Default expiration time
27
- # @option options [String] :expires_field ('expiresAt') Document field to store expiration time
28
- # @option options [String] :value_field ('value') Document field to store value
29
- # @option options [String] :type_field ('type') Document field to store value type
30
- # @option options [::Moped::Session] :backend Use existing backend instance
31
- # @option options Other options passed to `Moped::Session#new`
32
- def initialize(options = {})
33
- super(options)
34
- collection = options.delete(:collection) || 'moneta'
35
- db = options.delete(:db) || 'moneta'
36
- user = options.delete(:user)
37
- password = options.delete(:password)
38
- @backend = options[:backend] ||
39
- begin
40
- host = options.delete(:host) || '127.0.0.1'
41
- port = options.delete(:port) || DEFAULT_PORT
42
- ::Moped::Session.new(["#{host}:#{port}"])
43
- end
44
- @backend.use(db)
45
- @backend.login(user, password) if user && password
46
- @collection = @backend[collection]
47
- if @backend.command(buildinfo: 1)['version'] >= '2.2'
48
- @collection.indexes.create({ @expires_field => 1 }, expireAfterSeconds: 0)
49
- else
50
- warn 'Moneta::Adapters::Mongo - You are using MongoDB version < 2.2, expired documents will not be deleted'
51
- end
52
- end
53
-
54
- # (see Proxy#load)
55
- def load(key, options = {})
56
- key = to_binary(key)
57
- doc = @collection.find(_id: key).one
58
- if doc && (!doc[@expires_field] || doc[@expires_field] >= Time.now)
59
- # @expires_field must be a Time object (BSON date datatype)
60
- expires = expires_at(options, nil)
61
- @collection.find(_id: key).update(:$set => { @expires_field => expires || nil }) if expires != nil
62
- doc_to_value(doc)
63
- end
64
- end
65
-
66
- # (see Proxy#store)
67
- def store(key, value, options = {})
68
- key = to_binary(key)
69
- @collection.find(_id: key).upsert(value_to_doc(key, value, options))
70
- value
71
- end
72
-
73
- # (see Proxy#each_key)
74
- def each_key
75
- return enum_for(:each_key) unless block_given?
76
- @collection.find.each { |doc| yield from_binary(doc[:_id]) }
77
- self
78
- end
79
-
80
- # (see Proxy#delete)
81
- def delete(key, options = {})
82
- value = load(key, options)
83
- @collection.find(_id: to_binary(key)).remove if value
84
- value
85
- end
86
-
87
- # (see Proxy#increment)
88
- def increment(key, amount = 1, options = {})
89
- @backend.with(safe: true, consistency: :strong) do |safe|
90
- safe[@collection.name]
91
- .find(_id: to_binary(key))
92
- .modify({ :$inc => { @value_field => amount } },
93
- new: true, upsert: true)[@value_field]
94
- end
95
- rescue ::Moped::Errors::OperationFailure
96
- tries ||= 0
97
- tries += 1
98
- retry if tries < 3
99
- raise # otherwise
100
- end
101
-
102
- # (see Proxy#create)
103
- def create(key, value, options = {})
104
- key = to_binary(key)
105
- @backend.with(safe: true, consistency: :strong) do |safe|
106
- safe[@collection.name].insert(value_to_doc(key, value, options))
107
- end
108
- true
109
- rescue ::Moped::Errors::MongoError => ex
110
- raise if ex.details['code'] != 11000 # duplicate key error
111
- false
112
- end
113
-
114
- # (see Proxy#clear)
115
- def clear(options = {})
116
- @collection.find.remove_all
117
- self
118
- end
119
-
120
- # (see Proxy#slice)
121
- def slice(*keys, **options)
122
- query = @collection.find(_id: { :$in => keys.map(&method(:to_binary)) })
123
- pairs = query.map do |doc|
124
- next if doc[@expires_field] && doc[@expires_field] < Time.now
125
- [from_binary(doc[:_id]), doc_to_value(doc)]
126
- end.compact
127
-
128
- if (expires = expires_at(options, nil)) != nil
129
- query.update_all(:$set => { @expires_field => expires || nil })
130
- end
131
-
132
- pairs
133
- end
134
-
135
- # (see Proxy#merge!)
136
- def merge!(pairs, options = {})
137
- @backend.with(safe: true, consistency: :strong) do |safe|
138
- collection = safe[@collection.name]
139
- existing = collection
140
- .find(_id: { :$in => pairs.map { |key, _| to_binary(key) }.to_a })
141
- .map { |doc| [from_binary(doc[:_id]), doc_to_value(doc)] }
142
- .to_h
143
-
144
- update_pairs, insert_pairs = pairs.partition { |key, _| existing.key?(key) }
145
- unless insert_pairs.empty?
146
- collection.insert(insert_pairs.map do |key, value|
147
- value_to_doc(to_binary(key), value, options)
148
- end)
149
- end
150
-
151
- update_pairs.each do |key, value|
152
- value = yield(key, existing[key], value) if block_given?
153
- binary = to_binary(key)
154
- collection
155
- .find(_id: binary)
156
- .update(value_to_doc(binary, value, options))
157
- end
158
- end
159
- self
160
- end
161
- end
162
- end
163
- end
@@ -1,156 +0,0 @@
1
- require 'moneta/adapters/mongo/base'
2
- require 'mongo'
3
-
4
- module Moneta
5
- module Adapters
6
- # MongoDB backend
7
- #
8
- # Supports expiration, documents will be automatically removed starting
9
- # with mongodb >= 2.2 (see {http://docs.mongodb.org/manual/tutorial/expire-data/}).
10
- #
11
- # You can store hashes directly using this adapter.
12
- #
13
- # @example Store hashes
14
- # db = Moneta::Adapters::MongoOfficial.new
15
- # db['key'] = {a: 1, b: 2}
16
- #
17
- # @api public
18
- class MongoOfficial < MongoBase
19
- # @param [Hash] options
20
- # @option options [String] :collection ('moneta') MongoDB collection name
21
- # @option options [String] :host ('127.0.0.1') MongoDB server host
22
- # @option options [String] :user Username used to authenticate
23
- # @option options [String] :password Password used to authenticate
24
- # @option options [Integer] :port (MongoDB default port) MongoDB server port
25
- # @option options [String] :db ('moneta') MongoDB database
26
- # @option options [Integer] :expires Default expiration time
27
- # @option options [String] :expires_field ('expiresAt') Document field to store expiration time
28
- # @option options [String] :value_field ('value') Document field to store value
29
- # @option options [String] :type_field ('type') Document field to store value type
30
- # @option options [::Mongo::Client] :backend Use existing backend instance
31
- # @option options Other options passed to `Mongo::MongoClient#new`
32
- def initialize(options = {})
33
- super(options)
34
- collection = options.delete(:collection) || 'moneta'
35
- db = options.delete(:db) || 'moneta'
36
- @backend = options[:backend] ||
37
- begin
38
- host = options.delete(:host) || '127.0.0.1'
39
- port = options.delete(:port) || DEFAULT_PORT
40
- options[:logger] ||= ::Logger.new(STDERR).tap do |logger|
41
- logger.level = ::Logger::ERROR
42
- end
43
- ::Mongo::Client.new(["#{host}:#{port}"], options)
44
- end
45
- @backend.use(db)
46
- @collection = @backend[collection]
47
- if @backend.command(buildinfo: 1).documents.first['version'] >= '2.2'
48
- @collection.indexes.create_one({ @expires_field => 1 }, expire_after: 0)
49
- else
50
- warn 'Moneta::Adapters::Mongo - You are using MongoDB version < 2.2, expired documents will not be deleted'
51
- end
52
- end
53
-
54
- # (see Proxy#load)
55
- def load(key, options = {})
56
- key = to_binary(key)
57
- doc = @collection.find(_id: key).limit(1).first
58
- if doc && (!doc[@expires_field] || doc[@expires_field] >= Time.now)
59
- expires = expires_at(options, nil)
60
- # @expires_field must be a Time object (BSON date datatype)
61
- @collection.update_one({ _id: key },
62
- '$set' => { @expires_field => expires }) unless expires == nil
63
- doc_to_value(doc)
64
- end
65
- end
66
-
67
- # (see Proxy#store)
68
- def store(key, value, options = {})
69
- key = to_binary(key)
70
- @collection.replace_one({ _id: key },
71
- value_to_doc(key, value, options),
72
- upsert: true)
73
- value
74
- end
75
-
76
- # (see Proxy#each_key)
77
- def each_key
78
- return enum_for(:each_key) unless block_given?
79
- @collection.find.each { |doc| yield from_binary(doc[:_id]) }
80
- self
81
- end
82
-
83
- # (see Proxy#delete)
84
- def delete(key, options = {})
85
- key = to_binary(key)
86
- if doc = @collection.find(_id: key).find_one_and_delete and
87
- !doc[@expires_field] || doc[@expires_field] >= Time.now
88
- doc_to_value(doc)
89
- end
90
- end
91
-
92
- # (see Proxy#increment)
93
- def increment(key, amount = 1, options = {})
94
- @collection.find_one_and_update({ _id: to_binary(key) },
95
- { '$inc' => { @value_field => amount } },
96
- return_document: :after,
97
- upsert: true)[@value_field]
98
- end
99
-
100
- # (see Proxy#create)
101
- def create(key, value, options = {})
102
- key = to_binary(key)
103
- @collection.insert_one(value_to_doc(key, value, options))
104
- true
105
- rescue ::Mongo::Error::OperationFailure => ex
106
- raise unless ex.message =~ /^E11000 / # duplicate key error
107
- false
108
- end
109
-
110
- # (see Proxy#clear)
111
- def clear(options = {})
112
- @collection.delete_many
113
- self
114
- end
115
-
116
- # (see Proxy#close)
117
- def close
118
- @backend.close
119
- nil
120
- end
121
-
122
- # (see Proxy#slice)
123
- def slice(*keys, **options)
124
- query = @collection.find(_id: { :$in => keys.map(&method(:to_binary)) })
125
- pairs = query.map do |doc|
126
- next if doc[@expires_field] && doc[@expires_field] < Time.now
127
- [from_binary(doc[:_id]), doc_to_value(doc)]
128
- end.compact
129
-
130
- if (expires = expires_at(options, nil)) != nil
131
- query.update_many(:$set => { @expires_field => expires || nil })
132
- end
133
-
134
- pairs
135
- end
136
-
137
- # (see Proxy#merge!)
138
- def merge!(pairs, options = {})
139
- existing = Hash[slice(*pairs.map { |key, _| key })]
140
- update_pairs, insert_pairs = pairs.partition { |key, _| existing.key?(key) }
141
-
142
- @collection.insert_many(insert_pairs.map do |key, value|
143
- value_to_doc(to_binary(key), value, options)
144
- end)
145
-
146
- update_pairs.each do |key, value|
147
- value = yield(key, existing[key], value) if block_given?
148
- binary = to_binary(key)
149
- @collection.replace_one({ _id: binary }, value_to_doc(binary, value, options))
150
- end
151
-
152
- self
153
- end
154
- end
155
- end
156
- end