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 }