|
2 | 2 |
|
3 | 3 | namespace Webdcg\Redis\Traits; |
4 | 4 |
|
| 5 | +use Webdcg\Redis\Exceptions\ScriptCommandException; |
| 6 | + |
5 | 7 | trait Scripting |
6 | 8 | { |
| 9 | + /* |
| 10 | + * Available Script Commands |
| 11 | + */ |
| 12 | + protected $SCRIPT_COMMANDS = ['LOAD', 'FLUSH', 'KILL', 'EXISTS']; |
| 13 | + |
7 | 14 | /** |
8 | 15 | * Evaluate a LUA script serverside. |
| 16 | + * |
9 | 17 | * See: https://redis.io/commands/eval. |
10 | 18 | * |
11 | 19 | * @param string $script |
12 | 20 | * @param array $arguments |
13 | 21 | * @param int|integer $numKeys |
14 | 22 | * |
15 | | - * @return mixed What is returned depends on what the LUA |
16 | | - * script itself returns, which could be a scalar value |
| 23 | + * @return mixed What is returned depends on what the LUA script |
| 24 | + * itself returns, which could be a scalar value |
17 | 25 | * (int/string), or an array. Arrays that are returned |
18 | 26 | * can also contain other arrays, if that's how it was |
19 | 27 | * set up in your LUA script. If there is an error |
20 | 28 | * executing the LUA script, the getLastError() |
21 | 29 | * function can tell you the message that came back |
22 | 30 | * from Redis (e.g. compile error). |
23 | 31 | */ |
24 | | - public function eval(string $script, array $arguments = [], int $numKeys = 0) |
| 32 | + public function eval(string $script, ?array $arguments = null, ?int $numKeys = null) |
25 | 33 | { |
| 34 | + if (!is_null($arguments) && !is_null($numKeys)) { |
| 35 | + return $this->redis->eval($script, $arguments, $numKeys); |
| 36 | + } |
| 37 | + |
26 | 38 | return $this->redis->eval($script); |
27 | 39 | } |
28 | 40 |
|
29 | | - public function evalSha(): bool |
| 41 | + |
| 42 | + /** |
| 43 | + * Evaluate a LUA script serverside, from the SHA1 hash of the script instead |
| 44 | + * of the script itself. |
| 45 | + * |
| 46 | + * In order to run this command Redis will have to have already loaded the |
| 47 | + * script, either by running it or via the SCRIPT LOAD command. |
| 48 | + * |
| 49 | + * See: https://redis.io/commands/evalsha. |
| 50 | + * |
| 51 | + * @param string $sha1 The sha1 encoded hash of the script you want to run. |
| 52 | + * @param array|null $arguments Arguments to pass to the LUA script. |
| 53 | + * @param int|null $numKeys The number of arguments that should go into the |
| 54 | + * KEYS array, vs. the ARGV array when Redis spins |
| 55 | + * the script (optional). |
| 56 | + * |
| 57 | + * @return mixed |
| 58 | + */ |
| 59 | + public function evalSha(string $sha1, ?array $arguments = null, ?int $numKeys = null) |
30 | 60 | { |
31 | | - return false; |
| 61 | + if (!is_null($arguments) && !is_null($numKeys)) { |
| 62 | + return $this->redis->evalSha($sha1, $arguments, $numKeys); |
| 63 | + } |
| 64 | + |
| 65 | + return $this->redis->evalSha($sha1); |
32 | 66 | } |
33 | 67 |
|
34 | | - public function script(): bool |
| 68 | + |
| 69 | + /** |
| 70 | + * Execute the Redis SCRIPT command to perform various operations on the |
| 71 | + * scripting subsystem. |
| 72 | + * |
| 73 | + * See: https://redis.io/commands/script-load. |
| 74 | + * See: https://redis.io/commands/script-flush. |
| 75 | + * |
| 76 | + * @param string $command |
| 77 | + * @param splat $scripts |
| 78 | + * |
| 79 | + * @return mixed SCRIPT LOAD will return the SHA1 hash of the |
| 80 | + * passed script on success, and FALSE on |
| 81 | + * failure. |
| 82 | + * SCRIPT FLUSH should always return TRUE |
| 83 | + * SCRIPT KILL will return true if a script was |
| 84 | + * able to be killed and false if not. |
| 85 | + * SCRIPT EXISTS will return an array with TRUE |
| 86 | + * or FALSE for each passed script. |
| 87 | + */ |
| 88 | + public function script(string $command, ...$scripts) |
35 | 89 | { |
36 | | - return false; |
| 90 | + $command = strtoupper($command); |
| 91 | + |
| 92 | + if (!in_array($command, $this->SCRIPT_COMMANDS)) { |
| 93 | + throw new ScriptCommandException('Script Command not supported', 1); |
| 94 | + } |
| 95 | + |
| 96 | + if ($command == 'FLUSH' || $command == 'KILL') { |
| 97 | + return $this->redis->script($command); |
| 98 | + } |
| 99 | + |
| 100 | + if ($command == 'EXISTS') { |
| 101 | + return $this->redis->script($command, ...$scripts); |
| 102 | + } |
| 103 | + |
| 104 | + if (count($scripts) != 1) { |
| 105 | + throw new ScriptCommandException('Invalid Number of Scripts to Load', 1); |
| 106 | + } |
| 107 | + |
| 108 | + return $this->redis->script($command, $scripts[0]); |
37 | 109 | } |
38 | 110 |
|
39 | | - public function getLastError(): bool |
| 111 | + |
| 112 | + /** |
| 113 | + * The last error message (if any) |
| 114 | + * |
| 115 | + * |
| 116 | + * @return mixed|string|null A string with the last returned script |
| 117 | + * based error message, or NULL if there |
| 118 | + * is no error. |
| 119 | + */ |
| 120 | + public function getLastError(): ?string |
40 | 121 | { |
41 | | - return false; |
| 122 | + return $this->redis->getLastError(); |
42 | 123 | } |
43 | 124 |
|
| 125 | + |
| 126 | + /** |
| 127 | + * Clear the last error message |
| 128 | + * |
| 129 | + * @return bool true |
| 130 | + */ |
44 | 131 | public function clearLastError(): bool |
45 | 132 | { |
46 | | - return false; |
| 133 | + return $this->redis->clearLastError(); |
47 | 134 | } |
48 | 135 |
|
49 | | - public function prefix(): bool |
| 136 | + |
| 137 | + /** |
| 138 | + * A utility method to prefix the value with the prefix setting for phpredis. |
| 139 | + * |
| 140 | + * @param string $key The value you wish to prefix |
| 141 | + * |
| 142 | + * @return string If a prefix is set up, the value now prefixed. |
| 143 | + * If there is no prefix, the value will be returned |
| 144 | + * unchanged. |
| 145 | + */ |
| 146 | + public function _prefix(string $key): string |
50 | 147 | { |
51 | | - return false; |
| 148 | + return $this->redis->_prefix($key); |
52 | 149 | } |
53 | 150 |
|
54 | | - public function unserialize(): bool |
| 151 | + /** |
| 152 | + * A utility method to serialize values manually. |
| 153 | + * |
| 154 | + * This method allows you to serialize a value with whatever serializer is |
| 155 | + * configured, manually. This can be useful for serialization/unserialization |
| 156 | + * of data going in and out of EVAL commands as phpredis can't automatically |
| 157 | + * do this itself. Note that if no serializer is set, phpredis will change |
| 158 | + * Array values to 'Array', and Objects to 'Object'. |
| 159 | + * |
| 160 | + * @param mixed|string|array|obhect $value The value to be serialized. |
| 161 | + * |
| 162 | + * @return mixed The serialized value. |
| 163 | + */ |
| 164 | + public function _serialize($value) |
55 | 165 | { |
56 | | - return false; |
| 166 | + return $this->redis->_serialize($value); |
57 | 167 | } |
58 | 168 |
|
59 | | - public function serialize(): bool |
| 169 | + |
| 170 | + /** |
| 171 | + * A utility method to unserialize data with whatever serializer is set up. |
| 172 | + * |
| 173 | + * If there is no serializer set, the value will be returned unchanged. |
| 174 | + * If there is a serializer set up, and the data passed in is malformed, |
| 175 | + * an exception will be thrown. This can be useful if phpredis is |
| 176 | + * serializing values, and you return something from redis in a LUA script |
| 177 | + * that is serialized. |
| 178 | + * |
| 179 | + * @param string $value The value to be unserialized |
| 180 | + * |
| 181 | + * @return mixed Unserialized value |
| 182 | + */ |
| 183 | + public function _unserialize(string $value) |
60 | 184 | { |
61 | | - return false; |
| 185 | + return $this->redis->_unserialize($value); |
62 | 186 | } |
63 | 187 | } |
0 commit comments