1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: class NSqliteDriver extends NObject implements ISupplementalDriver
22: {
23:
24: private $connection;
25:
26:
27: private $fmtDateTime;
28:
29:
30:
31: public function __construct(NConnection $connection, array $options)
32: {
33: $this->connection = $connection;
34: $this->fmtDateTime = isset($options['formatDateTime']) ? $options['formatDateTime'] : 'U';
35:
36: }
37:
38:
39:
40:
41:
42:
43:
44: 45: 46:
47: public function delimite($name)
48: {
49: return '[' . strtr($name, '[]', ' ') . ']';
50: }
51:
52:
53:
54: 55: 56:
57: public function formatBool($value)
58: {
59: return $value ? '1' : '0';
60: }
61:
62:
63:
64: 65: 66:
67: public function formatDateTime(DateTime $value)
68: {
69: return $value->format($this->fmtDateTime);
70: }
71:
72:
73:
74: 75: 76:
77: public function formatLike($value, $pos)
78: {
79: $value = addcslashes(substr($this->connection->quote($value), 1, -1), '%_\\');
80: return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'") . " ESCAPE '\\'";
81: }
82:
83:
84:
85: 86: 87:
88: public function applyLimit(&$sql, $limit, $offset)
89: {
90: if ($limit >= 0 || $offset > 0) {
91: $sql .= ' LIMIT ' . $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
92: }
93: }
94:
95:
96:
97: 98: 99:
100: public function normalizeRow($row, $statement)
101: {
102: return $row;
103: }
104:
105:
106:
107:
108:
109:
110:
111: 112: 113:
114: public function getTables()
115: {
116: return $this->connection->query("
117: SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view')
118: UNION ALL
119: SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view')
120: ORDER BY name
121: ")->fetchAll();
122: }
123:
124:
125:
126: 127: 128:
129: public function getColumns($table)
130: {
131: $meta = $this->connection->query("
132: SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->connection->quote($table)}
133: UNION ALL
134: SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->connection->quote($table)}
135: ")->fetch();
136:
137: $columns = array();
138: foreach ($this->connection->query("PRAGMA table_info({$this->delimite($table)})") as $row) {
139: $column = $row['name'];
140: $pattern = "/(\"$column\"|\[$column\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";
141: $type = explode('(', $row['type']);
142: $columns[] = array(
143: 'name' => $column,
144: 'table' => $table,
145: 'fullname' => "$table.$column",
146: 'nativetype' => strtoupper($type[0]),
147: 'size' => isset($type[1]) ? (int) $type[1] : NULL,
148: 'nullable' => $row['notnull'] == '0',
149: 'default' => $row['dflt_value'],
150: 'autoincrement' => (bool) preg_match($pattern, $meta['sql']),
151: 'primary' => $row['pk'] == '1',
152: 'vendor' => (array) $row,
153: );
154: }
155: return $columns;
156: }
157:
158:
159:
160: 161: 162:
163: public function getIndexes($table)
164: {
165: $indexes = array();
166: foreach ($this->connection->query("PRAGMA index_list({$this->delimite($table)})") as $row) {
167: $indexes[$row['name']]['name'] = $row['name'];
168: $indexes[$row['name']]['unique'] = (bool) $row['unique'];
169: }
170:
171: foreach ($indexes as $index => $values) {
172: $res = $this->connection->query("PRAGMA index_info({$this->delimite($index)})");
173: while ($row = $res->fetch(TRUE)) {
174: $indexes[$index]['columns'][$row['seqno']] = $row['name'];
175: }
176: }
177:
178: $columns = $this->getColumns($table);
179: foreach ($indexes as $index => $values) {
180: $column = $indexes[$index]['columns'][0];
181: $primary = FALSE;
182: foreach ($columns as $info) {
183: if ($column == $info['name']) {
184: $primary = $info['primary'];
185: break;
186: }
187: }
188: $indexes[$index]['primary'] = (bool) $primary;
189: }
190: if (!$indexes) {
191: foreach ($columns as $column) {
192: if ($column['vendor']['pk']) {
193: $indexes[] = array(
194: 'name' => 'ROWID',
195: 'unique' => TRUE,
196: 'primary' => TRUE,
197: 'columns' => array($column['name']),
198: );
199: break;
200: }
201: }
202: }
203:
204: return array_values($indexes);
205: }
206:
207:
208:
209: 210: 211:
212: public function getForeignKeys($table)
213: {
214: $keys = array();
215: foreach ($this->connection->query("PRAGMA foreign_key_list({$this->delimite($table)})") as $row) {
216: $keys[$row['id']]['name'] = $row['id'];
217: $keys[$row['id']]['local'][$row['seq']] = $row['from'];
218: $keys[$row['id']]['table'] = $row['table'];
219: $keys[$row['id']]['foreign'][$row['seq']] = $row['to'];
220: $keys[$row['id']]['onDelete'] = $row['on_delete'];
221: $keys[$row['id']]['onUpdate'] = $row['on_update'];
222:
223: if ($keys[$row['id']]['foreign'][0] == NULL) {
224: $keys[$row['id']]['foreign'] = NULL;
225: }
226: }
227: return array_values($keys);
228: }
229:
230:
231:
232: 233: 234:
235: public function isSupported($item)
236: {
237: return FALSE;
238: }
239:
240: }
241: