]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/schema.php
use schema tool to create a table
[quix0rs-gnu-social.git] / lib / schema.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Database schema utilities
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Database
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @copyright 2009 StatusNet, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET')) {
31     exit(1);
32 }
33
34 /**
35  * Class representing the database schema
36  *
37  * A class representing the database schema. Can be used to
38  * manipulate the schema -- especially for plugins and upgrade
39  * utilities.
40  *
41  * @category Database
42  * @package  StatusNet
43  * @author   Evan Prodromou <evan@status.net>
44  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
45  * @link     http://status.net/
46  */
47
48 class Schema
49 {
50     static $_single = null;
51     protected $conn = null;
52
53     protected function __construct()
54     {
55         // XXX: there should be an easier way to do this.
56         $user = new User();
57         $this->conn = $user->getDatabaseConnection();
58         $user->free();
59         unset($user);
60     }
61
62     static function get()
63     {
64         if (empty(self::$_single)) {
65             self::$_single = new Schema();
66         }
67         return self::$_single;
68     }
69
70     public function getTableDef($name)
71     {
72         $res =& $this->conn->query('DESCRIBE ' . $name);
73
74         if (PEAR::isError($res)) {
75             throw new Exception($res->getMessage());
76         }
77
78         $td = new TableDef();
79
80         $td->name    = $name;
81         $td->columns = array();
82
83         $row = array();
84
85         while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) {
86
87             $cd = new ColumnDef();
88
89             $cd->name = $row['Field'];
90
91             $packed = $row['Type'];
92
93             if (preg_match('/^(\w+)\((\d+)\)$/', $packed, $match)) {
94                 $cd->type = $match[1];
95                 $cd->size = $match[2];
96             } else {
97                 $cd->type = $packed;
98             }
99
100             $cd->nullable = ($row['Null'] == 'YES') ? true : false;
101             $cd->key      = $row['Key'];
102             $cd->default  = $row['Default'];
103             $cd->extra    = $row['Extra'];
104
105             $td->columns[] = $cd;
106         }
107
108         return $td;
109     }
110
111     public function getColumnDef($table, $column)
112     {
113         $td = $this->getTableDef($table);
114
115         foreach ($td->columns as $cd) {
116             if ($cd->name == $column) {
117                 return $cd;
118             }
119         }
120
121         return null;
122     }
123
124     public function getIndexDef($table, $index)
125     {
126         return null;
127     }
128
129     public function createTable($name, $columns, $indices=null)
130     {
131         $uniques = array();
132         $primary = array();
133         $indices = array();
134
135         $sql = "CREATE TABLE $name (\n";
136
137         for ($i = 0; $i < count($columns); $i++) {
138
139             $cd =& $columns[$i];
140
141             if ($i > 0) {
142                 $sql .= ",\n";
143             }
144
145             $sql .= $this->_columnSql($cd);
146
147             switch ($cd->key) {
148              case 'UNI':
149                 $uniques[] = $cd->name;
150                 break;
151              case 'PRI':
152                 $primary[] = $cd->name;
153                 break;
154              case 'MUL':
155                 $indices[] = $cd->name;
156                 break;
157             }
158         }
159
160         if (count($primary) > 0) { // it really should be...
161             $sql .= ",\nconstraint primary key (" . implode(',', $primary) . ")";
162         }
163
164         foreach ($uniques as $u) {
165             $sql .= ",\nunique index {$name}_{$u}_idx ($u)";
166         }
167
168         foreach ($indices as $i) {
169             $sql .= ",\nindex {$name}_{$i}_idx ($i)";
170         }
171
172         $sql .= "); ";
173
174         common_debug($sql);
175
176         $res =& $this->conn->query($sql);
177
178         if (PEAR::isError($res)) {
179             throw new Exception($res->getMessage());
180         }
181
182         return true;
183     }
184
185     public function dropTable($name)
186     {
187         $res =& $this->conn->query("DROP TABLE $name");
188
189         if (PEAR::isError($res)) {
190             throw new Exception($res->getMessage());
191         }
192
193         return true;
194     }
195
196     public function createIndex($name, $table, $columns)
197     {
198     }
199
200     public function dropIndex($name, $table)
201     {
202     }
203
204     public function addColumn($table, $columndef)
205     {
206     }
207
208     public function modifyColumn($table, $column, $columndef)
209     {
210     }
211
212     public function dropColumn($table, $column)
213     {
214     }
215
216     public function ensureTable($name, $columns, $indices)
217     {
218         $def = $this->tableDef($name);
219         if (empty($def)) {
220             return $this->createTable($name, $columns, $indices);
221         }
222     }
223
224     function _columnSql($cd)
225     {
226         $sql = "{$cd->name} ";
227
228         if (!empty($cd->size)) {
229             $sql .= "{$cd->type}({$cd->size}) ";
230         } else {
231             $sql .= "{$cd->type} ";
232         }
233
234         if (!empty($cd->default)) {
235             $sql .= "default {$cd->default} ";
236         } else {
237             $sql .= ($cd->nullable) ? "null " : "not null ";
238         }
239
240         return $sql;
241     }
242 }
243
244 class TableDef
245 {
246     public $name;
247     public $columns;
248 }
249
250 class ColumnDef
251 {
252     public $name;
253     public $type;
254     public $size;
255     public $nullable;
256     public $key;
257     public $default;
258     public $extra;
259
260     function __construct($name, $type, $size=null, $nullable=null,
261                          $key=null, $default=null, $extra=null) {
262         $this->name     = $name;
263         $this->type     = $type;
264         $this->size     = $size;
265         $this->nullable = $nullable;
266         $this->key      = $key;
267         $this->default  = $default;
268         $this->extra    = $extra;
269     }
270 }
271
272 class IndexDef
273 {
274     public $name;
275     public $table;
276     public $columns;
277 }