1 <?php
  2 
  3   4   5   6   7   8   9  10 
 11 
 12 namespace ICanBoogie\ActiveRecord;
 13 
 14 use ICanBoogie\PropertyNotDefined;
 15 
 16  17  18  19  20  21 
 22 class Connections implements \ArrayAccess, \IteratorAggregate
 23 {
 24      25  26  27  28 
 29     private $definitions;
 30 
 31      32  33  34  35 
 36     private $established = [];
 37 
 38      39  40  41  42 
 43     public function __construct(array $definitions)
 44     {
 45         foreach ($definitions as $id => $definition)
 46         {
 47             $this[$id] = $definition;
 48         }
 49     }
 50 
 51      52  53  54  55  56  57 
 58     public function __get($property)
 59     {
 60         switch ($property)
 61         {
 62             case 'definitions': return $this->definitions;
 63             case 'established': return $this->established;
 64         }
 65 
 66         throw new PropertyNotDefined([ $property, $this ]);
 67     }
 68 
 69      70  71 
 72     public function offsetExists($id)
 73     {
 74         return isset($this->definitions[$id]);
 75     }
 76 
 77      78  79  80  81  82 
 83     public function offsetSet($id, $definition)
 84     {
 85         if (isset($this->established[$id]))
 86         {
 87             throw new ConnectionAlreadyEstablished($id);
 88         }
 89 
 90         if (is_string($definition))
 91         {
 92             $definition = [ 'dsn' => $definition ];
 93         }
 94 
 95         if (empty($definition['dsn']))
 96         {
 97             throw new \InvalidArgumentException("<q>dsn</q> is empty or not defined.");
 98         }
 99 
100         $this->definitions[$id] = $definition;
101     }
102 
103     104 105 106 
107     public function offsetUnset($id)
108     {
109         if (isset($this->established[$id]))
110         {
111             throw new ConnectionAlreadyEstablished($id);
112         }
113 
114         unset($this->definitions[$id]);
115     }
116 
117     118 119 120 121 122 123 124 125 126 127 128 
129     public function offsetGet($id)
130     {
131         if (isset($this->established[$id]))
132         {
133             return $this->established[$id];
134         }
135 
136         if (!$this->offsetExists($id))
137         {
138             throw new ConnectionNotDefined($id);
139         }
140 
141         $options = $this->definitions[$id] + [
142 
143             'dsn' => null,
144             'username' => 'root',
145             'password' => null
146         ];
147 
148         $options['options'][Connection::ID] = $id;
149 
150         
151         
152         
153         
154 
155         try
156         {
157             return $this->established[$id] = new Connection($options['dsn'], $options['username'], $options['password'], $options['options']);
158         }
159         catch (\PDOException $e)
160         {
161             throw new ConnectionNotEstablished("Connection not established: " . $e->getMessage() . ".", 500, $e);
162         }
163     }
164 
165     166 167 
168     public function getIterator()
169     {
170         return new \ArrayIterator($this->established);
171     }
172 }
173 
174 175 176 
177 
178 179 180 
181 class ConnectionNotDefined extends ActiveRecordException
182 {
183     public function __construct($id, $code=500, \Exception $previous=null)
184     {
185         parent::__construct("Connection not defined: {$id}.", $code, $previous);
186     }
187 }
188 
189 190 191 
192 class ConnectionNotEstablished extends ActiveRecordException
193 {
194 
195 }
196 
197 198 199 
200 class ConnectionAlreadyEstablished extends ActiveRecordException
201 {
202     public function __construct($id, $code=500, \Exception $previous=null)
203     {
204         parent::__construct("Connection already established: {$id}.", $code, $previous);
205     }
206 }