Browse Source

Initial support for optional parameters when creating a Client instance. Optional authorization and database selection are now performed automatically upon connection.

Daniele Alessandri 15 years ago
parent
commit
6df1d02e4c

+ 1 - 1
README.markdown

@@ -54,7 +54,7 @@ Furthermore, a pipeline can be initialized on a cluster of redis instances in th
 same exact way they are created on single connection. Sharding is still transparent 
 same exact way they are created on single connection. Sharding is still transparent 
 to the user:
 to the user:
 
 
-    $redis = Predis\Client::createCluster(
+    $redis = Predis\Client::create(
         array('host' => '10.0.0.1', 'port' => 6379),
         array('host' => '10.0.0.1', 'port' => 6379),
         array('host' => '10.0.0.2', 'port' => 6379)
         array('host' => '10.0.0.2', 'port' => 6379)
     );
     );

+ 1 - 2
examples/CommandPipeline.php

@@ -4,8 +4,7 @@ require_once 'SharedConfigurations.php';
 // when you have a whole set of consecutive commands to send to 
 // when you have a whole set of consecutive commands to send to 
 // a redis server, you can use a pipeline to improve performances.
 // a redis server, you can use a pipeline to improve performances.
 
 
-$redis = new Predis\Client(REDIS_HOST, REDIS_PORT);
-$redis->select(REDIS_DB);
+$redis = Predis\Client::create($configurations);
 
 
 $replies = $redis->pipeline(function($pipe) {
 $replies = $redis->pipeline(function($pipe) {
     $pipe->ping();
     $pipe->ping();

+ 1 - 2
examples/MultipleSetAndGet.php

@@ -11,8 +11,7 @@ $mkv = array(
     'usr:0003' => 'Third user' 
     'usr:0003' => 'Third user' 
 );
 );
 
 
-$redis = new Predis\Client(REDIS_HOST, REDIS_PORT);
-$redis->select(REDIS_DB);
+$redis = Predis\Client::create($configurations);
 
 
 $redis->mset($mkv);
 $redis->mset($mkv);
 $retval = $redis->mget(array_keys($mkv));
 $retval = $redis->mget(array_keys($mkv));

+ 5 - 3
examples/SharedConfigurations.php

@@ -1,7 +1,9 @@
 <?php
 <?php
 require_once '../lib/Predis.php';
 require_once '../lib/Predis.php';
 
 
-const REDIS_HOST = '127.0.0.1';
-const REDIS_PORT = 6379;
-const REDIS_DB   = 15;
+$configurations = array(
+    'host'     => '127.0.0.1', 
+    'port'     => 6379, 
+    'database' => 15
+);
 ?>
 ?>

+ 1 - 2
examples/SimpleSetAndGet.php

@@ -3,8 +3,7 @@ require_once 'SharedConfigurations.php';
 
 
 // simple set and get scenario
 // simple set and get scenario
 
 
-$redis = new Predis\Client(REDIS_HOST, REDIS_PORT);
-$redis->select(REDIS_DB);
+$redis = Predis\Client::create($configurations);
 
 
 $redis->set('library', 'predis');
 $redis->set('library', 'predis');
 $retval = $redis->get('library');
 $retval = $redis->get('library');

+ 93 - 6
lib/Predis.php

@@ -25,16 +25,85 @@ class Client {
         $this->_connection->disconnect();
         $this->_connection->disconnect();
     }
     }
 
 
-    public static function createCluster(/* arguments */) {
-        $cluster = new ConnectionCluster();
-        foreach (func_get_args() as $parameters) {
-            $cluster->add(new Connection($parameters['host'], $parameters['port']));
-        }
+    public static function create(/* arguments */) {
+        $argv = func_get_args();
+        $argc = func_num_args();
+
         $client = new Client();
         $client = new Client();
-        $client->setConnection($cluster);
+
+        if ($argc == 1) {
+            $client->setConnection($client->createConnection($argv[0]));
+        }
+        else if ($argc > 1) {
+            $cluster = new ConnectionCluster();
+            foreach ($argv as $parameters) {
+                $cluster->add($client->createConnection($parameters));
+            }
+            $client->setConnection($cluster);
+        }
+
         return $client;
         return $client;
     }
     }
 
 
+    private static function parseURI($uri) {
+        $parsed = @parse_url($uri);
+
+        if ($parsed == false || $parsed['scheme'] != 'redis' || $parsed['host'] == null) {
+            throw new ClientException("Invalid URI: $uri");
+        }
+
+        $details = array();
+        foreach (explode('&', $parsed['query']) as $kv) {
+            list($k, $v) = explode('=', $kv);
+            switch ($k) {
+                case 'database':
+                    $details['database'] = $v;
+                    break;
+                case 'password':
+                    $details['password'] = $v;
+                    break;
+            }
+        }
+
+        return self::filterConnectionParams(array_merge($parsed, $details));
+    }
+
+    private static function filterConnectionParams($parameters) {
+        return array(
+            'host' => $parameters['host'] != null 
+                ? $parameters['host'] 
+                : Connection::DEFAULT_HOST, 
+            'port' => $parameters['port'] != null 
+                ? (int) $parameters['port'] 
+                : Connection::DEFAULT_PORT, 
+            'database' => $parameters['database'], 
+            'password' => $parameters['password'], 
+        );
+    }
+
+    private function createConnection($connectionDetails) {
+        $parameters = is_array($connectionDetails) 
+            ? self::filterConnectionParams($connectionDetails) 
+            : self::parseURI($connectionDetails);
+
+        $connection = new Connection($parameters['host'], $parameters['port']);
+
+        if ($parameters['password'] !== null) {
+            $connection->pushInitCommand($this->createCommandInstance(
+                'auth', 
+                array($parameters['password'])
+            ));
+        }
+        if ($parameters['database'] !== null) {
+            $connection->pushInitCommand($this->createCommandInstance(
+                'select', 
+                array($parameters['database'])
+            ));
+        }
+
+        return $connection;
+    }
+
     private function setConnection(IConnection $connection) {
     private function setConnection(IConnection $connection) {
         $this->_connection = $connection;
         $this->_connection = $connection;
     }
     }
@@ -534,6 +603,7 @@ class Connection implements IConnection {
     public function __construct($host = self::DEFAULT_HOST, $port = self::DEFAULT_PORT) {
     public function __construct($host = self::DEFAULT_HOST, $port = self::DEFAULT_PORT) {
         $this->_host = $host;
         $this->_host = $host;
         $this->_port = $port;
         $this->_port = $port;
+        $this->_initCmds = array();
     }
     }
 
 
     public function __destruct() {
     public function __destruct() {
@@ -554,6 +624,10 @@ class Connection implements IConnection {
             throw new ClientException(trim($errstr), $errno);
             throw new ClientException(trim($errstr), $errno);
         }
         }
         stream_set_timeout($this->_socket, self::READ_WRITE_TIMEOUT);
         stream_set_timeout($this->_socket, self::READ_WRITE_TIMEOUT);
+
+        if (count($this->_initCmds) > 0){
+            $this->sendInitializationCommands();
+        }
     }
     }
 
 
     public function disconnect() {
     public function disconnect() {
@@ -562,6 +636,19 @@ class Connection implements IConnection {
         }
         }
     }
     }
 
 
+    public function pushInitCommand(Command $command){
+        $this->_initCmds[] = $command;
+    }
+
+    private function sendInitializationCommands() {
+        foreach ($this->_initCmds as $command) {
+            $this->writeCommand($command);
+        }
+        foreach ($this->_initCmds as $command) {
+            $this->readResponse($command);
+        }
+    }
+
     public function writeCommand(Command $command) {
     public function writeCommand(Command $command) {
         fwrite($this->getSocket(), $command());
         fwrite($this->getSocket(), $command());
     }
     }