1: <?php
2:
3: namespace zsql;
4:
5: /**
6: * Import classes from the global namespace
7: */
8: use \mysqli;
9: use \mysqli_result;
10:
11: class Database
12: {
13: /**
14: * @var integer
15: */
16: protected $affectedRows;
17:
18: /**
19: * @var mysqli
20: */
21: protected $connection;
22:
23: /**
24: * @var integer
25: */
26: protected $insertId;
27:
28: /**
29: * Holds the total number of queries ran for the database object's lifetime.
30: *
31: * @var integer
32: */
33: protected $queryCount = 0;
34:
35: /**
36: * Construct a new database object.
37: *
38: * @param \mysqli $connection
39: */
40: public function __construct(mysqli $connection)
41: {
42: $this->setConnection($connection);
43: }
44:
45: /**
46: * Close the mysql connection on destruct
47: */
48: public function __destruct()
49: {
50: if( $this->getConnection() ) {
51: $this->getConnection()->close();
52: }
53: }
54:
55: /**
56: * Get affected rows
57: *
58: * @return integer
59: */
60: public function getAffectedRows()
61: {
62: return $this->affectedRows;
63: }
64:
65: /**
66: * Exposes the local connection object
67: *
68: * @return \mysqli
69: */
70: public function getConnection()
71: {
72: return $this->connection;
73: }
74:
75: /**
76: * Sets the local mysqli object
77: *
78: * @param \mysqli $connection
79: * @return \zsql\Database
80: */
81: public function setConnection(mysqli $connection = null)
82: {
83: $this->connection = $connection;
84: return $this;
85: }
86:
87: /**
88: * Get the last insert ID
89: *
90: * @return integer
91: */
92: public function getInsertId()
93: {
94: return $this->insertId;
95: }
96:
97: /**
98: * Gets number of queries run using this adapter.
99: *
100: * @return integer
101: */
102: public function getQueryCount()
103: {
104: return $this->queryCount;
105: }
106:
107: /**
108: * Wrapper for \zsql\Select
109: *
110: * @return \zsql\Select
111: */
112: public function select()
113: {
114: return new Select($this);
115: }
116:
117: /**
118: * Wrapper for \zsql\Insert
119: *
120: * @return \zsql\Insert
121: */
122: public function insert()
123: {
124: return new Insert($this);
125: }
126:
127: /**
128: * Wrapper for \zsql\Update
129: *
130: * @return \zsql\Update
131: */
132: public function update()
133: {
134: return new Update($this);
135: }
136:
137: /**
138: * Wrapper for \zsql\Delete
139: *
140: * @return \zsql\Delete
141: */
142: public function delete()
143: {
144: return new Delete($this);
145: }
146:
147: /**
148: * Executes an SQL query
149: *
150: * @param string|\zsql\Query $query
151: * @param string $resultmode
152: * @return \Engine\Database\Result|mixed
153: */
154: public function query($query, $resultmode = MYSQLI_STORE_RESULT)
155: {
156: $connection = $this->getConnection();
157:
158: $this->affectedRows = null;
159: $this->insertId = null;
160: $this->queryCount++;
161:
162: $queryString = (string) $query;
163: $ret = $connection->query($queryString, $resultmode);
164:
165: // Save insert ID if instance of insert
166: if( $query instanceof \zsql\Insert ) {
167: $this->insertId = $connection->insert_id;
168: }
169:
170: // Save affected rows
171: $this->affectedRows = $connection->affected_rows;
172:
173: // Handle result
174: if( $ret !== false ) {
175: // Select -> \zsql\Result
176: // Insert -> insertId OR true
177: // Update/Delete -> affectedRows
178: if( $ret instanceof mysqli_result ) {
179: // handle mysqli_result object
180: return new Result($ret);
181: } else if( $query instanceof \zsql\Insert ) {
182: return $this->getInsertId();
183: } else if( $query instanceof \zsql\Update ||
184: $query instanceof \zsql\Delete ) {
185: return $this->getAffectedRows();
186: }
187: // Should never get to this line
188: } else {
189: // Query failed, throw exception
190: throw new Exception(sprintf("%s: %s\n%s",
191: $connection->errno, $connection->error, $query));
192: }
193: }
194:
195: /**
196: * Quote a raw string
197: *
198: * @param string $value
199: * @return string
200: */
201: public function quote($value)
202: {
203: if( null === $value ) {
204: return 'NULL';
205: } else if( is_bool($value) ) {
206: return ( $value ? '1' : '0' );
207: } else if( $value instanceof Expression ) {
208: return (string) $value;
209: } else if( is_integer($value) ) {
210: return sprintf('%d', $value);
211: } else if( is_float($value) ) {
212: return sprintf('%f', $value); // @todo make sure precision is right
213: } else {
214: return "'" . $this->getConnection()->real_escape_string($value) . "'";
215: }
216: }
217: }
218: