1: <?php
2: 3: 4: 5: 6:
7:
8: namespace Ark\Database;
9:
10: 11: 12:
13: class Connection
14: {
15: 16: 17: 18:
19: protected $current = null;
20: protected $connections = [];
21: protected $configs = [];
22:
23: 24: 25: 26: 27: 28: 29:
30: public function __construct($dsn = null, $username = null, $password = null, $options = array()){
31: $this->addConnection('default', $dsn, $username, $password, $options);
32: }
33:
34: 35: 36: 37:
38: public function isAutoSlave() {
39: return (!empty($this->configs['default']['options']['auto_slave'])) && isset($this->configs['slave']) && ($this->current === null);
40: }
41:
42: 43: 44: 45: 46:
47: public function getConfig($name = null){
48: if(null === $name){
49: $name = $this->current?:'default';
50: }
51: return $this->configs[$name];
52: }
53:
54: 55: 56: 57: 58:
59: public function getPDO($name = null){
60: if(null === $name){
61: $name = $this->current?:'default';
62: }
63: if(!isset($this->connections[$name])){
64: $config = $this->configs[$name];
65: $this->connections[$name] = new \PDO($config['dsn'], $config['username'], $config['password'], $config['options']);
66: }
67:
68: return $this->connections[$name];
69: }
70:
71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
81: public function addConnection($name, $dsn, $username = null, $password = null, $options = []){
82:
83: static $defaultOptions = array(
84: \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
85:
86: );
87: if(isset($options['prefix'])){
88: $prefix = $options['prefix'];
89: unset($options['prefix']);
90: }
91: else{
92: $prefix = '';
93: }
94: $this->configs[$name] = [
95: 'dsn' => $dsn,
96: 'username' => $username,
97: 'password' => $password,
98: 'prefix' => $prefix,
99: 'options' => $options + $defaultOptions,
100: ];
101:
102: return $this;
103: }
104:
105: 106: 107: 108: 109:
110: public function switchConnection($name = null){
111: $this->current = $name;
112:
113: return $this;
114: }
115:
116: 117: 118: 119: 120: 121:
122: public function factory($model){
123: return new ModelFactory($this, $model);
124: }
125:
126: 127: 128: 129: 130:
131: public function builder(){
132: return new QueryBuilder($this);
133: }
134:
135: 136: 137:
138: public function getAttribute($attribute){
139: return $this->getPDO()->getAttribute($attribute);
140: }
141:
142: 143: 144:
145: public function setAttribute($attribute, $value){
146: return $this->getPDO()->setAttribute($attribute, $value);
147: }
148:
149: 150: 151:
152: public function prepare(){
153: return call_user_func_array(array($this->getPDO(), 'prepare'), func_get_args());
154: }
155:
156: 157: 158:
159: public function query(){
160: return call_user_func_array(array($this->getPDO(), 'query'), func_get_args());
161: }
162:
163: 164: 165:
166: public function exec(){
167: return call_user_func_array(array($this->getPDO(), 'exec'), func_get_args());
168: }
169:
170: 171: 172:
173: public function beginTransaction(){
174: return $this->getPDO()->beginTransaction();
175: }
176:
177: 178: 179:
180: public function rollBack(){
181: return $this->getPDO()->rollBack();
182: }
183:
184: 185: 186:
187: public function commit(){
188: return $this->getPDO()->commit();
189: }
190:
191: 192: 193:
194: public function inTransaction(){
195: return $this->getPDO()->inTransaction();
196: }
197:
198: 199: 200:
201: public function lastInsertId(){
202: return call_user_func_array(array($this->getPDO(), 'lastInsertId'), func_get_args());
203: }
204:
205: 206: 207:
208: public function quote(){
209: return call_user_func_array(array($this->getPDO(), 'quote'), func_get_args());
210: }
211:
212: public function errorCode(){
213: return call_user_func_array(array($this->getPDO(), 'errorCode'), func_get_args());
214: }
215:
216: public function errorInfo(){
217: return call_user_func_array(array($this->getPDO(), 'errorInfo'), func_get_args());
218: }
219:
220: 221: 222: 223: 224:
225: public function quoteTable($name){
226: return $this->quoteIdentifier($name);
227: }
228:
229: 230: 231: 232: 233:
234: public function quoteColumn($name){
235: return $this->quoteIdentifier($name);
236: }
237:
238: 239: 240: 241: 242:
243: public function quoteIdentifier($name){
244: $quote = null;
245: switch($this->getAttribute(\PDO::ATTR_DRIVER_NAME)){
246: case 'pgsql':
247: case 'sqlsrv':
248: case 'dblib':
249: case 'mssql':
250: case 'sybase':
251: $quote = '"';
252: break;
253: case 'mysql':
254: case 'sqlite':
255: case 'sqlite2':
256: default:
257: $quote = '`';
258: }
259:
260: $parts = explode('.', $name);
261: foreach($parts as $k => $part){
262: if($part !== '*'){
263: $parts[$k] = $quote.$part.$quote;
264: }
265: }
266:
267: return implode('.', $parts);
268: }
269:
270: public function buildLimitOffset($sql, $limit, $offset = 0){
271: switch($this->getAttribute(\PDO::ATTR_DRIVER_NAME)){
272: case 'sqlsrv':
273: case 'dblib':
274: case 'mssql':
275: case 'sybase':
276: throw new Exception('Limit/offset not implemented yet');
277: case 'pgsql':
278: case 'mysql':
279: case 'sqlite':
280: case 'sqlite2':
281: default:
282: if($limit > 0){
283: $sql .= "\n LIMIT ".$limit;
284: }
285: if($offset > 0){
286: $sql .= " OFFSET ".$offset;
287: }
288:
289: return $sql;
290: }
291: }
292:
293: public function getPrefix(){
294: return $this->configs[$this->current?:'default']['prefix'];
295: }
296:
297: public function fixPrefix($sql){
298:
299: }
300: }
301: