redis2-namespaced 3.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.order +170 -0
  4. data/.travis/Gemfile +11 -0
  5. data/.travis.yml +55 -0
  6. data/.yardopts +3 -0
  7. data/CHANGELOG.md +285 -0
  8. data/LICENSE +20 -0
  9. data/README.md +251 -0
  10. data/Rakefile +403 -0
  11. data/benchmarking/logging.rb +71 -0
  12. data/benchmarking/pipeline.rb +51 -0
  13. data/benchmarking/speed.rb +21 -0
  14. data/benchmarking/suite.rb +24 -0
  15. data/benchmarking/worker.rb +71 -0
  16. data/examples/basic.rb +15 -0
  17. data/examples/dist_redis.rb +43 -0
  18. data/examples/incr-decr.rb +17 -0
  19. data/examples/list.rb +26 -0
  20. data/examples/pubsub.rb +37 -0
  21. data/examples/sets.rb +36 -0
  22. data/examples/unicorn/config.ru +3 -0
  23. data/examples/unicorn/unicorn.rb +20 -0
  24. data/lib/redis2/client.rb +419 -0
  25. data/lib/redis2/connection/command_helper.rb +44 -0
  26. data/lib/redis2/connection/hiredis.rb +63 -0
  27. data/lib/redis2/connection/registry.rb +12 -0
  28. data/lib/redis2/connection/ruby.rb +322 -0
  29. data/lib/redis2/connection/synchrony.rb +124 -0
  30. data/lib/redis2/connection.rb +9 -0
  31. data/lib/redis2/distributed.rb +853 -0
  32. data/lib/redis2/errors.rb +40 -0
  33. data/lib/redis2/hash_ring.rb +131 -0
  34. data/lib/redis2/pipeline.rb +141 -0
  35. data/lib/redis2/subscribe.rb +83 -0
  36. data/lib/redis2/version.rb +3 -0
  37. data/lib/redis2.rb +2533 -0
  38. data/redis.gemspec +43 -0
  39. data/test/bitpos_test.rb +69 -0
  40. data/test/blocking_commands_test.rb +42 -0
  41. data/test/command_map_test.rb +30 -0
  42. data/test/commands_on_hashes_test.rb +21 -0
  43. data/test/commands_on_lists_test.rb +20 -0
  44. data/test/commands_on_sets_test.rb +77 -0
  45. data/test/commands_on_sorted_sets_test.rb +109 -0
  46. data/test/commands_on_strings_test.rb +101 -0
  47. data/test/commands_on_value_types_test.rb +131 -0
  48. data/test/connection_handling_test.rb +189 -0
  49. data/test/db/.gitkeep +0 -0
  50. data/test/distributed_blocking_commands_test.rb +46 -0
  51. data/test/distributed_commands_on_hashes_test.rb +10 -0
  52. data/test/distributed_commands_on_lists_test.rb +22 -0
  53. data/test/distributed_commands_on_sets_test.rb +83 -0
  54. data/test/distributed_commands_on_sorted_sets_test.rb +18 -0
  55. data/test/distributed_commands_on_strings_test.rb +59 -0
  56. data/test/distributed_commands_on_value_types_test.rb +95 -0
  57. data/test/distributed_commands_requiring_clustering_test.rb +164 -0
  58. data/test/distributed_connection_handling_test.rb +23 -0
  59. data/test/distributed_internals_test.rb +70 -0
  60. data/test/distributed_key_tags_test.rb +52 -0
  61. data/test/distributed_persistence_control_commands_test.rb +26 -0
  62. data/test/distributed_publish_subscribe_test.rb +92 -0
  63. data/test/distributed_remote_server_control_commands_test.rb +66 -0
  64. data/test/distributed_scripting_test.rb +102 -0
  65. data/test/distributed_sorting_test.rb +20 -0
  66. data/test/distributed_test.rb +58 -0
  67. data/test/distributed_transactions_test.rb +32 -0
  68. data/test/encoding_test.rb +18 -0
  69. data/test/error_replies_test.rb +59 -0
  70. data/test/helper.rb +218 -0
  71. data/test/helper_test.rb +24 -0
  72. data/test/internals_test.rb +410 -0
  73. data/test/lint/blocking_commands.rb +150 -0
  74. data/test/lint/hashes.rb +162 -0
  75. data/test/lint/lists.rb +143 -0
  76. data/test/lint/sets.rb +125 -0
  77. data/test/lint/sorted_sets.rb +238 -0
  78. data/test/lint/strings.rb +260 -0
  79. data/test/lint/value_types.rb +122 -0
  80. data/test/persistence_control_commands_test.rb +26 -0
  81. data/test/pipelining_commands_test.rb +242 -0
  82. data/test/publish_subscribe_test.rb +210 -0
  83. data/test/remote_server_control_commands_test.rb +117 -0
  84. data/test/scanning_test.rb +413 -0
  85. data/test/scripting_test.rb +78 -0
  86. data/test/sorting_test.rb +59 -0
  87. data/test/support/connection/hiredis.rb +1 -0
  88. data/test/support/connection/ruby.rb +1 -0
  89. data/test/support/connection/synchrony.rb +17 -0
  90. data/test/support/redis_mock.rb +115 -0
  91. data/test/support/wire/synchrony.rb +24 -0
  92. data/test/support/wire/thread.rb +5 -0
  93. data/test/synchrony_driver.rb +88 -0
  94. data/test/test.conf +9 -0
  95. data/test/thread_safety_test.rb +32 -0
  96. data/test/transactions_test.rb +264 -0
  97. data/test/unknown_commands_test.rb +14 -0
  98. data/test/url_param_test.rb +132 -0
  99. metadata +226 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4eff6fe736e1f2b3a9dc533057a0fb8257edd8f7
4
+ data.tar.gz: aebea43d3d26f76d76802cf5bd63c2f832fd587e
5
+ SHA512:
6
+ metadata.gz: 2dbafbff793f7d741a71537032ffaba33023cfabc5436259a6323011cbbbefaa504c162adcc56ef7f4badd14424419c907166647ed04b97807682b621764ac8d
7
+ data.tar.gz: bd56875c1f25d2808958911de73f3c64cce1328efa966e9a3ce6e92d8e2cbc9fadaec9514dad3674834e5496991f2ff40d10d3f06e95b70f7432b62085164b55
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *.rdb
2
+ *.swp
3
+ /.idea
4
+ /.yardoc
5
+ /coverage/*
6
+ /doc/
7
+ /nohup.out
8
+ /pkg/*
9
+ /rdsrv
10
+ /redis/*
11
+ /test/db
data/.order ADDED
@@ -0,0 +1,170 @@
1
+ {
2
+ "connection": [
3
+ "auth",
4
+ "select",
5
+ "ping",
6
+ "echo",
7
+ "quit"
8
+ ],
9
+ "server": [
10
+ "bgrewriteaof",
11
+ "bgsave",
12
+ "config",
13
+ "dbsize",
14
+ "debug",
15
+ "flushall",
16
+ "flushdb",
17
+ "info",
18
+ "lastsave",
19
+ "monitor",
20
+ "save",
21
+ "shutdown",
22
+ "slaveof",
23
+ "slowlog",
24
+ "sync",
25
+ "time",
26
+ "client"
27
+ ],
28
+ "generic": [
29
+ "persist",
30
+ "expire",
31
+ "expireat",
32
+ "ttl",
33
+ "pexpire",
34
+ "pexpireat",
35
+ "pttl",
36
+ "dump",
37
+ "restore",
38
+ "del",
39
+ "exists",
40
+ "keys",
41
+ "migrate",
42
+ "move",
43
+ "object",
44
+ "randomkey",
45
+ "rename",
46
+ "renamenx",
47
+ "sort",
48
+ "type"
49
+ ],
50
+ "string": [
51
+ "decr",
52
+ "decrby",
53
+ "incr",
54
+ "incrby",
55
+ "incrbyfloat",
56
+ "set",
57
+ "setex",
58
+ "psetex",
59
+ "setnx",
60
+ "mset",
61
+ "mapped_mset",
62
+ "msetnx",
63
+ "mapped_msetnx",
64
+ "get",
65
+ "mget",
66
+ "mapped_mget",
67
+ "setrange",
68
+ "getrange",
69
+ "setbit",
70
+ "getbit",
71
+ "append",
72
+ "bitcount",
73
+ "getset",
74
+ "strlen",
75
+ "bitop"
76
+ ],
77
+ "list": [
78
+ "llen",
79
+ "lpush",
80
+ "lpushx",
81
+ "rpush",
82
+ "rpushx",
83
+ "lpop",
84
+ "rpop",
85
+ "rpoplpush",
86
+ "_bpop",
87
+ "blpop",
88
+ "brpop",
89
+ "brpoplpush",
90
+ "lindex",
91
+ "linsert",
92
+ "lrange",
93
+ "lrem",
94
+ "lset",
95
+ "ltrim"
96
+ ],
97
+ "set": [
98
+ "scard",
99
+ "sadd",
100
+ "srem",
101
+ "spop",
102
+ "srandmember",
103
+ "smove",
104
+ "sismember",
105
+ "smembers",
106
+ "sdiff",
107
+ "sdiffstore",
108
+ "sinter",
109
+ "sinterstore",
110
+ "sunion",
111
+ "sunionstore"
112
+ ],
113
+ "sorted_set": [
114
+ "zcard",
115
+ "zadd",
116
+ "zincrby",
117
+ "zrem",
118
+ "zscore",
119
+ "zrange",
120
+ "zrevrange",
121
+ "zrank",
122
+ "zrevrank",
123
+ "zremrangebyrank",
124
+ "zrangebyscore",
125
+ "zrevrangebyscore",
126
+ "zremrangebyscore",
127
+ "zcount",
128
+ "zinterstore",
129
+ "zunionstore"
130
+ ],
131
+ "hash": [
132
+ "hlen",
133
+ "hset",
134
+ "hsetnx",
135
+ "hmset",
136
+ "mapped_hmset",
137
+ "hget",
138
+ "hmget",
139
+ "mapped_hmget",
140
+ "hdel",
141
+ "hexists",
142
+ "hincrby",
143
+ "hincrbyfloat",
144
+ "hkeys",
145
+ "hvals",
146
+ "hgetall"
147
+ ],
148
+ "pubsub": [
149
+ "publish",
150
+ "subscribed?",
151
+ "subscribe",
152
+ "unsubscribe",
153
+ "psubscribe",
154
+ "punsubscribe"
155
+ ],
156
+ "transactions": [
157
+ "watch",
158
+ "unwatch",
159
+ "pipelined",
160
+ "multi",
161
+ "exec",
162
+ "discard"
163
+ ],
164
+ "scripting": [
165
+ "script",
166
+ "_eval",
167
+ "eval",
168
+ "evalsha"
169
+ ]
170
+ }
data/.travis/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec :path => "../"
4
+
5
+ case ENV["conn"]
6
+ when "hiredis"
7
+ gem "hiredis"
8
+ when "synchrony"
9
+ gem "hiredis"
10
+ gem "em-synchrony"
11
+ end
data/.travis.yml ADDED
@@ -0,0 +1,55 @@
1
+ language: ruby
2
+
3
+ branches:
4
+ only:
5
+ - master
6
+
7
+ rvm:
8
+ - 1.8.7
9
+ - 1.9.2
10
+ - 1.9.3
11
+ - 2.0.0
12
+ - 2.1.0
13
+ - jruby-18mode
14
+ - jruby-19mode
15
+
16
+ gemfile:
17
+ - .travis/Gemfile
18
+
19
+ env:
20
+ global:
21
+ - TIMEOUT=1
22
+ matrix:
23
+ - conn=ruby REDIS_BRANCH=2.6
24
+ - conn=hiredis REDIS_BRANCH=2.6
25
+ - conn=synchrony REDIS_BRANCH=2.6
26
+ - conn=ruby REDIS_BRANCH=2.8
27
+ - conn=ruby REDIS_BRANCH=unstable
28
+
29
+ matrix:
30
+ exclude:
31
+ # hiredis
32
+ - rvm: jruby-18mode
33
+ gemfile: .travis/Gemfile
34
+ env: conn=hiredis REDIS_BRANCH=2.6
35
+ - rvm: jruby-19mode
36
+ gemfile: .travis/Gemfile
37
+ env: conn=hiredis REDIS_BRANCH=2.6
38
+
39
+ # synchrony
40
+ - rvm: 1.8.7
41
+ gemfile: .travis/Gemfile
42
+ env: conn=synchrony REDIS_BRANCH=2.6
43
+ - rvm: jruby-18mode
44
+ gemfile: .travis/Gemfile
45
+ env: conn=synchrony REDIS_BRANCH=2.6
46
+ - rvm: jruby-19mode
47
+ gemfile: .travis/Gemfile
48
+ env: conn=synchrony REDIS_BRANCH=2.6
49
+
50
+ notifications:
51
+ irc:
52
+ - irc.freenode.net#redis-rb
53
+ email:
54
+ - damian.janowski@gmail.com
55
+ - pcnoordhuis@gmail.com
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --exclude redis/connection
2
+ --exclude redis/compat
3
+ --markup markdown
data/CHANGELOG.md ADDED
@@ -0,0 +1,285 @@
1
+ # (unreleased)
2
+
3
+ ...
4
+
5
+ # 3.0.7
6
+
7
+ * Added method `Redis2#dup` to duplicate a Redis2 connection.
8
+
9
+ * IPv6 support.
10
+
11
+ # 3.0.6
12
+
13
+ * Added support for `SCAN` and variants.
14
+
15
+ # 3.0.5
16
+
17
+ * Fix calling #select from a pipeline (#309).
18
+
19
+ * Added method `Redis2#connected?`.
20
+
21
+ * Added support for `MIGRATE` (Redis2 2.6).
22
+
23
+ * Support extended SET command (#343, thanks to @benubois).
24
+
25
+ # 3.0.4
26
+
27
+ * Ensure #watch without a block returns "OK" (#332).
28
+
29
+ * Make futures identifiable (#330).
30
+
31
+ * Fix an issue preventing STORE in a SORT with multiple GETs (#328).
32
+
33
+ # 3.0.3
34
+
35
+ * Blocking list commands (`BLPOP`, `BRPOP`, `BRPOPLPUSH`) use a socket
36
+ timeout equal to the sum of the command's timeout and the Redis2
37
+ client's timeout, instead of disabling socket timeout altogether.
38
+
39
+ * Ruby 2.0 compatibility.
40
+
41
+ * Added support for `DUMP` and `RESTORE` (Redis2 2.6).
42
+
43
+ * Added support for `BITCOUNT` and `BITOP` (Redis2 2.6).
44
+
45
+ * Call `#to_s` on value argument for `SET`, `SETEX`, `PSETEX`, `GETSET`,
46
+ `SETNX`, and `SETRANGE`.
47
+
48
+ # 3.0.2
49
+
50
+ * Unescape CGI escaped password in URL.
51
+
52
+ * Fix test to check availability of `UNIXSocket`.
53
+
54
+ * Fix handling of score = +/- infinity for sorted set commands.
55
+
56
+ * Replace array splats with concatenation where possible.
57
+
58
+ * Raise if `EXEC` returns an error.
59
+
60
+ * Passing a nil value in options hash no longer overwrites the default.
61
+
62
+ * Allow string keys in options hash passed to `Redis2.new` or
63
+ `Redis2.connect`.
64
+
65
+ * Fix uncaught error triggering unrelated error (synchrony driver).
66
+
67
+ See f7ffd5f1a628029691084de69e5b46699bb8b96d and #248.
68
+
69
+ # 3.0.1
70
+
71
+ * Fix reconnect logic not kicking in on a write error.
72
+
73
+ See 427dbd52928af452f35aa0a57b621bee56cdcb18 and #238.
74
+
75
+ # 3.0.0
76
+
77
+ ### Upgrading from 2.x to 3.0
78
+
79
+ The following items are the most important changes to review when
80
+ upgrading from redis-rb 2.x. A full list of changes can be found below.
81
+
82
+ * The methods for the following commands have changed the arguments they
83
+ take, their return value, or both.
84
+
85
+ * `BLPOP`, `BRPOP`, `BRPOPLPUSH`
86
+ * `SORT`
87
+ * `MSETNX`
88
+ * `ZRANGE`, `ZREVRANGE`, `ZRANGEBYSCORE`, `ZREVRANGEBYSCORE`
89
+ * `ZINCRBY`, `ZSCORE`
90
+
91
+ * The return value from `#pipelined` and `#multi` no longer contains
92
+ unprocessed replies, but the same replies that would be returned if
93
+ the command had not been executed in these blocks.
94
+
95
+ * The client raises custom errors on connection errors, instead of
96
+ `RuntimeError` and errors in the `Errno` family.
97
+
98
+ ### Changes
99
+
100
+ * Added support for scripting commands (Redis2 2.6).
101
+
102
+ Scripts can be executed using `#eval` and `#evalsha`. Both can
103
+ commands can either take two arrays to specify `KEYS` and `ARGV`, or
104
+ take a hash containing `:keys` and `:argv` to specify `KEYS` and
105
+ `ARGV`.
106
+
107
+ ```ruby
108
+ redis.eval("return ARGV[1] * ARGV[2]", :argv => [2, 3])
109
+ # => 6
110
+ ```
111
+
112
+ Subcommands of the `SCRIPT` command can be executed via the
113
+ `#script` method.
114
+
115
+ For example:
116
+
117
+ ```ruby
118
+ redis.script(:load, "return ARGV[1] * ARGV[2]")
119
+ # => "58db5d365a1922f32e7aa717722141ea9c2b0cf3"
120
+ redis.script(:exists, "58db5d365a1922f32e7aa717722141ea9c2b0cf3")
121
+ # => true
122
+ redis.script(:flush)
123
+ # => "OK"
124
+ ```
125
+
126
+ * The repository now lives at [https://github.com/redis/redis-rb](https://github.com/redis/redis-rb).
127
+ Thanks, Ezra!
128
+
129
+ * Added support for `PEXPIRE`, `PEXPIREAT`, `PTTL`, `PSETEX`,
130
+ `INCRYBYFLOAT`, `HINCRYBYFLOAT` and `TIME` (Redis2 2.6).
131
+
132
+ * `Redis2.current` is now thread unsafe, because the client itself is thread safe.
133
+
134
+ In the future you'll be able to do something like:
135
+
136
+ ```ruby
137
+ Redis2.current = Redis2::Pool.connect
138
+ ```
139
+
140
+ This makes `Redis2.current` actually usable in multi-threaded environments,
141
+ while not affecting those running a single thread.
142
+
143
+ * Change API for `BLPOP`, `BRPOP` and `BRPOPLPUSH`.
144
+
145
+ Both `BLPOP` and `BRPOP` now take a single argument equal to a
146
+ string key, or an array with string keys, followed by an optional
147
+ hash with a `:timeout` key. When not specified, the timeout defaults
148
+ to `0` to not time out.
149
+
150
+ ```ruby
151
+ redis.blpop(["list1", "list2"], :timeout => 1.0)
152
+ ```
153
+
154
+ `BRPOPLPUSH` also takes an optional hash with a `:timeout` key as
155
+ last argument for consistency. When not specified, the timeout
156
+ defaults to `0` to not time out.
157
+
158
+ ```ruby
159
+ redis.brpoplpush("some_list", "another_list", :timeout => 1.0)
160
+ ```
161
+
162
+ * When `SORT` is passed multiple key patterns to get via the `:get`
163
+ option, it now returns an array per result element, holding all `GET`
164
+ substitutions.
165
+
166
+ * The `MSETNX` command now returns a boolean.
167
+
168
+ * The `ZRANGE`, `ZREVRANGE`, `ZRANGEBYSCORE` and `ZREVRANGEBYSCORE` commands
169
+ now return an array containing `[String, Float]` pairs when
170
+ `:with_scores => true` is passed.
171
+
172
+ For example:
173
+
174
+ ```ruby
175
+ redis.zrange("zset", 0, -1, :with_scores => true)
176
+ # => [["foo", 1.0], ["bar", 2.0]]
177
+ ```
178
+
179
+ * The `ZINCRBY` and `ZSCORE` commands now return a `Float` score instead
180
+ of a string holding a representation of the score.
181
+
182
+ * The client now raises custom exceptions where it makes sense.
183
+
184
+ If by any chance you were rescuing low-level exceptions (`Errno::*`),
185
+ you should now rescue as follows:
186
+
187
+ Errno::ECONNRESET -> Redis2::ConnectionError
188
+ Errno::EPIPE -> Redis2::ConnectionError
189
+ Errno::ECONNABORTED -> Redis2::ConnectionError
190
+ Errno::EBADF -> Redis2::ConnectionError
191
+ Errno::EINVAL -> Redis2::ConnectionError
192
+ Errno::EAGAIN -> Redis2::TimeoutError
193
+ Errno::ECONNREFUSED -> Redis2::CannotConnectError
194
+
195
+ * Always raise exceptions originating from erroneous command invocation
196
+ inside pipelines and MULTI/EXEC blocks.
197
+
198
+ The old behavior (swallowing exceptions) could cause application bugs
199
+ to go unnoticed.
200
+
201
+ * Implement futures for assigning values inside pipelines and MULTI/EXEC
202
+ blocks. Futures are assigned their value after the pipeline or
203
+ MULTI/EXEC block has executed.
204
+
205
+ ```ruby
206
+ $redis.pipelined do
207
+ @future = $redis.get "key"
208
+ end
209
+
210
+ puts @future.value
211
+ ```
212
+
213
+ * Ruby 1.8.6 is officially not supported.
214
+
215
+ * Support `ZCOUNT` in `Redis2::Distributed` (Michael Dungan).
216
+
217
+ * Pipelined commands now return the same replies as when called outside
218
+ a pipeline.
219
+
220
+ In the past, pipelined replies were returned without post-processing.
221
+
222
+ * Support `SLOWLOG` command (Michael Bernstein).
223
+
224
+ * Calling `SHUTDOWN` effectively disconnects the client (Stefan Kaes).
225
+
226
+ * Basic support for mapping commands so that they can be renamed on the
227
+ server.
228
+
229
+ * Connecting using a URL now checks that a host is given.
230
+
231
+ It's just a small sanity check, cf. #126
232
+
233
+ * Support variadic commands introduced in Redis2 2.4.
234
+
235
+ # 2.2.2
236
+
237
+ * Added method `Redis2::Distributed#hsetnx`.
238
+
239
+ # 2.2.1
240
+
241
+ * Internal API: Client#call and family are now called with a single array
242
+ argument, since splatting a large number of arguments (100K+) results in a
243
+ stack overflow on 1.9.2.
244
+
245
+ * The `INFO` command can optionally take a subcommand. When the subcommand is
246
+ `COMMANDSTATS`, the client will properly format the returned statistics per
247
+ command. Subcommands for `INFO` are available since Redis2 v2.3.0 (unstable).
248
+
249
+ * Change `IO#syswrite` back to the buffered `IO#write` since some Rubies do
250
+ short writes for large (1MB+) buffers and some don't (see issue #108).
251
+
252
+ # 2.2.0
253
+
254
+ * Added method `Redis2#without_reconnect` that ensures the client will not try
255
+ to reconnect when running the code inside the specified block.
256
+
257
+ * Thread-safe by default. Thread safety can be explicitly disabled by passing
258
+ `:thread_safe => false` as argument.
259
+
260
+ * Commands called inside a MULTI/EXEC no longer raise error replies, since a
261
+ successful EXEC means the commands inside the block were executed.
262
+
263
+ * MULTI/EXEC blocks are pipelined.
264
+
265
+ * Don't disconnect on error replies.
266
+
267
+ * Use `IO#syswrite` instead of `IO#write` because write buffering is not
268
+ necessary.
269
+
270
+ * Connect to a unix socket by passing the `:path` option as argument.
271
+
272
+ * The timeout value is coerced into a float, allowing sub-second timeouts.
273
+
274
+ * Accept both `:with_scores` _and_ `:withscores` as argument to sorted set
275
+ commands.
276
+
277
+ * Use [hiredis](https://github.com/pietern/hiredis-rb) (v0.3 or higher) by
278
+ requiring "redis/connection/hiredis".
279
+
280
+ * Use [em-synchrony](https://github.com/igrigorik/em-synchrony) by requiring
281
+ "redis/connection/synchrony".
282
+
283
+ # 2.1.1
284
+
285
+ See commit log.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ezra Zygmuntowicz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.