|
@@ -2,6 +2,8 @@
|
2
|
2
|
|
3
|
3
|
namespace Luticate\Generator;
|
4
|
4
|
|
|
5
|
+use Luticate\Utils\DataAccess\AbstractDbDataAccess;
|
|
6
|
+use Luticate\Utils\DataAccess\PgSqlDataAccess;
|
5
|
7
|
use PDO;
|
6
|
8
|
use Twig_Autoloader;
|
7
|
9
|
use Twig_Environment;
|
|
@@ -58,17 +60,16 @@ class LuGenerator {
|
58
|
60
|
$this->_config = $config;
|
59
|
61
|
}
|
60
|
62
|
|
61
|
|
- public function __construct()
|
|
63
|
+ public function __construct($database)
|
62
|
64
|
{
|
63
|
|
- $dsn = getenv("DB_CONNECTION") . ":dbname=" . getenv("DB_DATABASE") . ";host="
|
64
|
|
- . getenv("DB_HOST") . ";port=" . getenv("DB_PORT");
|
65
|
|
- $this->_pdo = new PDO($dsn, getenv("DB_USERNAME"), getenv("DB_PASSWORD"));
|
|
65
|
+ $dsn = $database["driver"] . ":dbname=" . $database["database"] . ";host="
|
|
66
|
+ . $database["host"] . ";port=" . $database["port"];
|
|
67
|
+ $this->_pdo = new PDO($dsn, $database["username"], $database["password"]);
|
66
|
68
|
}
|
67
|
69
|
|
68
|
|
- protected function printError($query, $message)
|
|
70
|
+ protected function printError($message)
|
69
|
71
|
{
|
70
|
72
|
echo $message . "\n";
|
71
|
|
- var_dump($query->errorInfo());
|
72
|
73
|
var_dump($this->_pdo->errorInfo());
|
73
|
74
|
return null;
|
74
|
75
|
}
|
|
@@ -108,60 +109,15 @@ class LuGenerator {
|
108
|
109
|
$content = $template->render($twig_vars);
|
109
|
110
|
file_put_contents($destFile, $content);
|
110
|
111
|
}
|
111
|
|
-
|
112
|
|
- public function getTables()
|
113
|
|
- {
|
114
|
|
- $tablesQuery = $this->_pdo->prepare("SELECT table_name
|
115
|
|
-FROM information_schema.tables
|
116
|
|
-WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema')");
|
117
|
|
- if ($tablesQuery->execute(array())) {
|
118
|
|
- $tables = $tablesQuery->fetchAll();
|
119
|
|
- echo "Found " . count($tables) . " tables\n";
|
120
|
|
- return $tables;
|
121
|
|
- }
|
122
|
|
- else
|
123
|
|
- return $this->printError($tablesQuery, "Failed to get tables");
|
124
|
|
- }
|
125
|
|
-
|
126
|
|
- public function getColumns($table_name)
|
127
|
|
- {
|
128
|
|
- $columnsQuery = $this->_pdo->prepare("SELECT column_name as name, data_type as data_type FROM information_schema.columns WHERE table_name = :table_name");
|
129
|
|
- if ($columnsQuery->execute(array(":table_name" => $table_name)))
|
130
|
|
- {
|
131
|
|
- $columns = $columnsQuery->fetchAll();
|
132
|
|
- echo "Found " . count($columns) . " columns in table " . $table_name . "\n";
|
133
|
|
- return $columns;
|
134
|
|
- }
|
135
|
|
- else
|
136
|
|
- return $this->printError($columnsQuery, "Failed to get columns from " . $table_name);
|
137
|
|
- }
|
138
|
|
-
|
139
|
|
- public function sqlTypeToPhpType($type)
|
140
|
|
- {
|
141
|
|
- if ($type == "character" || $type == "character varying" || $type == "char"
|
142
|
|
- || $type == "varchar" || $type == "bytea") {
|
143
|
|
- return "string";
|
144
|
|
- }
|
145
|
|
- if ($type == "bigint" || $type == "bigserial" || $type == "serial8" || $type == "serial2"
|
146
|
|
- || $type == "serial4" || $type == "int8" || $type == "int2" || $type == "integer" || $type == "smallint") {
|
147
|
|
- return "integer";
|
148
|
|
- }
|
149
|
|
- if ($type == "decimal" || $type == "real" || $type == "double precision" || $type == "float8") {
|
150
|
|
- return "double";
|
151
|
|
- }
|
152
|
|
- if ($type == "bit" || $type == "bit varying" || $type == "varbit" || $type == "boolean" || $type == "bool") {
|
153
|
|
- return "boolean";
|
154
|
|
- }
|
155
|
|
- return $type;
|
156
|
|
- }
|
157
|
|
-
|
|
112
|
+
|
158
|
113
|
public function sqlTypesToPhpTypes($array)
|
159
|
114
|
{
|
|
115
|
+ $db = $this->getDbDataAccess();
|
160
|
116
|
foreach ($array as $key => $value)
|
161
|
117
|
{
|
162
|
118
|
$array[$key]["data_type"] = array(
|
163
|
119
|
"sql" => $array[$key]["data_type"],
|
164
|
|
- "php" => $this->sqlTypeToPhpType($array[$key]["data_type"])
|
|
120
|
+ "php" => $db->sqlTypeToPhpType($array[$key]["data_type"])
|
165
|
121
|
);
|
166
|
122
|
}
|
167
|
123
|
return $array;
|
|
@@ -177,61 +133,26 @@ WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'informat
|
177
|
133
|
$this->buildTwig('dbo_array.php', $fileArray, $vars);
|
178
|
134
|
}
|
179
|
135
|
|
180
|
|
- public function getStoredProcedures()
|
|
136
|
+ public function generateSp($sp, $file, $spFile, $dboName, $dboFile, $dboFileArray)
|
181
|
137
|
{
|
182
|
|
- $spQuery = $this->_pdo->prepare("SELECT r.routine_name AS sp_name, r.data_type AS data_type, proc.proretset AS proretset, proc.prosrc AS prosrc
|
183
|
|
-FROM information_schema.routines r
|
184
|
|
-LEFT JOIN pg_catalog.pg_proc proc ON proc.proname = r.routine_name
|
185
|
|
-WHERE r.specific_schema='public'");
|
186
|
|
- if ($spQuery->execute())
|
187
|
|
- {
|
188
|
|
- $sp = $spQuery->fetchAll();
|
189
|
|
- echo "Found " . count($sp) . " stored procedures\n";
|
190
|
|
- return $sp;
|
191
|
|
- }
|
192
|
|
- else
|
193
|
|
- return $this->printError($spQuery, "Failed to get stored procedures");
|
194
|
|
- }
|
195
|
|
-
|
196
|
|
- public function getStoredProceduresArguments($sp)
|
197
|
|
- {
|
198
|
|
- $sp_name = $sp["sp_name"];
|
199
|
|
- $spQuery = $this->_pdo->prepare("SELECT parameters.parameter_name as name, parameters.data_type, parameters.parameter_mode
|
200
|
|
-FROM information_schema.routines
|
201
|
|
-JOIN information_schema.parameters ON routines.specific_name=parameters.specific_name
|
202
|
|
-WHERE routines.specific_schema='public' AND routines.routine_name = :sp_name
|
203
|
|
-ORDER BY parameters.ordinal_position;");
|
204
|
|
- if ($spQuery->execute(array("sp_name" => $sp_name)))
|
205
|
|
- {
|
206
|
|
- $sp_ = $spQuery->fetchAll();
|
207
|
|
- $sps = array("in" => array(), "out" => array());
|
208
|
|
- foreach ($sp_ as $p)
|
209
|
|
- $sps[strtolower($p["parameter_mode"])][] = $p;
|
210
|
|
- $out_count = count($sps['out']);
|
211
|
|
- if ($out_count == 0)
|
212
|
|
- {
|
213
|
|
- $sps['out'][] = array(
|
214
|
|
- "name" => $sp_name,
|
215
|
|
- "data_type" => $sp["data_type"],
|
216
|
|
- "parameter_mode" => "OUT"
|
217
|
|
- );
|
218
|
|
- $out_count = 1;
|
219
|
|
- }
|
220
|
|
- echo "Found " . count($sps['in']) . " input arguments for stored procedure " . $sp_name . "\n";
|
221
|
|
- echo "Found " . $out_count . " output arguments for stored procedure " . $sp_name . "\n";
|
222
|
|
- return $sps;
|
|
138
|
+ file_put_contents($spFile, $sp["sp"]["prosrc"]);
|
|
139
|
+ $args = [];
|
|
140
|
+ $db = $this->getDbDataAccess();
|
|
141
|
+ foreach ($sp['args']['out'] as $arg) {
|
|
142
|
+ $args[] = [
|
|
143
|
+ "name" => $arg["name"],
|
|
144
|
+ "data_type" => [
|
|
145
|
+ "php" => $db->sqlTypeToPhpType($arg["data_type"]),
|
|
146
|
+ "sql" => $arg["data_type"]
|
|
147
|
+ ]
|
|
148
|
+ ];
|
223
|
149
|
}
|
224
|
|
- else
|
225
|
|
- return $this->printError($spQuery, "Failed to get arguments for stored procedure " . $sp_name);
|
226
|
|
- }
|
227
|
|
-
|
228
|
|
- public function generateSp($sp, $args, $file, $spFile)
|
229
|
|
- {
|
230
|
|
- $vars = array(
|
231
|
|
- "sp" => $sp,
|
232
|
|
- "args" => $args
|
233
|
|
- );
|
234
|
|
- file_put_contents($spFile, $sp["prosrc"]);
|
|
150
|
+ $this->generateDbo($dboName, $args, $dboFile, $dboFileArray);
|
|
151
|
+ $vars = [
|
|
152
|
+ "args" => $sp["args"],
|
|
153
|
+ "sp" => $sp["sp"],
|
|
154
|
+ "dboName" => $dboName
|
|
155
|
+ ];
|
235
|
156
|
$this->buildTwig('sp.php', $file, $vars);
|
236
|
157
|
}
|
237
|
158
|
|
|
@@ -310,16 +231,14 @@ ORDER BY parameters.ordinal_position;");
|
310
|
231
|
|
311
|
232
|
$tables = $this->getTables();
|
312
|
233
|
if (!is_null($tables)) {
|
313
|
|
- foreach ($tables as $table) {
|
314
|
|
- $table_name = $table["table_name"];
|
|
234
|
+ echo "Found " . count($tables) . " tables\n";
|
|
235
|
+ foreach ($tables as $table_name => $columns) {
|
315
|
236
|
if ($this->matchIgnore("tables", $table_name)) {
|
316
|
237
|
echo "Table $table_name ignored\n";
|
317
|
238
|
continue;
|
318
|
239
|
}
|
319
|
|
- $columns = $this->getColumns($table_name);
|
320
|
|
- if (is_null($columns))
|
321
|
|
- continue;
|
322
|
240
|
$columns = $this->sqlTypesToPhpTypes($columns);
|
|
241
|
+ echo "Found " . count($columns) . " columns in table " . $table_name . "\n";
|
323
|
242
|
$baseName = LuStringUtils::snakeToCamelCase($table_name, true);
|
324
|
243
|
$dboName = $baseName . "Dbo";
|
325
|
244
|
$dataAccessName = $baseName . "DataAccess";
|
|
@@ -338,24 +257,54 @@ ORDER BY parameters.ordinal_position;");
|
338
|
257
|
$controller_dir . $controllerName . ".php");
|
339
|
258
|
}
|
340
|
259
|
}
|
|
260
|
+ else {
|
|
261
|
+ $this->printError("Failed to get tables");
|
|
262
|
+ }
|
341
|
263
|
$sps = $this->getStoredProcedures();
|
342
|
264
|
if (!is_null($sps)) {
|
343
|
|
- foreach ($sps as $sp)
|
|
265
|
+ echo "Found " . count($sps) . " stored procedures\n";
|
|
266
|
+ foreach ($sps as $sp_name => $sp)
|
344
|
267
|
{
|
345
|
|
- $sp_name = $sp["sp_name"];
|
346
|
268
|
if ($this->matchIgnore("sp", $sp_name)) {
|
347
|
269
|
echo "Stored procedure $sp_name ignored\n";
|
348
|
270
|
continue;
|
349
|
271
|
}
|
350
|
|
- $args = $this->getStoredProceduresArguments($sp);
|
351
|
|
- if (is_null($args))
|
352
|
|
- continue;
|
|
272
|
+ $args = $sp["args"];
|
|
273
|
+ echo "Found " . count($args['in']) . " input and " .
|
|
274
|
+ count($args['out']) . " output arguments in stored procedure " . $sp_name . "\n";
|
353
|
275
|
$args["in"] = $this->sqlTypesToPhpTypes($args["in"]);
|
354
|
276
|
$args["out"] = $this->sqlTypesToPhpTypes($args["out"]);
|
355
|
277
|
$sp_model_name = LuStringUtils::snakeToCamelCase($sp_name, true);
|
356
|
|
- $this->generateSp($sp, $args, $sp_dir . $sp_model_name . ".php", $sp_src_dir . $sp_name . ".sql");
|
|
278
|
+ $dboName = $sp_model_name . "Dbo";
|
|
279
|
+ $this->generateSp($sp, $sp_dir . $sp_model_name . ".php", $sp_src_dir . $sp_name . ".sql", $dboName,
|
|
280
|
+ $dbo_dir . $dboName . ".php", $dbo_dir . $dboName . "Array.php");
|
357
|
281
|
}
|
358
|
282
|
}
|
|
283
|
+ else {
|
|
284
|
+ $this->printError("Failed to get stored procedures");
|
|
285
|
+ }
|
|
286
|
+ }
|
|
287
|
+
|
|
288
|
+ public function getStoredProcedures()
|
|
289
|
+ {
|
|
290
|
+ return $this->getDbDataAccess()->getStoredProceduresFull($this->_pdo);
|
|
291
|
+ }
|
|
292
|
+
|
|
293
|
+ public function getTables()
|
|
294
|
+ {
|
|
295
|
+ return $this->getDbDataAccess()->getTablesFull($this->_pdo);
|
|
296
|
+ }
|
|
297
|
+
|
|
298
|
+ /**
|
|
299
|
+ * @return AbstractDbDataAccess|null
|
|
300
|
+ */
|
|
301
|
+ public function getDbDataAccess()
|
|
302
|
+ {
|
|
303
|
+ $driver = $this->_pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
|
304
|
+ if ($driver == "pgsql") {
|
|
305
|
+ return new PgSqlDataAccess();
|
|
306
|
+ }
|
|
307
|
+ return null;
|
359
|
308
|
}
|
360
|
309
|
}
|
361
|
310
|
|