Predis_Compatibility.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <?php
  2. namespace Predis;
  3. abstract class InlineCommand extends Command {
  4. public function serializeRequest($command, $arguments) {
  5. if (isset($arguments[0]) && is_array($arguments[0])) {
  6. $arguments[0] = implode($arguments[0], ' ');
  7. }
  8. return $command . (count($arguments) > 0
  9. ? ' ' . implode($arguments, ' ') . Protocol::NEWLINE
  10. : Protocol::NEWLINE
  11. );
  12. }
  13. }
  14. abstract class BulkCommand extends Command {
  15. public function serializeRequest($command, $arguments) {
  16. $data = array_pop($arguments);
  17. if (is_array($data)) {
  18. $data = implode($data, ' ');
  19. }
  20. return $command . ' ' . implode($arguments, ' ') . ' ' . strlen($data) .
  21. Protocol::NEWLINE . $data . Protocol::NEWLINE;
  22. }
  23. }
  24. RedisServerProfile::registerProfile('\Predis\RedisServer_v1_0', '1.0');
  25. class RedisServer_v1_0 extends \Predis\RedisServerProfile {
  26. public function getVersion() { return '1.0'; }
  27. public function getSupportedCommands() {
  28. return array(
  29. /* miscellaneous commands */
  30. 'ping' => '\Predis\Compatibility\v1_0\Commands\Ping',
  31. 'echo' => '\Predis\Compatibility\v1_0\Commands\DoEcho',
  32. 'auth' => '\Predis\Compatibility\v1_0\Commands\Auth',
  33. /* connection handling */
  34. 'quit' => '\Predis\Compatibility\v1_0\Commands\Quit',
  35. /* commands operating on string values */
  36. 'set' => '\Predis\Compatibility\v1_0\Commands\Set',
  37. 'setnx' => '\Predis\Compatibility\v1_0\Commands\SetPreserve',
  38. 'setPreserve' => '\Predis\Compatibility\v1_0\Commands\SetPreserve',
  39. 'get' => '\Predis\Compatibility\v1_0\Commands\Get',
  40. 'mget' => '\Predis\Compatibility\v1_0\Commands\GetMultiple',
  41. 'getMultiple' => '\Predis\Compatibility\v1_0\Commands\GetMultiple',
  42. 'getset' => '\Predis\Compatibility\v1_0\Commands\GetSet',
  43. 'getSet' => '\Predis\Compatibility\v1_0\Commands\GetSet',
  44. 'incr' => '\Predis\Compatibility\v1_0\Commands\Increment',
  45. 'increment' => '\Predis\Compatibility\v1_0\Commands\Increment',
  46. 'incrby' => '\Predis\Compatibility\v1_0\Commands\IncrementBy',
  47. 'incrementBy' => '\Predis\Compatibility\v1_0\Commands\IncrementBy',
  48. 'decr' => '\Predis\Compatibility\v1_0\Commands\Decrement',
  49. 'decrement' => '\Predis\Compatibility\v1_0\Commands\Decrement',
  50. 'decrby' => '\Predis\Compatibility\v1_0\Commands\DecrementBy',
  51. 'decrementBy' => '\Predis\Compatibility\v1_0\Commands\DecrementBy',
  52. 'exists' => '\Predis\Compatibility\v1_0\Commands\Exists',
  53. 'del' => '\Predis\Compatibility\v1_0\Commands\Delete',
  54. 'delete' => '\Predis\Compatibility\v1_0\Commands\Delete',
  55. 'type' => '\Predis\Compatibility\v1_0\Commands\Type',
  56. /* commands operating on the key space */
  57. 'keys' => '\Predis\Compatibility\v1_0\Commands\Keys',
  58. 'randomkey' => '\Predis\Compatibility\v1_0\Commands\RandomKey',
  59. 'randomKey' => '\Predis\Compatibility\v1_0\Commands\RandomKey',
  60. 'rename' => '\Predis\Compatibility\v1_0\Commands\Rename',
  61. 'renamenx' => '\Predis\Compatibility\v1_0\Commands\RenamePreserve',
  62. 'renamePreserve' => '\Predis\Compatibility\v1_0\Commands\RenamePreserve',
  63. 'expire' => '\Predis\Compatibility\v1_0\Commands\Expire',
  64. 'expireat' => '\Predis\Compatibility\v1_0\Commands\ExpireAt',
  65. 'expireAt' => '\Predis\Compatibility\v1_0\Commands\ExpireAt',
  66. 'dbsize' => '\Predis\Compatibility\v1_0\Commands\DatabaseSize',
  67. 'databaseSize' => '\Predis\Compatibility\v1_0\Commands\DatabaseSize',
  68. 'ttl' => '\Predis\Compatibility\v1_0\Commands\TimeToLive',
  69. 'timeToLive' => '\Predis\Compatibility\v1_0\Commands\TimeToLive',
  70. /* commands operating on lists */
  71. 'rpush' => '\Predis\Compatibility\v1_0\Commands\ListPushTail',
  72. 'pushTail' => '\Predis\Compatibility\v1_0\Commands\ListPushTail',
  73. 'lpush' => '\Predis\Compatibility\v1_0\Commands\ListPushHead',
  74. 'pushHead' => '\Predis\Compatibility\v1_0\Commands\ListPushHead',
  75. 'llen' => '\Predis\Compatibility\v1_0\Commands\ListLength',
  76. 'listLength' => '\Predis\Compatibility\v1_0\Commands\ListLength',
  77. 'lrange' => '\Predis\Compatibility\v1_0\Commands\ListRange',
  78. 'listRange' => '\Predis\Compatibility\v1_0\Commands\ListRange',
  79. 'ltrim' => '\Predis\Compatibility\v1_0\Commands\ListTrim',
  80. 'listTrim' => '\Predis\Compatibility\v1_0\Commands\ListTrim',
  81. 'lindex' => '\Predis\Compatibility\v1_0\Commands\ListIndex',
  82. 'listIndex' => '\Predis\Compatibility\v1_0\Commands\ListIndex',
  83. 'lset' => '\Predis\Compatibility\v1_0\Commands\ListSet',
  84. 'listSet' => '\Predis\Compatibility\v1_0\Commands\ListSet',
  85. 'lrem' => '\Predis\Compatibility\v1_0\Commands\ListRemove',
  86. 'listRemove' => '\Predis\Compatibility\v1_0\Commands\ListRemove',
  87. 'lpop' => '\Predis\Compatibility\v1_0\Commands\ListPopFirst',
  88. 'popFirst' => '\Predis\Compatibility\v1_0\Commands\ListPopFirst',
  89. 'rpop' => '\Predis\Compatibility\v1_0\Commands\ListPopLast',
  90. 'popLast' => '\Predis\Compatibility\v1_0\Commands\ListPopLast',
  91. /* commands operating on sets */
  92. 'sadd' => '\Predis\Compatibility\v1_0\Commands\SetAdd',
  93. 'setAdd' => '\Predis\Compatibility\v1_0\Commands\SetAdd',
  94. 'srem' => '\Predis\Compatibility\v1_0\Commands\SetRemove',
  95. 'setRemove' => '\Predis\Compatibility\v1_0\Commands\SetRemove',
  96. 'spop' => '\Predis\Compatibility\v1_0\Commands\SetPop',
  97. 'setPop' => '\Predis\Compatibility\v1_0\Commands\SetPop',
  98. 'smove' => '\Predis\Compatibility\v1_0\Commands\SetMove',
  99. 'setMove' => '\Predis\Compatibility\v1_0\Commands\SetMove',
  100. 'scard' => '\Predis\Compatibility\v1_0\Commands\SetCardinality',
  101. 'setCardinality' => '\Predis\Compatibility\v1_0\Commands\SetCardinality',
  102. 'sismember' => '\Predis\Compatibility\v1_0\Commands\SetIsMember',
  103. 'setIsMember' => '\Predis\Compatibility\v1_0\Commands\SetIsMember',
  104. 'sinter' => '\Predis\Compatibility\v1_0\Commands\SetIntersection',
  105. 'setIntersection' => '\Predis\Compatibility\v1_0\Commands\SetIntersection',
  106. 'sinterstore' => '\Predis\Compatibility\v1_0\Commands\SetIntersectionStore',
  107. 'setIntersectionStore' => '\Predis\Compatibility\v1_0\Commands\SetIntersectionStore',
  108. 'sunion' => '\Predis\Compatibility\v1_0\Commands\SetUnion',
  109. 'setUnion' => '\Predis\Compatibility\v1_0\Commands\SetUnion',
  110. 'sunionstore' => '\Predis\Compatibility\v1_0\Commands\SetUnionStore',
  111. 'setUnionStore' => '\Predis\Compatibility\v1_0\Commands\SetUnionStore',
  112. 'sdiff' => '\Predis\Compatibility\v1_0\Commands\SetDifference',
  113. 'setDifference' => '\Predis\Compatibility\v1_0\Commands\SetDifference',
  114. 'sdiffstore' => '\Predis\Compatibility\v1_0\Commands\SetDifferenceStore',
  115. 'setDifferenceStore' => '\Predis\Compatibility\v1_0\Commands\SetDifferenceStore',
  116. 'smembers' => '\Predis\Compatibility\v1_0\Commands\SetMembers',
  117. 'setMembers' => '\Predis\Compatibility\v1_0\Commands\SetMembers',
  118. 'srandmember' => '\Predis\Compatibility\v1_0\Commands\SetRandomMember',
  119. 'setRandomMember' => '\Predis\Compatibility\v1_0\Commands\SetRandomMember',
  120. /* multiple databases handling commands */
  121. 'select' => '\Predis\Compatibility\v1_0\Commands\SelectDatabase',
  122. 'selectDatabase' => '\Predis\Compatibility\v1_0\Commands\SelectDatabase',
  123. 'move' => '\Predis\Compatibility\v1_0\Commands\MoveKey',
  124. 'moveKey' => '\Predis\Compatibility\v1_0\Commands\MoveKey',
  125. 'flushdb' => '\Predis\Compatibility\v1_0\Commands\FlushDatabase',
  126. 'flushDatabase' => '\Predis\Compatibility\v1_0\Commands\FlushDatabase',
  127. 'flushall' => '\Predis\Compatibility\v1_0\Commands\FlushAll',
  128. 'flushDatabases' => '\Predis\Compatibility\v1_0\Commands\FlushAll',
  129. /* sorting */
  130. 'sort' => '\Predis\Compatibility\v1_0\Commands\Sort',
  131. /* remote server control commands */
  132. 'info' => '\Predis\Compatibility\v1_0\Commands\Info',
  133. 'slaveof' => '\Predis\Compatibility\v1_0\Commands\SlaveOf',
  134. 'slaveOf' => '\Predis\Compatibility\v1_0\Commands\SlaveOf',
  135. /* persistence control commands */
  136. 'save' => '\Predis\Compatibility\v1_0\Commands\Save',
  137. 'bgsave' => '\Predis\Compatibility\v1_0\Commands\BackgroundSave',
  138. 'backgroundSave' => '\Predis\Compatibility\v1_0\Commands\BackgroundSave',
  139. 'lastsave' => '\Predis\Compatibility\v1_0\Commands\LastSave',
  140. 'lastSave' => '\Predis\Compatibility\v1_0\Commands\LastSave',
  141. 'shutdown' => '\Predis\Compatibility\v1_0\Commands\Shutdown',
  142. );
  143. }
  144. }
  145. /* ------------------------------------------------------------------------- */
  146. namespace Predis\Compatibility\v1_0\Commands;
  147. /* miscellaneous commands */
  148. class Ping extends \Predis\InlineCommand {
  149. public function canBeHashed() { return false; }
  150. public function getCommandId() { return 'PING'; }
  151. public function parseResponse($data) {
  152. return $data === 'PONG' ? true : false;
  153. }
  154. }
  155. class DoEcho extends \Predis\BulkCommand {
  156. public function canBeHashed() { return false; }
  157. public function getCommandId() { return 'ECHO'; }
  158. }
  159. class Auth extends \Predis\InlineCommand {
  160. public function canBeHashed() { return false; }
  161. public function getCommandId() { return 'AUTH'; }
  162. }
  163. /* connection handling */
  164. class Quit extends \Predis\InlineCommand {
  165. public function canBeHashed() { return false; }
  166. public function getCommandId() { return 'QUIT'; }
  167. public function closesConnection() { return true; }
  168. }
  169. /* commands operating on string values */
  170. class Set extends \Predis\BulkCommand {
  171. public function getCommandId() { return 'SET'; }
  172. }
  173. class SetPreserve extends \Predis\BulkCommand {
  174. public function getCommandId() { return 'SETNX'; }
  175. public function parseResponse($data) { return (bool) $data; }
  176. }
  177. class Get extends \Predis\InlineCommand {
  178. public function getCommandId() { return 'GET'; }
  179. }
  180. class GetMultiple extends \Predis\InlineCommand {
  181. public function canBeHashed() { return false; }
  182. public function getCommandId() { return 'MGET'; }
  183. }
  184. class GetSet extends \Predis\BulkCommand {
  185. public function getCommandId() { return 'GETSET'; }
  186. }
  187. class Increment extends \Predis\InlineCommand {
  188. public function getCommandId() { return 'INCR'; }
  189. }
  190. class IncrementBy extends \Predis\InlineCommand {
  191. public function getCommandId() { return 'INCRBY'; }
  192. }
  193. class Decrement extends \Predis\InlineCommand {
  194. public function getCommandId() { return 'DECR'; }
  195. }
  196. class DecrementBy extends \Predis\InlineCommand {
  197. public function getCommandId() { return 'DECRBY'; }
  198. }
  199. class Exists extends \Predis\InlineCommand {
  200. public function getCommandId() { return 'EXISTS'; }
  201. public function parseResponse($data) { return (bool) $data; }
  202. }
  203. class Delete extends \Predis\InlineCommand {
  204. public function getCommandId() { return 'DEL'; }
  205. }
  206. class Type extends \Predis\InlineCommand {
  207. public function getCommandId() { return 'TYPE'; }
  208. }
  209. /* commands operating on the key space */
  210. class Keys extends \Predis\InlineCommand {
  211. public function canBeHashed() { return false; }
  212. public function getCommandId() { return 'KEYS'; }
  213. public function parseResponse($data) {
  214. return strlen($data) > 0 ? explode(' ', $data) : array();
  215. }
  216. }
  217. class RandomKey extends \Predis\InlineCommand {
  218. public function canBeHashed() { return false; }
  219. public function getCommandId() { return 'RANDOMKEY'; }
  220. public function parseResponse($data) { return $data !== '' ? $data : null; }
  221. }
  222. class Rename extends \Predis\InlineCommand {
  223. public function canBeHashed() { return false; }
  224. public function getCommandId() { return 'RENAME'; }
  225. }
  226. class RenamePreserve extends \Predis\InlineCommand {
  227. public function canBeHashed() { return false; }
  228. public function getCommandId() { return 'RENAMENX'; }
  229. public function parseResponse($data) { return (bool) $data; }
  230. }
  231. class Expire extends \Predis\InlineCommand {
  232. public function getCommandId() { return 'EXPIRE'; }
  233. public function parseResponse($data) { return (bool) $data; }
  234. }
  235. class ExpireAt extends \Predis\InlineCommand {
  236. public function getCommandId() { return 'EXPIREAT'; }
  237. public function parseResponse($data) { return (bool) $data; }
  238. }
  239. class DatabaseSize extends \Predis\InlineCommand {
  240. public function canBeHashed() { return false; }
  241. public function getCommandId() { return 'DBSIZE'; }
  242. }
  243. class TimeToLive extends \Predis\InlineCommand {
  244. public function getCommandId() { return 'TTL'; }
  245. }
  246. /* commands operating on lists */
  247. class ListPushTail extends \Predis\BulkCommand {
  248. public function getCommandId() { return 'RPUSH'; }
  249. }
  250. class ListPushHead extends \Predis\BulkCommand {
  251. public function getCommandId() { return 'LPUSH'; }
  252. }
  253. class ListLength extends \Predis\InlineCommand {
  254. public function getCommandId() { return 'LLEN'; }
  255. }
  256. class ListRange extends \Predis\InlineCommand {
  257. public function getCommandId() { return 'LRANGE'; }
  258. }
  259. class ListTrim extends \Predis\InlineCommand {
  260. public function getCommandId() { return 'LTRIM'; }
  261. }
  262. class ListIndex extends \Predis\InlineCommand {
  263. public function getCommandId() { return 'LINDEX'; }
  264. }
  265. class ListSet extends \Predis\BulkCommand {
  266. public function getCommandId() { return 'LSET'; }
  267. }
  268. class ListRemove extends \Predis\BulkCommand {
  269. public function getCommandId() { return 'LREM'; }
  270. }
  271. class ListPopFirst extends \Predis\InlineCommand {
  272. public function getCommandId() { return 'LPOP'; }
  273. }
  274. class ListPopLast extends \Predis\InlineCommand {
  275. public function getCommandId() { return 'RPOP'; }
  276. }
  277. /* commands operating on sets */
  278. class SetAdd extends \Predis\BulkCommand {
  279. public function getCommandId() { return 'SADD'; }
  280. public function parseResponse($data) { return (bool) $data; }
  281. }
  282. class SetRemove extends \Predis\BulkCommand {
  283. public function getCommandId() { return 'SREM'; }
  284. public function parseResponse($data) { return (bool) $data; }
  285. }
  286. class SetPop extends \Predis\InlineCommand {
  287. public function getCommandId() { return 'SPOP'; }
  288. }
  289. class SetMove extends \Predis\BulkCommand {
  290. public function canBeHashed() { return false; }
  291. public function getCommandId() { return 'SMOVE'; }
  292. public function parseResponse($data) { return (bool) $data; }
  293. }
  294. class SetCardinality extends \Predis\InlineCommand {
  295. public function getCommandId() { return 'SCARD'; }
  296. }
  297. class SetIsMember extends \Predis\BulkCommand {
  298. public function getCommandId() { return 'SISMEMBER'; }
  299. public function parseResponse($data) { return (bool) $data; }
  300. }
  301. class SetIntersection extends \Predis\InlineCommand {
  302. public function getCommandId() { return 'SINTER'; }
  303. }
  304. class SetIntersectionStore extends \Predis\InlineCommand {
  305. public function getCommandId() { return 'SINTERSTORE'; }
  306. }
  307. class SetUnion extends \Predis\InlineCommand {
  308. public function getCommandId() { return 'SUNION'; }
  309. }
  310. class SetUnionStore extends \Predis\InlineCommand {
  311. public function getCommandId() { return 'SUNIONSTORE'; }
  312. }
  313. class SetDifference extends \Predis\InlineCommand {
  314. public function getCommandId() { return 'SDIFF'; }
  315. }
  316. class SetDifferenceStore extends \Predis\InlineCommand {
  317. public function getCommandId() { return 'SDIFFSTORE'; }
  318. }
  319. class SetMembers extends \Predis\InlineCommand {
  320. public function getCommandId() { return 'SMEMBERS'; }
  321. }
  322. class SetRandomMember extends \Predis\InlineCommand {
  323. public function getCommandId() { return 'SRANDMEMBER'; }
  324. }
  325. /* multiple databases handling commands */
  326. class SelectDatabase extends \Predis\InlineCommand {
  327. public function canBeHashed() { return false; }
  328. public function getCommandId() { return 'SELECT'; }
  329. }
  330. class MoveKey extends \Predis\InlineCommand {
  331. public function canBeHashed() { return false; }
  332. public function getCommandId() { return 'MOVE'; }
  333. public function parseResponse($data) { return (bool) $data; }
  334. }
  335. class FlushDatabase extends \Predis\InlineCommand {
  336. public function canBeHashed() { return false; }
  337. public function getCommandId() { return 'FLUSHDB'; }
  338. }
  339. class FlushAll extends \Predis\InlineCommand {
  340. public function canBeHashed() { return false; }
  341. public function getCommandId() { return 'FLUSHALL'; }
  342. }
  343. /* sorting */
  344. class Sort extends \Predis\InlineCommand {
  345. public function getCommandId() { return 'SORT'; }
  346. public function filterArguments(Array $arguments) {
  347. if (count($arguments) === 1) {
  348. return $arguments;
  349. }
  350. // TODO: add more parameters checks
  351. $query = array($arguments[0]);
  352. $sortParams = $arguments[1];
  353. if (isset($sortParams['by'])) {
  354. $query[] = 'BY';
  355. $query[] = $sortParams['by'];
  356. }
  357. if (isset($sortParams['get'])) {
  358. $getargs = $sortParams['get'];
  359. if (is_array($getargs)) {
  360. foreach ($getargs as $getarg) {
  361. $query[] = 'GET';
  362. $query[] = $getarg;
  363. }
  364. }
  365. else {
  366. $query[] = 'GET';
  367. $query[] = $getargs;
  368. }
  369. }
  370. if (isset($sortParams['limit']) && is_array($sortParams['limit'])) {
  371. $query[] = 'LIMIT';
  372. $query[] = $sortParams['limit'][0];
  373. $query[] = $sortParams['limit'][1];
  374. }
  375. if (isset($sortParams['sort'])) {
  376. $query[] = strtoupper($sortParams['sort']);
  377. }
  378. if (isset($sortParams['alpha']) && $sortParams['alpha'] == true) {
  379. $query[] = 'ALPHA';
  380. }
  381. if (isset($sortParams['store']) && $sortParams['store'] == true) {
  382. $query[] = 'STORE';
  383. $query[] = $sortParams['store'];
  384. }
  385. return $query;
  386. }
  387. }
  388. /* persistence control commands */
  389. class Save extends \Predis\InlineCommand {
  390. public function canBeHashed() { return false; }
  391. public function getCommandId() { return 'SAVE'; }
  392. }
  393. class BackgroundSave extends \Predis\InlineCommand {
  394. public function canBeHashed() { return false; }
  395. public function getCommandId() { return 'BGSAVE'; }
  396. public function parseResponse($data) {
  397. if ($data == 'Background saving started') {
  398. return true;
  399. }
  400. return $data;
  401. }
  402. }
  403. class LastSave extends \Predis\InlineCommand {
  404. public function canBeHashed() { return false; }
  405. public function getCommandId() { return 'LASTSAVE'; }
  406. }
  407. class Shutdown extends \Predis\InlineCommand {
  408. public function canBeHashed() { return false; }
  409. public function getCommandId() { return 'SHUTDOWN'; }
  410. public function closesConnection() { return true; }
  411. }
  412. /* remote server control commands */
  413. class Info extends \Predis\InlineCommand {
  414. public function canBeHashed() { return false; }
  415. public function getCommandId() { return 'INFO'; }
  416. public function parseResponse($data) {
  417. $info = array();
  418. $infoLines = explode("\r\n", $data, -1);
  419. foreach ($infoLines as $row) {
  420. list($k, $v) = explode(':', $row);
  421. if (!preg_match('/^db\d+$/', $k)) {
  422. $info[$k] = $v;
  423. }
  424. else {
  425. $db = array();
  426. foreach (explode(',', $v) as $dbvar) {
  427. list($dbvk, $dbvv) = explode('=', $dbvar);
  428. $db[trim($dbvk)] = $dbvv;
  429. }
  430. $info[$k] = $db;
  431. }
  432. }
  433. return $info;
  434. }
  435. }
  436. class SlaveOf extends \Predis\InlineCommand {
  437. public function canBeHashed() { return false; }
  438. public function getCommandId() { return 'SLAVEOF'; }
  439. public function filterArguments(Array $arguments) {
  440. if (count($arguments) === 0 || $arguments[0] === 'NO ONE') {
  441. return array('NO', 'ONE');
  442. }
  443. return $arguments;
  444. }
  445. }
  446. ?>