Commit Graph

82 Commits

Author SHA1 Message Date
Daniele Alessandri f06a41cfdc Change method to undefine commands in factory.
The previous implementation was not good because we were exposing in the
public API an internal implementation detail of the base factory class,
furthermore it made Predis\Command\Factory::define() confusing. Having a
separate method to undefine commands in the factory is self-explanatory.

We also changed `Predis\Configuration\Option\Commands` accordingly when
a dictionary of $commandID => $classCommand is passed to the "commands"
client option and $classCommand is NULL.

A few minor changes (mostly cosmetic or documentation) were applied too.

From feedback to PR #644.
2020-08-21 14:30:52 +02:00
Daniele Alessandri c26909699b Merge remote-tracking branch 'github/pr/639' into main 2020-08-18 16:03:10 +02:00
Raza Mehdi 5edf443141 Fix tests. 2020-08-16 01:59:41 +05:00
Daniele Alessandri 67c0fb8eb1 Separate id and alias in predis cluster (client-side sharding).
This change does not affect distribution but simply separates the two
concepts of connection ID (ip:port pair) and alias (value set via the
"alias" connection parameter), the method getConnectionByAlias() has
been added to reflect this change.

The method getConnectionBySlot() has also been added.
2016-06-18 17:12:20 +02:00
Daniele Alessandri 184d583895 Implement the concept of role for connections.
When using replication backends, now the role of a connection is not
defined by its alias but by the new connection parameter "role" that
can be set to "master", "slave" and (for redis-sentinel) "sentinel".

This also led to a redesign of how connections can be retrieved from
replication backends: the method getConnectionById() now retrieves a
connection only by its ID (ip:port pair), to get a connection by its
alias there is the new method getConnectionByAlias(). This method is
not supported by the redis-sentinel backend due to its dynamic nature
(connections are retrieved and initialized at runtime from sentinels)
but it is still possible to get a single connection from the pool by
using its ID. It is also possible to retrive a connection by its role
using the method getConnectionByRole().

NOTE: the "role" parameter is an hint for the internals of aggregate
connection backends so it is still possible that the actual role of
a connection changes during the execution of a script (e.g. a slave
gets promoted to the role of master): in this case the parameters of
that connection will not be changed as they are immutable, but the
method getConnectionByRole() will return the appropriate connection.

Predis\Client::getClientBy() has been updated with the addition of
"role" and "alias" as supported selectors.
2016-06-18 15:32:53 +02:00
Daniele Alessandri b3b35a9ae2 Remove Predis\Client::getConnectionById(). 2016-06-16 16:10:46 +02:00
Daniele Alessandri 7bb2192294 Replace Predis\Client::on() with getClientBy().
This method improves the previous one, which worked only by picking a
connection by ID, allowing users to specify a selector type among the
following ones: "id", "key", "slot", "command". These selectors are
expanded internally to methods, invoked against the connection object
in use by the client, that follow the getConnectionByXXX() convention
already in use through the library:

  id      => getConnectionById()
  key     => getConnectionByKey()
  slot    => getConnectionBySlot()
  command => getConnectionByCommand()

The underlying connection does not necessarily need to implement the
aggregate connection interface as the client relies on a duck-typing
approach by using method_exists().
2016-06-16 16:10:42 +02:00
Daniele Alessandri fa643ac20c Apply CS fixes. 2016-06-10 11:12:26 +02:00
Daniele Alessandri eb1e686ff9 [tests] Change indentation of mock method expectations. 2016-06-10 11:08:26 +02:00
Daniele Alessandri f02f3b6d37 [tests] Improve code coverage.
There is still some work to improve coverage in other classes though.
2016-06-09 16:41:19 +02:00
Daniele Alessandri ee7104d2e5 Replace "getClientFor()" with "on()" in Client.
This new method acts exactly like "getClientFor()" by returning a new
client instance for the specified node unless a callback is passed as
the second argument, in this case the callback is invoked and the new
client instance is passed to it. The value returned by the callback
is used as the return value of the "on()" method.
2016-06-07 20:00:11 +02:00
Daniele Alessandri d34bdd38c3 Reorganize and improve client options.
All option classes have been moved in the Predis\Configuration\Option
namespace and some have been optimized to have less impact on client
initialization timings.

Furthermore the accepted values for some options have been changed,
this is the complete list of accepted values:

- _aggregate_: callable returning an aggregate connection.
- cluster: string value ("predis", "redis"), callable returning an
  aggregate connection.
- replication: string value ("predis", "sentinel"), callable returning
  an aggregate connection.
- commands: command factory, named array mapping command IDs to PHP
  classes, callable returning a command factory or a named array.
- connections: connection factory, callable returning a connection
  factory, named array mapping connection schemes to PHP classes.
- _prefix_: string value, command processor, callable.
- _exceptions_: boolean value.

Note that the cluster and replication options now return a closure
acting as initializer instead of an aggregate connection.
2016-06-07 15:23:32 +02:00
Daniele Alessandri 1028599ac5 Split Predis\Connection\Aggregate namespace.
Now we have two namespaces for cluster and replication backends:

  - Predis\Connection\Cluster
  - Predis\Connection\Replication
2016-06-07 15:23:32 +02:00
Daniele Alessandri 4b47639f9e Rename command classes using command ID as name.
Some notable exceptions are EVAL and ECHO because having these names
as class names would raise a syntax error.
2016-06-04 20:54:41 +02:00
Daniele Alessandri 62b421f20e Switch from server profiles to commands factory.
This change reduces some unnecessary complexity in the library, Redis
commands do not change much after all. Developers can still implement
their own commands factory, inject new commands or override existing
ones. The "profile" client options has been renamed to "commands" and
it accepts instances of Predis\Command\FactoryInterface.

The test suite checks at runtime the version of the running instance
of Redis for integration tests to adapt itself automatically.
2016-06-04 15:36:21 +02:00
Daniele Alessandri 6e3f301588 Move commands classes in Predis\Command\Redis. 2016-06-04 15:36:16 +02:00
Daniele Alessandri 843ad23ea7 [tests] Move utility method into base test class. 2016-06-01 22:27:36 +02:00
Daniele Alessandri ecab7e4642 Implement IteratorAggregate interface for Client.
Now it is possible to iterate over traversable aggregate connections
and get a key/value pair of $connectionId => $clientInstance for each
node.
2016-06-01 12:33:20 +02:00
Daniele Alessandri 7282ca2b52 Remove unneeded "use" imports. 2015-07-24 21:25:40 +02:00
Daniele Alessandri 6590c44a27 Run php-cs-fixer against codebase in src/ and tests/. 2015-07-24 18:04:42 +02:00
Daniele Alessandri 7c1d324f30 [tests] Apply some fixes and improvements and remove old stuff. 2015-07-24 17:26:06 +02:00
Daniele Alessandri 45e351be79 [phpdoc] Fix formatting of phpdoc headers. 2014-07-27 23:59:37 +02:00
Daniele Alessandri dbfc1a74ba More random fixes after inspection. 2014-07-27 23:06:17 +02:00
Daniele Alessandri 4e1186f845 [phpdoc] Fix undefined classes. 2014-07-27 21:57:50 +02:00
Daniele Alessandri aa5c893d5a [phpdoc] Fix undefined namespaces. 2014-07-27 21:57:40 +02:00
Daniele Alessandri 202c558103 Run php-cs against source code. 2014-07-17 15:59:43 +02:00
Daniele Alessandri 5a474c5a32 Rename alias used in Predis\Client for Predis\Transaction\MultiExec. 2014-06-03 18:56:48 +02:00
Daniele Alessandri abd284c972 Complete reorganization of the Predis\Connection namespace.
* Renamed SingleConnectionInterface to NodeConnectionInterface since
  this name is better and makes even more sense in the context of
  cluster and replication scenarios.

* Moved specialized aggregate connections (the ones implementing both
  predis and redis cluster and master/slave replication) in a newly
  created Predis\Connection\Aggregate sub-namespace.

* Removed the "Connection" part from names of aggregate connection
  interfaces in the Predis\Connection\Aggregate sub-namespace.

* Changed "Composable" to "Composite" in the name of interfaces and
  classes that can use pluggable protocol processors.
2014-06-03 15:19:32 +02:00
Daniele Alessandri 8357af177e [test] Fix wrong variable. 2013-12-22 15:00:50 +01:00
Daniele Alessandri 2aa97e3e61 Apply fixes for consistency.
I know that importing classes and interfaces for the root namespace
using the "use" directive is weird and totally uncommon...
2013-12-21 11:26:09 +01:00
Daniele Alessandri 2a6409590c Run php-cs against test suite. 2013-12-17 12:55:56 +01:00
Daniele Alessandri 0f34f41ccf Fix and reword some exception messages. 2013-12-16 15:13:18 +01:00
Daniele Alessandri 58c5029574 Rename Predis\Connection\AggregatedConnectionInterface. 2013-12-15 12:38:21 +01:00
Daniele Alessandri 2a7607f128 Rename Predis\Connection\ConnectionFactory. 2013-12-15 10:09:08 +01:00
Daniele Alessandri cbf015164c Rename Predis\Client::raw() to Predis\Client::executeRaw().
This is more consistent with Predis\Client::executeRaw() and its more
explicit since simply "raw" as a method name was a bit too vague even
despite being nicely short.
2013-12-14 20:37:28 +01:00
Daniele Alessandri 8744285cb3 Ignoring the plural form of "reply" for renames is dumb...
[ci skip]
2013-12-10 18:08:14 +01:00
Daniele Alessandri 373d30b070 Use Predis\Response\Status to identify all kinds of status responses.
Status response objects are needed mostly to make it possible from the
client perspective to differentiate a status response with the payload
"OK" from a normale bulk reply containing "OK".

The biggest change is for commands returning +OK responses: these were
previously translated to TRUE (bool value), but they are now returned
as instances of Predis\Response\Status. Just to illustrate an example
of the possibilities with this change we will use SET since it is the
most widely used command returning +OK:

  $response = $client->set('foo', 'bar');

  echo $response;         // 'OK'
  $response == 'OK';      // TRUE
  isset($response->ok);   // TRUE
  $response == true;      // TRUE
  $response === true;     // FALSE
  $response instanceof Predis\Response\ObjectInterface;     // TRUE
  $response instanceof Predis\Response\Status;              // TRUE

For those checking responses returned by commands such as SET or PONG,
the breaking change basically lies in the usage of strict comparison:
doing $response === true will now evaluate to FALSE instead of TRUE.

By default Predis caches common status responses such as OK or QUEUED
to lower the memory usage when using pipelines or transactions.
2013-12-07 15:15:23 +01:00
Daniele Alessandri bcf92a7548 [tests] Fix tests under PHP 5.3 due to another dumb mistake.
Seriously, I am startint to hate PHP 5.3...
2013-12-01 15:27:42 +01:00
Daniele Alessandri 583b924085 Add the ability for the client to send raw commands to Redis.
When sending raw commands their arguments are not filtered, responses
are not parsed and key prefixes are not applied. The client also does
not throw any exception on Redis errors regardless of its settings.

The first parameter takes the raw arguments of the command (included
its identifier) as defined by the Redis documentation while the second
optional parameter is always populated by reference to indicate when
Redis actually returned an error response.

  $client->raw(['PING']);                // "PONG"
  $client->raw(['SET','foo','bar']);     // "OK"
  $client->raw(['GET','foo'], $err);     // "bar", $err=FALSE
  $client->raw(['LPUSH','foo',1], $err); // "WRONGTYPE...", $err=TRUE

Internally, this method creates instances of Predis\Command\RawCommand
that get passed to the underlying connection instance for execution as
if they were usual commands defined by Predis.

Raw commands work in both cluster and replication scenarios since they
are recognized by their command ID, but key prefixing is not supported
since it is done by the profile instance when instantiating commands.
2013-12-01 13:42:03 +01:00
Daniele Alessandri e049db124c By convention all of the Redis command identifiers are uppercase. 2013-12-01 10:45:37 +01:00
Daniele Alessandri b253bdc41e [tests] Improve the basic framework of our test suite.
We now have a base test case class for Predis (namely PredisTestCase)
grouping various commonly used utility methods shared by all of the
tests in the suite, greatly improving reusability.
2013-11-30 19:38:27 +01:00
Daniele Alessandri 09895f27bf Rename command class for scripting to Predis\Command\ScriptCommand.
We also changed our wording to indentify this kind of abstraction so
instead of using "scripted commands" (kind of broken English) we now
use "scriptable commands".
2013-11-30 12:43:21 +01:00
Daniele Alessandri 2a5483df90 Reorganize the Predis\Profile namespace.
The profile factory code has been extrapolated into a the new class
Predis\Profile\Factory (final and with only static methods).
2013-11-22 12:01:29 +01:00
Daniele Alessandri 712e6420e9 Rewrite parts of Predis\Transaction\MultiExec to make them less ugly.
We also changed some options for this class, the accepted ones are:

  - "keys": string or array of strings for automatic WATCH.
  - "cas": sets the check-and-set mode.
  - "retry": number of attempts before giving up aborted transactions.
  - "exceptions": sets whether exceptions should be thrown on error
    responses (overrides the "exceptions" client option).

The "on_retry" option has been removed.
2013-11-17 15:57:43 +01:00
Daniele Alessandri 3d499e82a3 Add some supported options to Predis\Client::pipeline().
Only two options available for now, used to specify which kind of
pipeline object the client should use or return:

  - "atomic": returns a pipeline wrapped in a MULTI / EXEC transaction
    (class: Predis\Pipeline\Atomic).
  - "fire-and-forget": returns a pipeline that does not read back
    responses from the server (class: Predis\Pipeline\FireAndForget).

We might add more options in the future.
2013-11-16 21:54:17 +01:00
Daniele Alessandri 8068c87e47 Rewrite a good chunk of the classes in the Predis\Pipeline namespace.
First of all we completely removed the concept of pipeline executors.
Now pipelines can be easily customized by extending our default class
Predis\Pipeline\Pipeline.

Tests coverage for the Predis\Pipeline namespace is decent but can be
definitely improved while test cases can be beautified.
2013-11-16 21:23:49 +01:00
Daniele Alessandri c6f51e82bf Rename "Array" type-hint to to "array". 2013-11-16 17:01:58 +01:00
Daniele Alessandri aaac082324 Rename classes in Predis\Transaction. 2013-11-16 16:34:34 +01:00
Daniele Alessandri 9d2cb975eb Rename classes in Predis\Monitor namespace. 2013-11-16 15:42:56 +01:00
Daniele Alessandri c3a58dffdf Rename classes in the Predis\PubSub namespace. 2013-11-16 15:27:58 +01:00