moneta 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (446) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +83 -32
  5. data/.yardopts +6 -1
  6. data/CHANGES +30 -0
  7. data/CONTRIBUTORS +4 -0
  8. data/Gemfile +28 -36
  9. data/LICENSE +1 -1
  10. data/README.md +136 -67
  11. data/SPEC.md +70 -0
  12. data/feature_matrix.yaml +235 -0
  13. data/lib/active_support/cache/moneta_store.rb +102 -6
  14. data/lib/moneta.rb +9 -2
  15. data/lib/moneta/adapters/activerecord.rb +258 -98
  16. data/lib/moneta/adapters/activesupportcache.rb +133 -0
  17. data/lib/moneta/adapters/cassandra.rb +290 -44
  18. data/lib/moneta/adapters/client.rb +11 -2
  19. data/lib/moneta/adapters/couch.rb +179 -25
  20. data/lib/moneta/adapters/datamapper.rb +1 -0
  21. data/lib/moneta/adapters/daybreak.rb +21 -4
  22. data/lib/moneta/adapters/dbm.rb +7 -7
  23. data/lib/moneta/adapters/file.rb +11 -1
  24. data/lib/moneta/adapters/gdbm.rb +7 -7
  25. data/lib/moneta/adapters/kyotocabinet.rb +66 -1
  26. data/lib/moneta/adapters/leveldb.rb +27 -1
  27. data/lib/moneta/adapters/lmdb.rb +29 -1
  28. data/lib/moneta/adapters/lruhash.rb +30 -0
  29. data/lib/moneta/adapters/memcached/dalli.rb +50 -5
  30. data/lib/moneta/adapters/memcached/native.rb +11 -4
  31. data/lib/moneta/adapters/memory.rb +2 -0
  32. data/lib/moneta/adapters/mongo/base.rb +32 -7
  33. data/lib/moneta/adapters/mongo/moped.rb +59 -2
  34. data/lib/moneta/adapters/mongo/official.rb +40 -0
  35. data/lib/moneta/adapters/pstore.rb +56 -8
  36. data/lib/moneta/adapters/redis.rb +79 -19
  37. data/lib/moneta/adapters/sdbm.rb +7 -7
  38. data/lib/moneta/adapters/sequel.rb +440 -39
  39. data/lib/moneta/adapters/sqlite.rb +74 -10
  40. data/lib/moneta/adapters/tdb.rb +16 -1
  41. data/lib/moneta/adapters/tokyocabinet.rb +7 -1
  42. data/lib/moneta/adapters/tokyotyrant.rb +22 -0
  43. data/lib/moneta/cache.rb +11 -1
  44. data/lib/moneta/expires.rb +110 -8
  45. data/lib/moneta/lock.rb +21 -2
  46. data/lib/moneta/mixins.rb +279 -3
  47. data/lib/moneta/pool.rb +15 -6
  48. data/lib/moneta/proxy.rb +46 -2
  49. data/lib/moneta/server.rb +5 -1
  50. data/lib/moneta/shared.rb +27 -11
  51. data/lib/moneta/stack.rb +1 -1
  52. data/lib/moneta/synchronize.rb +2 -8
  53. data/lib/moneta/transformer.rb +152 -2
  54. data/lib/moneta/transformer/config.rb +2 -0
  55. data/lib/moneta/transformer/helper.rb +2 -2
  56. data/lib/moneta/version.rb +1 -1
  57. data/lib/moneta/weak_each_key.rb +74 -0
  58. data/lib/moneta/wrapper.rb +25 -0
  59. data/moneta.gemspec +2 -2
  60. data/script/benchmarks +174 -62
  61. data/script/parallel-tests +58 -83
  62. data/script/start-hbase +46 -0
  63. data/script/start-services +9 -2
  64. data/script/update-feature-matrix +148 -0
  65. data/spec/active_support/cache_moneta_store_spec.rb +132 -109
  66. data/spec/features/concurrent_create.rb +21 -0
  67. data/spec/features/concurrent_increment.rb +32 -0
  68. data/spec/features/create.rb +25 -0
  69. data/spec/features/create_expires.rb +19 -0
  70. data/spec/features/default_expires.rb +15 -0
  71. data/spec/features/each_key.rb +119 -0
  72. data/spec/features/expires.rb +291 -0
  73. data/spec/features/features.rb +16 -0
  74. data/spec/features/increment.rb +98 -0
  75. data/spec/features/marshallable_key.rb +43 -0
  76. data/spec/features/marshallable_value.rb +7 -0
  77. data/spec/features/multiprocess.rb +8 -0
  78. data/spec/features/not_create.rb +7 -0
  79. data/spec/features/not_each_key.rb +7 -0
  80. data/spec/features/not_increment.rb +13 -0
  81. data/spec/features/not_persist.rb +9 -0
  82. data/spec/features/null.rb +66 -0
  83. data/spec/features/persist.rb +14 -0
  84. data/spec/features/returndifferent.rb +9 -0
  85. data/spec/features/returnsame.rb +9 -0
  86. data/spec/features/store.rb +261 -0
  87. data/spec/features/store_large.rb +13 -0
  88. data/spec/features/transform_value.rb +44 -0
  89. data/spec/features/transform_value_expires.rb +41 -0
  90. data/spec/helper.rb +391 -74
  91. data/spec/moneta/adapters/activerecord/adapter_activerecord_existing_connection_spec.rb +59 -0
  92. data/spec/moneta/adapters/activerecord/adapter_activerecord_spec.rb +118 -0
  93. data/spec/moneta/adapters/activerecord/standard_activerecord_spec.rb +18 -0
  94. data/spec/moneta/adapters/activerecord/standard_activerecord_with_expires_spec.rb +24 -0
  95. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_spec.rb +51 -0
  96. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_with_default_expires_spec.rb +51 -0
  97. data/spec/moneta/adapters/cassandra/adapter_cassandra_spec.rb +17 -0
  98. data/spec/moneta/adapters/cassandra/adapter_cassandra_with_default_expires_spec.rb +18 -0
  99. data/spec/moneta/adapters/cassandra/helper.rb +18 -0
  100. data/spec/moneta/adapters/cassandra/standard_cassandra_spec.rb +18 -0
  101. data/spec/moneta/adapters/client/adapter_client_spec.rb +11 -0
  102. data/spec/moneta/adapters/client/standard_client_tcp_spec.rb +23 -0
  103. data/spec/moneta/adapters/client/standard_client_unix_spec.rb +12 -0
  104. data/spec/moneta/adapters/cookie/adapter_cookie_spec.rb +7 -0
  105. data/spec/moneta/adapters/couch/adapter_couch_spec.rb +7 -0
  106. data/spec/moneta/adapters/couch/standard_couch_spec.rb +9 -0
  107. data/spec/moneta/adapters/couch/standard_couch_with_expires_spec.rb +13 -0
  108. data/spec/moneta/adapters/datamapper/adapter_datamapper_spec.rb +43 -0
  109. data/spec/moneta/adapters/datamapper/standard_datamapper_spec.rb +21 -0
  110. data/spec/moneta/adapters/datamapper/standard_datamapper_with_expires_spec.rb +26 -0
  111. data/spec/moneta/adapters/datamapper/standard_datamapper_with_repository_spec.rb +22 -0
  112. data/spec/moneta/adapters/daybreak/adapter_daybreak_spec.rb +7 -0
  113. data/spec/moneta/adapters/daybreak/standard_daybreak_spec.rb +7 -0
  114. data/spec/moneta/adapters/daybreak/standard_daybreak_with_expires_spec.rb +11 -0
  115. data/spec/moneta/adapters/dbm/adapter_dbm_spec.rb +7 -0
  116. data/spec/moneta/adapters/dbm/standard_dbm_spec.rb +7 -0
  117. data/spec/moneta/adapters/dbm/standard_dbm_with_expires_spec.rb +12 -0
  118. data/spec/moneta/adapters/file/adapter_file_spec.rb +7 -0
  119. data/spec/moneta/adapters/file/standard_file_spec.rb +7 -0
  120. data/spec/moneta/adapters/file/standard_file_with_expires_spec.rb +11 -0
  121. data/spec/moneta/adapters/fog/adapter_fog_spec.rb +16 -0
  122. data/spec/moneta/adapters/fog/standard_fog_spec.rb +15 -0
  123. data/spec/moneta/adapters/fog/standard_fog_with_expires_spec.rb +20 -0
  124. data/spec/moneta/adapters/gdbm/adapter_gdbm_spec.rb +7 -0
  125. data/spec/moneta/adapters/gdbm/standard_gdbm_spec.rb +7 -0
  126. data/spec/moneta/adapters/gdbm/standard_gdbm_with_expires_spec.rb +11 -0
  127. data/spec/moneta/adapters/hashfile/standard_hashfile_spec.rb +7 -0
  128. data/spec/moneta/adapters/hashfile/standard_hashfile_with_expires_spec.rb +12 -0
  129. data/spec/moneta/adapters/hbase/adapter_hbase_spec.rb +7 -0
  130. data/spec/moneta/adapters/hbase/standard_hbase_spec.rb +4 -0
  131. data/spec/moneta/adapters/hbase/standard_hbase_with_expires_spec.rb +8 -0
  132. data/spec/moneta/adapters/kyotocabinet/adapter_kyotocabinet_spec.rb +7 -0
  133. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_spec.rb +7 -0
  134. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_with_expires_spec.rb +14 -0
  135. data/spec/moneta/adapters/leveldb/adapter_leveldb_spec.rb +7 -0
  136. data/spec/moneta/adapters/leveldb/standard_leveldb_spec.rb +7 -0
  137. data/spec/moneta/adapters/leveldb/standard_leveldb_with_expires_spec.rb +11 -0
  138. data/spec/moneta/adapters/lmdb/adapter_lmdb_spec.rb +7 -0
  139. data/spec/moneta/adapters/lmdb/adapter_lmdb_with_db_spec.rb +7 -0
  140. data/spec/moneta/adapters/lmdb/standard_lmdb_spec.rb +7 -0
  141. data/spec/moneta/adapters/lmdb/standard_lmdb_with_expires_spec.rb +11 -0
  142. data/spec/moneta/adapters/localmemcache/adapter_localmemcache_spec.rb +7 -0
  143. data/spec/moneta/adapters/localmemcache/standard_localmemcache_spec.rb +7 -0
  144. data/spec/moneta/adapters/localmemcache/standard_localmemcache_with_expires_spec.rb +11 -0
  145. data/spec/moneta/{adapter_lruhash_spec.rb → adapters/lruhash/adapter_lruhash_spec.rb} +3 -25
  146. data/spec/moneta/adapters/lruhash/standard_lruhash_spec.rb +4 -0
  147. data/spec/moneta/adapters/lruhash/standard_lruhash_with_expires_spec.rb +8 -0
  148. data/spec/moneta/adapters/memcached/adapter_memcached_spec.rb +13 -0
  149. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_spec.rb +15 -0
  150. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_with_default_expires_spec.rb +15 -0
  151. data/spec/moneta/adapters/memcached/dalli/standard_memcached_dalli_spec.rb +11 -0
  152. data/spec/moneta/adapters/memcached/helper.rb +20 -0
  153. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_spec.rb +15 -0
  154. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_with_default_expires_spec.rb +15 -0
  155. data/spec/moneta/adapters/memcached/native/standard_memcached_native_spec.rb +11 -0
  156. data/spec/moneta/adapters/memcached/standard_memcached_spec.rb +17 -0
  157. data/spec/moneta/adapters/memory/adapter_memory_spec.rb +7 -0
  158. data/spec/moneta/adapters/memory/standard_memory_spec.rb +4 -0
  159. data/spec/moneta/adapters/memory/standard_memory_with_compress_spec.rb +9 -0
  160. data/spec/moneta/adapters/memory/standard_memory_with_expires_spec.rb +8 -0
  161. data/spec/moneta/adapters/memory/standard_memory_with_json_key_serializer_spec.rb +4 -0
  162. data/spec/moneta/adapters/memory/standard_memory_with_json_serializer_spec.rb +9 -0
  163. data/spec/moneta/adapters/memory/standard_memory_with_json_value_serializer_spec.rb +9 -0
  164. data/spec/moneta/adapters/memory/standard_memory_with_prefix_spec.rb +4 -0
  165. data/spec/moneta/adapters/memory/standard_memory_with_snappy_compress_spec.rb +9 -0
  166. data/spec/moneta/adapters/mongo/adapter_mongo_moped_spec.rb +25 -0
  167. data/spec/moneta/adapters/mongo/adapter_mongo_moped_with_default_expires_spec.rb +12 -0
  168. data/spec/moneta/adapters/mongo/adapter_mongo_official_spec.rb +25 -0
  169. data/spec/moneta/adapters/mongo/adapter_mongo_official_with_default_expires_spec.rb +12 -0
  170. data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +11 -0
  171. data/spec/moneta/adapters/mongo/adapter_mongo_with_default_expires_spec.rb +12 -0
  172. data/spec/moneta/adapters/mongo/standard_mongo_moped_spec.rb +7 -0
  173. data/spec/moneta/adapters/mongo/standard_mongo_official_spec.rb +7 -0
  174. data/spec/moneta/adapters/mongo/standard_mongo_spec.rb +7 -0
  175. data/spec/moneta/adapters/null/null_adapter_spec.rb +7 -0
  176. data/spec/moneta/adapters/null/standard_null_spec.rb +4 -0
  177. data/spec/moneta/adapters/pstore/adapter_pstore_spec.rb +7 -0
  178. data/spec/moneta/adapters/pstore/standard_pstore_spec.rb +9 -0
  179. data/spec/moneta/adapters/pstore/standard_pstore_with_expires_spec.rb +13 -0
  180. data/spec/moneta/adapters/redis/adapter_redis_spec.rb +10 -0
  181. data/spec/moneta/adapters/redis/adapter_redis_with_default_expires_spec.rb +10 -0
  182. data/spec/moneta/adapters/redis/standard_redis_spec.rb +7 -0
  183. data/spec/moneta/adapters/restclient/adapter_restclient_spec.rb +11 -0
  184. data/spec/moneta/adapters/restclient/standard_restclient_spec.rb +10 -0
  185. data/spec/moneta/adapters/riak/adapter_riak_spec.rb +14 -0
  186. data/spec/moneta/adapters/riak/standard_riak_spec.rb +10 -0
  187. data/spec/moneta/adapters/riak/standard_riak_with_expires_spec.rb +10 -0
  188. data/spec/moneta/adapters/sdbm/adapter_sdbm_spec.rb +7 -0
  189. data/spec/moneta/adapters/sdbm/standard_sdbm_spec.rb +7 -0
  190. data/spec/moneta/adapters/sdbm/standard_sdbm_with_expires_spec.rb +11 -0
  191. data/spec/moneta/adapters/sequel/adapter_sequel_spec.rb +181 -0
  192. data/spec/moneta/adapters/sequel/standard_sequel_spec.rb +14 -0
  193. data/spec/moneta/adapters/sequel/standard_sequel_with_expires_spec.rb +19 -0
  194. data/spec/moneta/adapters/sqlite/adapter_sqlite_spec.rb +7 -0
  195. data/spec/moneta/adapters/sqlite/standard_sqlite_spec.rb +7 -0
  196. data/spec/moneta/adapters/sqlite/standard_sqlite_with_expires_spec.rb +15 -0
  197. data/spec/moneta/adapters/tdb/adapter_tdb_spec.rb +7 -0
  198. data/spec/moneta/adapters/tdb/standard_tdb_spec.rb +7 -0
  199. data/spec/moneta/adapters/tdb/standard_tdb_with_expires_spec.rb +11 -0
  200. data/spec/moneta/adapters/tokyocabinet/adapter_tokyocabinet_bdb_spec.rb +7 -0
  201. data/spec/moneta/adapters/tokyocabinet/adapter_tokyocabinet_hdb_spec.rb +7 -0
  202. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_spec.rb +7 -0
  203. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_with_expires_spec.rb +11 -0
  204. data/spec/moneta/adapters/tokyotyrant/adapter_tokyotyrant_spec.rb +7 -0
  205. data/spec/moneta/adapters/tokyotyrant/standard_tokyotyrant_spec.rb +4 -0
  206. data/spec/moneta/adapters/tokyotyrant/standard_tokyotyrant_with_expires_spec.rb +8 -0
  207. data/spec/moneta/adapters/yaml/adapter_yaml_spec.rb +7 -0
  208. data/spec/moneta/adapters/yaml/standard_yaml_spec.rb +9 -0
  209. data/spec/moneta/adapters/yaml/standard_yaml_with_expires_spec.rb +13 -0
  210. data/spec/moneta/builder_spec.rb +0 -1
  211. data/spec/moneta/mutex_spec.rb +6 -23
  212. data/spec/moneta/proxies/cache/cache_file_memory_spec.rb +24 -0
  213. data/spec/moneta/proxies/cache/cache_memory_null_spec.rb +12 -0
  214. data/spec/moneta/proxies/expires/expires_file_spec.rb +28 -0
  215. data/spec/moneta/proxies/expires/expires_memory_spec.rb +15 -0
  216. data/spec/moneta/proxies/expires/expires_memory_with_default_expires_spec.rb +16 -0
  217. data/spec/moneta/proxies/lock/lock_spec.rb +10 -0
  218. data/spec/moneta/{optionmerger_spec.rb → proxies/optionmerger/optionmerger_spec.rb} +2 -18
  219. data/spec/moneta/proxies/pool/pool_spec.rb +12 -0
  220. data/spec/moneta/proxies/proxy/proxy_expires_memory_spec.rb +16 -0
  221. data/spec/moneta/proxies/proxy/proxy_redis_spec.rb +13 -0
  222. data/spec/moneta/proxies/shared/shared_tcp_spec.rb +49 -0
  223. data/spec/moneta/proxies/shared/shared_unix_spec.rb +48 -0
  224. data/spec/moneta/proxies/transformer/transformer_bencode_spec.rb +19 -0
  225. data/spec/moneta/proxies/transformer/transformer_bert_spec.rb +19 -0
  226. data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +23 -0
  227. data/spec/moneta/proxies/transformer/transformer_bzip2_spec.rb +19 -0
  228. data/spec/moneta/proxies/transformer/transformer_json_spec.rb +19 -0
  229. data/spec/moneta/proxies/transformer/transformer_key_inspect_spec.rb +17 -0
  230. data/spec/moneta/proxies/transformer/transformer_key_marshal_spec.rb +17 -0
  231. data/spec/moneta/proxies/transformer/transformer_key_to_s_spec.rb +17 -0
  232. data/spec/moneta/proxies/transformer/transformer_key_yaml_spec.rb +17 -0
  233. data/spec/moneta/proxies/transformer/transformer_lz4_spec.rb +19 -0
  234. data/spec/moneta/proxies/transformer/transformer_lzma_spec.rb +19 -0
  235. data/spec/moneta/proxies/transformer/transformer_lzo_spec.rb +19 -0
  236. data/spec/moneta/proxies/transformer/transformer_marshal_base64_spec.rb +20 -0
  237. data/spec/moneta/proxies/transformer/transformer_marshal_city128_spec.rb +15 -0
  238. data/spec/moneta/proxies/transformer/transformer_marshal_city32_spec.rb +15 -0
  239. data/spec/moneta/proxies/transformer/transformer_marshal_city64_spec.rb +15 -0
  240. data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +15 -0
  241. data/spec/moneta/proxies/transformer/transformer_marshal_hex_spec.rb +20 -0
  242. data/spec/moneta/proxies/transformer/transformer_marshal_hmac_spec.rb +19 -0
  243. data/spec/moneta/proxies/transformer/transformer_marshal_md5_spec.rb +15 -0
  244. data/spec/moneta/proxies/transformer/transformer_marshal_md5_spread_spec.rb +15 -0
  245. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_spec.rb +15 -0
  246. data/spec/moneta/proxies/transformer/transformer_marshal_qp_spec.rb +20 -0
  247. data/spec/moneta/proxies/transformer/transformer_marshal_rmd160_spec.rb +15 -0
  248. data/spec/moneta/proxies/transformer/transformer_marshal_sha1_spec.rb +15 -0
  249. data/spec/moneta/proxies/transformer/transformer_marshal_sha256_spec.rb +15 -0
  250. data/spec/moneta/proxies/transformer/transformer_marshal_sha384_spec.rb +15 -0
  251. data/spec/moneta/proxies/transformer/transformer_marshal_sha512_spec.rb +15 -0
  252. data/spec/moneta/proxies/transformer/transformer_marshal_spec.rb +19 -0
  253. data/spec/moneta/proxies/transformer/transformer_marshal_truncate_spec.rb +15 -0
  254. data/spec/moneta/proxies/transformer/transformer_marshal_urlsafe_base64_spec.rb +20 -0
  255. data/spec/moneta/proxies/transformer/transformer_marshal_uuencode_spec.rb +19 -0
  256. data/spec/moneta/proxies/transformer/transformer_msgpack_spec.rb +19 -0
  257. data/spec/moneta/proxies/transformer/transformer_ox_spec.rb +19 -0
  258. data/spec/moneta/proxies/transformer/transformer_php_spec.rb +19 -0
  259. data/spec/moneta/proxies/transformer/transformer_quicklz_spec.rb +19 -0
  260. data/spec/moneta/proxies/transformer/transformer_snappy_spec.rb +19 -0
  261. data/spec/moneta/proxies/transformer/transformer_tnet_spec.rb +19 -0
  262. data/spec/moneta/proxies/transformer/transformer_value_marshal_spec.rb +19 -0
  263. data/spec/moneta/proxies/transformer/transformer_value_yaml_spec.rb +19 -0
  264. data/spec/moneta/proxies/transformer/transformer_yaml_spec.rb +19 -0
  265. data/spec/moneta/proxies/transformer/transformer_zlib_spec.rb +19 -0
  266. data/spec/moneta/proxies/weak_create/weak_create_spec.rb +21 -0
  267. data/spec/moneta/proxies/weak_each_key/weak_each_key_spec.rb +24 -0
  268. data/spec/moneta/proxies/weak_increment/weak_increment_spec.rb +21 -0
  269. data/spec/moneta/semaphore_spec.rb +6 -23
  270. data/spec/moneta/stack_file_memory_spec.rb +5 -29
  271. data/spec/moneta/stack_memory_file_spec.rb +5 -31
  272. data/spec/quality_spec.rb +1 -1
  273. data/{spec → test}/action_dispatch/fixtures/session_autoload_test/foo.rb +0 -0
  274. data/{spec/action_dispatch/session_moneta_store_spec.rb → test/action_dispatch/session_moneta_store_test.rb} +13 -5
  275. metadata +415 -355
  276. data/script/generate-specs +0 -2696
  277. data/spec/moneta/adapter_activerecord_exisiting_connection_spec.rb +0 -36
  278. data/spec/moneta/adapter_activerecord_spec.rb +0 -65
  279. data/spec/moneta/adapter_cassandra_spec.rb +0 -33
  280. data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +0 -34
  281. data/spec/moneta/adapter_client_spec.rb +0 -35
  282. data/spec/moneta/adapter_cookie_spec.rb +0 -30
  283. data/spec/moneta/adapter_couch_spec.rb +0 -36
  284. data/spec/moneta/adapter_datamapper_spec.rb +0 -64
  285. data/spec/moneta/adapter_daybreak_spec.rb +0 -31
  286. data/spec/moneta/adapter_dbm_spec.rb +0 -31
  287. data/spec/moneta/adapter_file_spec.rb +0 -34
  288. data/spec/moneta/adapter_fog_spec.rb +0 -37
  289. data/spec/moneta/adapter_gdbm_spec.rb +0 -31
  290. data/spec/moneta/adapter_hbase_spec.rb +0 -33
  291. data/spec/moneta/adapter_kyotocabinet_spec.rb +0 -31
  292. data/spec/moneta/adapter_leveldb_spec.rb +0 -31
  293. data/spec/moneta/adapter_lmdb_spec.rb +0 -32
  294. data/spec/moneta/adapter_lmdb_with_db_spec.rb +0 -32
  295. data/spec/moneta/adapter_localmemcache_spec.rb +0 -32
  296. data/spec/moneta/adapter_memcached_dalli_spec.rb +0 -36
  297. data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +0 -37
  298. data/spec/moneta/adapter_memcached_native_spec.rb +0 -36
  299. data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +0 -37
  300. data/spec/moneta/adapter_memcached_spec.rb +0 -36
  301. data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +0 -37
  302. data/spec/moneta/adapter_memory_spec.rb +0 -184
  303. data/spec/moneta/adapter_mongo_moped_spec.rb +0 -64
  304. data/spec/moneta/adapter_mongo_moped_with_default_expires_spec.rb +0 -53
  305. data/spec/moneta/adapter_mongo_official_spec.rb +0 -64
  306. data/spec/moneta/adapter_mongo_official_with_default_expires_spec.rb +0 -53
  307. data/spec/moneta/adapter_mongo_spec.rb +0 -51
  308. data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +0 -53
  309. data/spec/moneta/adapter_pstore_spec.rb +0 -250
  310. data/spec/moneta/adapter_redis_spec.rb +0 -36
  311. data/spec/moneta/adapter_redis_with_default_expires_spec.rb +0 -37
  312. data/spec/moneta/adapter_restclient_spec.rb +0 -33
  313. data/spec/moneta/adapter_riak_spec.rb +0 -36
  314. data/spec/moneta/adapter_sdbm_spec.rb +0 -30
  315. data/spec/moneta/adapter_sequel_spec.rb +0 -34
  316. data/spec/moneta/adapter_sqlite_spec.rb +0 -32
  317. data/spec/moneta/adapter_tdb_spec.rb +0 -31
  318. data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +0 -31
  319. data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +0 -31
  320. data/spec/moneta/adapter_tokyotyrant_spec.rb +0 -34
  321. data/spec/moneta/adapter_yaml_spec.rb +0 -57
  322. data/spec/moneta/cache_file_memory_spec.rb +0 -50
  323. data/spec/moneta/cache_memory_null_spec.rb +0 -35
  324. data/spec/moneta/expires_file_spec.rb +0 -78
  325. data/spec/moneta/expires_memory_spec.rb +0 -189
  326. data/spec/moneta/expires_memory_with_default_expires_spec.rb +0 -190
  327. data/spec/moneta/lock_spec.rb +0 -187
  328. data/spec/moneta/null_adapter_spec.rb +0 -86
  329. data/spec/moneta/pool_spec.rb +0 -38
  330. data/spec/moneta/proxy_expires_memory_spec.rb +0 -191
  331. data/spec/moneta/proxy_redis_spec.rb +0 -40
  332. data/spec/moneta/shared_tcp_spec.rb +0 -46
  333. data/spec/moneta/shared_unix_spec.rb +0 -46
  334. data/spec/moneta/standard_activerecord_spec.rb +0 -253
  335. data/spec/moneta/standard_activerecord_with_expires_spec.rb +0 -255
  336. data/spec/moneta/standard_cassandra_spec.rb +0 -252
  337. data/spec/moneta/standard_client_tcp_spec.rb +0 -269
  338. data/spec/moneta/standard_client_unix_spec.rb +0 -254
  339. data/spec/moneta/standard_couch_spec.rb +0 -252
  340. data/spec/moneta/standard_couch_with_expires_spec.rb +0 -254
  341. data/spec/moneta/standard_datamapper_spec.rb +0 -254
  342. data/spec/moneta/standard_datamapper_with_expires_spec.rb +0 -256
  343. data/spec/moneta/standard_datamapper_with_repository_spec.rb +0 -254
  344. data/spec/moneta/standard_daybreak_spec.rb +0 -250
  345. data/spec/moneta/standard_daybreak_with_expires_spec.rb +0 -252
  346. data/spec/moneta/standard_dbm_spec.rb +0 -250
  347. data/spec/moneta/standard_dbm_with_expires_spec.rb +0 -252
  348. data/spec/moneta/standard_file_spec.rb +0 -253
  349. data/spec/moneta/standard_file_with_expires_spec.rb +0 -255
  350. data/spec/moneta/standard_fog_spec.rb +0 -256
  351. data/spec/moneta/standard_fog_with_expires_spec.rb +0 -258
  352. data/spec/moneta/standard_gdbm_spec.rb +0 -250
  353. data/spec/moneta/standard_gdbm_with_expires_spec.rb +0 -252
  354. data/spec/moneta/standard_hashfile_spec.rb +0 -253
  355. data/spec/moneta/standard_hashfile_with_expires_spec.rb +0 -255
  356. data/spec/moneta/standard_hbase_spec.rb +0 -252
  357. data/spec/moneta/standard_hbase_with_expires_spec.rb +0 -255
  358. data/spec/moneta/standard_kyotocabinet_spec.rb +0 -250
  359. data/spec/moneta/standard_kyotocabinet_with_expires_spec.rb +0 -252
  360. data/spec/moneta/standard_leveldb_spec.rb +0 -250
  361. data/spec/moneta/standard_leveldb_with_expires_spec.rb +0 -252
  362. data/spec/moneta/standard_lmdb_spec.rb +0 -251
  363. data/spec/moneta/standard_lmdb_with_expires_spec.rb +0 -253
  364. data/spec/moneta/standard_localmemcache_spec.rb +0 -251
  365. data/spec/moneta/standard_localmemcache_with_expires_spec.rb +0 -252
  366. data/spec/moneta/standard_lruhash_spec.rb +0 -187
  367. data/spec/moneta/standard_lruhash_with_expires_spec.rb +0 -189
  368. data/spec/moneta/standard_memcached_dalli_spec.rb +0 -255
  369. data/spec/moneta/standard_memcached_native_spec.rb +0 -255
  370. data/spec/moneta/standard_memcached_spec.rb +0 -255
  371. data/spec/moneta/standard_memory_spec.rb +0 -187
  372. data/spec/moneta/standard_memory_with_compress_spec.rb +0 -187
  373. data/spec/moneta/standard_memory_with_expires_spec.rb +0 -189
  374. data/spec/moneta/standard_memory_with_json_key_serializer_spec.rb +0 -86
  375. data/spec/moneta/standard_memory_with_json_serializer_spec.rb +0 -49
  376. data/spec/moneta/standard_memory_with_json_value_serializer_spec.rb +0 -90
  377. data/spec/moneta/standard_memory_with_prefix_spec.rb +0 -187
  378. data/spec/moneta/standard_memory_with_snappy_compress_spec.rb +0 -187
  379. data/spec/moneta/standard_mongo_moped_spec.rb +0 -255
  380. data/spec/moneta/standard_mongo_official_spec.rb +0 -255
  381. data/spec/moneta/standard_mongo_spec.rb +0 -255
  382. data/spec/moneta/standard_null_spec.rb +0 -120
  383. data/spec/moneta/standard_pstore_spec.rb +0 -253
  384. data/spec/moneta/standard_pstore_with_expires_spec.rb +0 -255
  385. data/spec/moneta/standard_redis_spec.rb +0 -255
  386. data/spec/moneta/standard_restclient_spec.rb +0 -252
  387. data/spec/moneta/standard_riak_spec.rb +0 -255
  388. data/spec/moneta/standard_riak_with_expires_spec.rb +0 -256
  389. data/spec/moneta/standard_sdbm_spec.rb +0 -249
  390. data/spec/moneta/standard_sdbm_with_expires_spec.rb +0 -251
  391. data/spec/moneta/standard_sequel_spec.rb +0 -253
  392. data/spec/moneta/standard_sequel_with_expires_spec.rb +0 -255
  393. data/spec/moneta/standard_sqlite_spec.rb +0 -251
  394. data/spec/moneta/standard_sqlite_with_expires_spec.rb +0 -253
  395. data/spec/moneta/standard_tdb_spec.rb +0 -250
  396. data/spec/moneta/standard_tdb_with_expires_spec.rb +0 -252
  397. data/spec/moneta/standard_tokyocabinet_spec.rb +0 -250
  398. data/spec/moneta/standard_tokyocabinet_with_expires_spec.rb +0 -252
  399. data/spec/moneta/standard_tokyotyrant_spec.rb +0 -253
  400. data/spec/moneta/standard_tokyotyrant_with_expires_spec.rb +0 -255
  401. data/spec/moneta/standard_yaml_spec.rb +0 -250
  402. data/spec/moneta/standard_yaml_with_expires_spec.rb +0 -252
  403. data/spec/moneta/transformer_bencode_spec.rb +0 -55
  404. data/spec/moneta/transformer_bert_spec.rb +0 -55
  405. data/spec/moneta/transformer_bson_spec.rb +0 -60
  406. data/spec/moneta/transformer_bzip2_spec.rb +0 -55
  407. data/spec/moneta/transformer_json_spec.rb +0 -55
  408. data/spec/moneta/transformer_key_inspect_spec.rb +0 -91
  409. data/spec/moneta/transformer_key_marshal_spec.rb +0 -191
  410. data/spec/moneta/transformer_key_to_s_spec.rb +0 -91
  411. data/spec/moneta/transformer_key_yaml_spec.rb +0 -191
  412. data/spec/moneta/transformer_lz4_spec.rb +0 -55
  413. data/spec/moneta/transformer_lzma_spec.rb +0 -55
  414. data/spec/moneta/transformer_lzo_spec.rb +0 -55
  415. data/spec/moneta/transformer_marshal_base64_spec.rb +0 -194
  416. data/spec/moneta/transformer_marshal_city128_spec.rb +0 -194
  417. data/spec/moneta/transformer_marshal_city32_spec.rb +0 -194
  418. data/spec/moneta/transformer_marshal_city64_spec.rb +0 -194
  419. data/spec/moneta/transformer_marshal_escape_spec.rb +0 -194
  420. data/spec/moneta/transformer_marshal_hex_spec.rb +0 -194
  421. data/spec/moneta/transformer_marshal_hmac_spec.rb +0 -194
  422. data/spec/moneta/transformer_marshal_md5_spec.rb +0 -194
  423. data/spec/moneta/transformer_marshal_md5_spread_spec.rb +0 -194
  424. data/spec/moneta/transformer_marshal_prefix_spec.rb +0 -194
  425. data/spec/moneta/transformer_marshal_qp_spec.rb +0 -194
  426. data/spec/moneta/transformer_marshal_rmd160_spec.rb +0 -194
  427. data/spec/moneta/transformer_marshal_sha1_spec.rb +0 -194
  428. data/spec/moneta/transformer_marshal_sha256_spec.rb +0 -194
  429. data/spec/moneta/transformer_marshal_sha384_spec.rb +0 -194
  430. data/spec/moneta/transformer_marshal_sha512_spec.rb +0 -194
  431. data/spec/moneta/transformer_marshal_spec.rb +0 -191
  432. data/spec/moneta/transformer_marshal_truncate_spec.rb +0 -194
  433. data/spec/moneta/transformer_marshal_uuencode_spec.rb +0 -194
  434. data/spec/moneta/transformer_msgpack_spec.rb +0 -55
  435. data/spec/moneta/transformer_ox_spec.rb +0 -191
  436. data/spec/moneta/transformer_php_spec.rb +0 -55
  437. data/spec/moneta/transformer_quicklz_spec.rb +0 -55
  438. data/spec/moneta/transformer_snappy_spec.rb +0 -55
  439. data/spec/moneta/transformer_tnet_spec.rb +0 -55
  440. data/spec/moneta/transformer_value_marshal_spec.rb +0 -191
  441. data/spec/moneta/transformer_value_yaml_spec.rb +0 -191
  442. data/spec/moneta/transformer_yaml_spec.rb +0 -191
  443. data/spec/moneta/transformer_zlib_spec.rb +0 -55
  444. data/spec/moneta/weak_create_spec.rb +0 -41
  445. data/spec/moneta/weak_increment_spec.rb +0 -41
  446. data/spec/monetaspecs.rb +0 -51267
@@ -3,6 +3,7 @@ module Moneta
3
3
  autoload :Cache, 'moneta/cache'
4
4
  autoload :CreateSupport, 'moneta/mixins'
5
5
  autoload :Defaults, 'moneta/mixins'
6
+ autoload :EachKeySupport, 'moneta/mixins'
6
7
  autoload :ExpiresSupport, 'moneta/mixins'
7
8
  autoload :Expires, 'moneta/expires'
8
9
  autoload :HashAdapter, 'moneta/mixins'
@@ -21,11 +22,13 @@ module Moneta
21
22
  autoload :Transformer, 'moneta/transformer'
22
23
  autoload :Utils, 'moneta/utils'
23
24
  autoload :WeakCreate, 'moneta/weak'
25
+ autoload :WeakEachKey, 'moneta/weak_each_key'
24
26
  autoload :WeakIncrement, 'moneta/weak'
25
27
  autoload :Wrapper, 'moneta/wrapper'
26
28
 
27
29
  module Adapters
28
30
  autoload :ActiveRecord, 'moneta/adapters/activerecord'
31
+ autoload :ActiveSupportCache,'moneta/adapters/activesupportcache'
29
32
  autoload :Cassandra, 'moneta/adapters/cassandra'
30
33
  autoload :Client, 'moneta/adapters/client'
31
34
  autoload :Cookie, 'moneta/adapters/cookie'
@@ -93,7 +96,7 @@ module Moneta
93
96
  # @api public
94
97
  def self.new(name, options = {})
95
98
  expires = options[:expires]
96
- options.delete(:expires) unless Integer === expires
99
+ options.delete(:expires) unless Numeric === expires
97
100
  logger = options.delete(:logger)
98
101
  threadsafe = options.delete(:threadsafe)
99
102
  compress = options.delete(:compress)
@@ -107,10 +110,14 @@ module Moneta
107
110
  when :Sequel
108
111
  # Sequel accept only base64 keys
109
112
  transformer[:key] << :base64
110
- when :ActiveRecord, :DataMapper, :Couch
113
+ when :ActiveRecord, :DataMapper
111
114
  # DataMapper and AR accept only base64 keys and values
112
115
  transformer[:key] << :base64
113
116
  transformer[:value] << :base64
117
+ when :Couch
118
+ # CouchDB needs to use URL-safe Base64 for its keys
119
+ transformer[:key] << :urlsafe_base64
120
+ transformer[:value] << :base64
114
121
  when :PStore, :YAML, :Null
115
122
  # For PStore and YAML only the key has to be a string
116
123
  transformer.delete(:value) if transformer[:value] == [:marshal]
@@ -1,5 +1,5 @@
1
1
  require 'active_record'
2
- require 'thread'
2
+ require 'uri'
3
3
 
4
4
  module Moneta
5
5
  module Adapters
@@ -8,167 +8,327 @@ module Moneta
8
8
  class ActiveRecord
9
9
  include Defaults
10
10
 
11
- supports :create, :increment
12
- attr_reader :table
11
+ supports :create, :increment, :each_key
13
12
 
14
- @table_mutex = ::Mutex.new
15
- @table_refcount = {}
13
+ attr_reader :table, :key_column, :value_column
14
+ delegate :with_connection, to: :connection_pool
16
15
 
16
+ @connection_lock = ::Mutex.new
17
17
  class << self
18
- def release(table)
19
- @table_mutex.synchronize do
20
- if (@table_refcount[table] -= 1) <= 0
21
- remove_const(table.name.sub(/^.*::/, ''))
22
- @table_refcount.delete(table)
18
+ attr_reader :connection_lock
19
+ delegate :configurations, :configurations=, :connection_handler, to: ::ActiveRecord::Base
20
+
21
+ def retrieve_connection_pool(spec_name)
22
+ connection_handler.retrieve_connection_pool(spec_name.to_s)
23
+ end
24
+
25
+ def establish_connection(spec_name)
26
+ connection_lock.synchronize do
27
+ if connection_pool = retrieve_connection_pool(spec_name)
28
+ connection_pool
29
+ else
30
+ connection_handler.establish_connection(spec_name.to_sym)
23
31
  end
24
32
  end
25
33
  end
26
34
 
27
- def get(options)
28
- name = 'Table_' << options.inspect.gsub(/[^\w]+/) do
29
- $&.unpack('H2' * $&.bytesize).join.upcase
30
- end
31
- @table_mutex.synchronize do
32
- table =
33
- if const_defined?(name)
34
- const_get(name)
35
- else
36
- create(name, options)
37
- end
38
- @table_refcount[table] ||= 0
39
- @table_refcount[table] += 1
40
- table
41
- end
35
+ def retrieve_or_establish_connection_pool(spec_name)
36
+ retrieve_connection_pool(spec_name) || establish_connection(spec_name)
42
37
  end
38
+ end
43
39
 
44
- private
40
+ # @param [Hash] options
41
+ # @option options [Object] :backend A class object inheriting from ActiveRecord::Base to use as a table
42
+ # @option options [String] :table ('moneta') Table name
43
+ # @option options [Hash/String/Symbol] :connection ActiveRecord connection configuration (`Hash` or `String`), or symbol giving the name of a Rails connection (e.g. :production)
44
+ # @option options [Proc, Boolean] :create_table Proc called with a connection if table
45
+ # needs to be created. Pass false to skip the create table check all together.
46
+ # @option options [Symbol] :key_column (:k) The name of the column to use for keys
47
+ # @option options [Symbol] :value_column (:v) The name of the column to use for values
48
+ def initialize(options = {})
49
+ @key_column = options.delete(:key_column) || :k
50
+ @value_column = options.delete(:value_column) || :v
45
51
 
46
- def create(name, options)
47
- table = Class.new(::ActiveRecord::Base)
48
- const_set(name, table)
49
- table.table_name = options[:table] || 'moneta'
50
- table.primary_key = :k
52
+ if backend = options.delete(:backend)
53
+ @spec = backend.connection_pool.spec
54
+ @table = ::Arel::Table.new(backend.table_name.to_sym)
55
+ else
56
+ # Feed the connection info into ActiveRecord and get back a name to use for getting the
57
+ # connection pool
58
+ connection = options.delete(:connection)
59
+ @spec =
60
+ case connection
61
+ when Symbol
62
+ connection
63
+ when Hash, String
64
+ # Normalize the connection specification to a hash
65
+ resolver = ::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new \
66
+ 'dummy' => connection
51
67
 
52
- if options[:connection]
53
- begin
54
- table.establish_connection(options[:connection])
55
- rescue
56
- tries ||= 0
57
- (tries += 1) < 3 ? retry : raise
58
- end
59
- end
60
-
61
- table.connection_pool.with_connection do |conn|
62
- unless table.table_exists?
63
- conn.create_table(table.table_name, id: false) do |t|
64
- # Do not use binary key (Issue #17)
65
- t.string :k, null: false
66
- t.binary :v
68
+ # Turn the config into a standardised hash, sans a couple of bits
69
+ hash = resolver.resolve(:dummy)
70
+ hash.delete('name')
71
+ hash.delete(:password) # For security
72
+ # Make a name unique to this config
73
+ name = 'moneta?' + URI.encode_www_form(hash.to_a.sort)
74
+ # Add into configurations unless its already there (initially done without locking for
75
+ # speed)
76
+ unless self.class.configurations.key? name
77
+ self.class.connection_lock.synchronize do
78
+ self.class.configurations[name] = connection \
79
+ unless self.class.configurations.key? name
80
+ end
67
81
  end
68
- conn.add_index(table.table_name, :k, unique: true)
82
+
83
+ name.to_sym
84
+ else
85
+ ::ActiveRecord::Base.connection_pool.spec.name.to_s
69
86
  end
87
+
88
+ table_name = (options.delete(:table) || :moneta).to_sym
89
+ create_table_proc = options.delete(:create_table)
90
+ if create_table_proc.nil?
91
+ create_table(table_name)
92
+ elsif create_table_proc
93
+ with_connection(&create_table_proc)
70
94
  end
71
95
 
72
- table
73
- rescue
74
- remove_const(name)
75
- raise
96
+ @table = ::Arel::Table.new(table_name)
76
97
  end
77
98
  end
78
99
 
79
- # @param [Hash] options
80
- # @option options [String] :table ('moneta') Table name
81
- # @option options [Hash] :connection ActiveRecord connection configuration
82
- def initialize(options = {})
83
- @table = self.class.get(options)
84
- end
85
-
86
100
  # (see Proxy#key?)
87
101
  def key?(key, options = {})
88
- @table.connection_pool.with_connection do
89
- !@table.where(k: key).empty?
102
+ with_connection do |conn|
103
+ sel = arel_sel_key(key).project(::Arel.sql('1'))
104
+ result = conn.select_all(sel)
105
+ !result.empty?
106
+ end
107
+ end
108
+
109
+ # (see Proxy#each_key)
110
+ def each_key(&block)
111
+ with_connection do |conn|
112
+ return enum_for(:each_key) { conn.select_value(arel_sel.project(table[key_column].count)) } unless block_given?
113
+ conn.select_values(arel_sel.project(table[key_column])).each { |k| yield(k) }
90
114
  end
115
+ self
91
116
  end
92
117
 
93
118
  # (see Proxy#load)
94
119
  def load(key, options = {})
95
- @table.connection_pool.with_connection do
96
- record = @table.select(:v).where(k: key).first
97
- record && record.v
120
+ with_connection do |conn|
121
+ conn_sel_value(conn, key)
98
122
  end
99
123
  end
100
124
 
101
125
  # (see Proxy#store)
102
126
  def store(key, value, options = {})
103
- @table.connection_pool.with_connection do
104
- record = @table.select(:k).where(k: key).first_or_initialize
105
- record.v = value
106
- record.save
107
- value
127
+ with_connection do |conn|
128
+ encoded = encode(conn, value)
129
+ conn_ins(conn, key, encoded) unless conn_upd(conn, key, encoded) == 1
108
130
  end
109
- rescue
110
- tries ||= 0
111
- (tries += 1) < 10 ? retry : raise
131
+ value
112
132
  end
113
133
 
114
134
  # (see Proxy#delete)
115
135
  def delete(key, options = {})
116
- @table.connection_pool.with_connection do
117
- if record = @table.where(k: key).first
118
- record.destroy
119
- record.v
136
+ with_connection do |conn|
137
+ conn.transaction do
138
+ sel = arel_sel_key(key).project(table[value_column]).lock
139
+ value = decode(conn, conn.select_value(sel))
140
+
141
+ del = arel_del.where(table[key_column].eq(key))
142
+ conn.delete(del)
143
+
144
+ value
120
145
  end
121
146
  end
122
147
  end
123
148
 
124
149
  # (see Proxy#increment)
125
150
  def increment(key, amount = 1, options = {})
126
- @table.connection_pool.with_connection do
127
- @table.transaction do
128
- if record = @table.where(k: key).lock.first
129
- value = Utils.to_int(record.v) + amount
130
- record.v = value.to_s
131
- record.save
151
+ with_connection do |conn|
152
+ begin
153
+ conn_ins(conn, key, amount.to_s)
154
+ amount
155
+ rescue ::ActiveRecord::RecordNotUnique
156
+ conn.transaction do
157
+ sel = arel_sel_key(key).project(table[value_column]).lock
158
+ value = decode(conn, conn.select_value(sel))
159
+ value = (value ? Integer(value) : 0) + amount
160
+ # Re-raise if the upate affects no rows (i.e. row deleted after attempted insert,
161
+ # before select for update)
162
+ raise unless conn_upd(conn, key, value.to_s) == 1
132
163
  value
133
- elsif create(key, amount.to_s, options)
134
- amount
135
- else
136
- raise 'Concurrent modification'
137
164
  end
138
165
  end
139
166
  end
140
- rescue
167
+ rescue ::ActiveRecord::RecordNotUnique
168
+ # This handles the "no row updated" issue, above
141
169
  tries ||= 0
142
- (tries += 1) < 10 ? retry : raise
170
+ if (tries += 1) <= 3; retry else raise end
143
171
  end
144
172
 
145
173
  # (see Proxy#create)
146
174
  def create(key, value, options = {})
147
- @table.connection_pool.with_connection do
148
- record = @table.new
149
- record.k = key
150
- record.v = value
151
- record.save
175
+ with_connection do |conn|
176
+ conn_ins(conn, key, value)
152
177
  true
153
178
  end
154
- rescue
155
- # FIXME: This catches too many errors
156
- # it should only catch a not-unique-exception
179
+ rescue ::ActiveRecord::RecordNotUnique
157
180
  false
158
181
  end
159
182
 
160
183
  # (see Proxy#clear)
161
184
  def clear(options = {})
162
- @table.connection_pool.with_connection do
163
- @table.delete_all
185
+ with_connection do |conn|
186
+ conn.delete(arel_del)
164
187
  end
165
188
  self
166
189
  end
167
190
 
168
191
  # (see Proxy#close)
169
192
  def close
170
- self.class.release(@table)
171
193
  @table = nil
194
+ @spec = nil
195
+ end
196
+
197
+ # (see Proxy#slice)
198
+ def slice(*keys, lock: false, **options)
199
+ with_connection do |conn|
200
+ sel = arel_slice(keys).project(table[key_column], table[value_column])
201
+ sel = sel.lock if lock
202
+ result = conn.select_all(sel)
203
+
204
+ k = key_column.to_s
205
+ v = value_column.to_s
206
+ result.map do |row|
207
+ [row[k], decode(conn, row[v])]
208
+ end
209
+ end
210
+ end
211
+
212
+ # (see Proxy#values_at)
213
+ def values_at(*keys, **options)
214
+ hash = Hash[slice(*keys, **options)]
215
+ keys.map { |key| hash[key] }
216
+ end
217
+
218
+ # (see Proxy#fetch_values)
219
+ def fetch_values(*keys, **options)
220
+ return values_at(*keys, **options) unless block_given?
221
+ hash = Hash[slice(*keys, **options)]
222
+ keys.map do |key|
223
+ if hash.key?(key)
224
+ hash[key]
225
+ else
226
+ yield key
227
+ end
228
+ end
229
+ end
230
+
231
+ # (see Proxy#merge!)
232
+ def merge!(pairs, options = {})
233
+ with_connection do |conn|
234
+ conn.transaction do
235
+ existing = Hash[slice(*pairs.map { |k, _| k }, lock: true, **options)]
236
+ update_pairs, insert_pairs = pairs.partition { |k, _| existing.key?(k) }
237
+ insert_pairs.each { |key, value| conn_ins(conn, key, encode(conn, value)) }
238
+
239
+ if block_given?
240
+ update_pairs.map! do |key, new_value|
241
+ [key, yield(key, existing[key], new_value)]
242
+ end
243
+ end
244
+
245
+ update_pairs.each { |key, value| conn_upd(conn, key, encode(conn, value)) }
246
+ end
247
+ end
248
+
249
+ self
250
+ end
251
+
252
+ private
253
+
254
+ def connection_pool
255
+ self.class.retrieve_or_establish_connection_pool(@spec)
256
+ end
257
+
258
+ def create_table table_name
259
+ with_connection do |conn|
260
+ return if conn.table_exists?(table_name)
261
+
262
+ # Prevent multiple connections from attempting to create the table simultaneously.
263
+ self.class.connection_lock.synchronize do
264
+ conn.create_table(table_name, id: false) do |t|
265
+ # Do not use binary key (Issue #17)
266
+ t.string key_column, null: false
267
+ t.binary value_column
268
+ end
269
+ conn.add_index(table_name, key_column, unique: true)
270
+ end
271
+ end
272
+ end
273
+
274
+ def arel_del
275
+ ::Arel::DeleteManager.new.from(table)
276
+ end
277
+
278
+ def arel_sel
279
+ ::Arel::SelectManager.new.from(table)
280
+ end
281
+
282
+ def arel_upd
283
+ ::Arel::UpdateManager.new.table(table)
284
+ end
285
+
286
+ def arel_sel_key(key)
287
+ arel_sel.where(table[key_column].eq(key))
288
+ end
289
+
290
+ def arel_slice(keys)
291
+ arel_sel.where(table[key_column].eq_any(keys))
292
+ end
293
+
294
+ def conn_ins(conn, key, value)
295
+ ins = ::Arel::InsertManager.new.into(table)
296
+ ins.insert([[table[key_column], key], [table[value_column], value]])
297
+ conn.insert ins
298
+ end
299
+
300
+ def conn_upd(conn, key, value)
301
+ conn.update arel_upd.where(table[key_column].eq(key)).set([[table[value_column], value]])
302
+ end
303
+
304
+ def conn_sel_value(conn, key)
305
+ decode(conn, conn.select_value(arel_sel_key(key).project(table[value_column])))
306
+ end
307
+
308
+ def encode(conn, value)
309
+ if value == nil
310
+ nil
311
+ elsif conn.respond_to?(:escape_bytea)
312
+ conn.escape_bytea(value)
313
+ elsif defined?(::ActiveRecord::ConnectionAdapters::SQLite3Adapter) &&
314
+ conn.is_a?(::ActiveRecord::ConnectionAdapters::SQLite3Adapter)
315
+ Arel::Nodes::SqlLiteral.new("X'#{value.unpack('H*').first}'")
316
+ else
317
+ value
318
+ end
319
+ end
320
+
321
+ def decode(conn, value)
322
+ if value == nil
323
+ nil
324
+ elsif defined?(::ActiveModel::Type::Binary::Data) &&
325
+ value.is_a?(::ActiveModel::Type::Binary::Data)
326
+ value.to_s
327
+ elsif conn.respond_to?(:unescape_bytea)
328
+ conn.unescape_bytea(value)
329
+ else
330
+ value
331
+ end
172
332
  end
173
333
  end
174
334
  end