Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
updateclass.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @package FDL
5 */
6 /**
7  * Update the SQL structure of a table of a DbObj Object
8  *
9  * @param string $appc the application directory (WHAT, FDL, ...)
10  * @param string $class the class name of the DbObj Class
11  * @param string $dbname the SQL database name (anakeen, freedom)
12  * @author Anakeen 2002
13  * @version $Id: updateclass.php.in,v 1.8 2008/12/31 14:39:35 jerome Exp $
14  * @package FDL
15  * @subpackage CORE
16  */
17 /**
18  */
19 
20 global $action;
21 
22 include_once ('Class.Application.php');
23 
24 $usage = new ApiUsage();
25 
26 $usage->setDefinitionText("Update the SQL structure of a table of a DbObj Object");
27 $appClass = $usage->addOptionalParameter('appc', "application class folder", function ($value, $name)
28 {
29  if (!is_scalar($value)) {
30  return sprintf("Multiple values for '%s' not allowed.", $name);
31  }
32  if (strpos($value, DIRECTORY_SEPARATOR) !== false) {
33  return sprintf("Value for '%s' must not contain directory separator chars ('%s').", $name, DIRECTORY_SEPARATOR);
34  }
35  return '';
36 }
37 , 'WHAT');
38 $class = $usage->addRequiredParameter('class', 'Class name', function ($value, $name)
39 {
40  if (!is_scalar($value)) {
41  return sprintf("Multiple values for '%s' not allowed.", $name);
42  }
43  if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $value)) {
44  return sprintf("Invalid class name '%s' for '%s'.", $value, $name, DIRECTORY_SEPARATOR);
45  }
46  return '';
47 });
48 $db = $usage->addOptionalParameter('dbcoord', "Database name", null, getDbAccess());
49 
50 $usage->verify();
51 
52 $phpClass = sprintf("%s/%s/Class.%s.php", DEFAULT_PUBDIR, $appClass, $class);
53 
54 require_once ($phpClass);
55 /*
56  * @var DbObj $o
57  */
58 $o = new $class($db);
59 
60 $sql = array();
63  /* Compute columns that appears both in new and old table */
64  $columns = \Dcp\Core\PgInformationSchema::getTableColumns($o->dbaccess, 'public', $o->dbtable);
65  $commonColumns = array_intersect($o->fields, $columns);
66  /* Add SQL rename of current table to table + '_old' */
67  $oldTableName = sprintf("%s_old", $o->dbtable);
68  $sql[] = sprintf("ALTER TABLE public.%s RENAME TO %s", pg_escape_identifier($o->dbtable) , pg_escape_identifier($oldTableName));
69  /* Add SQL creation of new table */
70  $sqlCommands = explode(";", str_replace("\n", " ", $o->sqlcreate));
71  foreach ($sqlCommands as $k => $sqlQuery) {
72  $tableIndexes = \Dcp\Core\PgInformationSchema::getTableIndexes($o->dbaccess, 'public', $o->dbtable);
73  /* Drop index (if exists) before recreating it */
74  if (preg_match('/CREATE\s+ (?:UNIQUE\s+)? INDEX\s+ (?:CONCURRENTLY\s+)? (?:IF\s+NOT\s+EXISTS\s+)? (?P<indexName>[a-z0-9_]+)/xi', $sqlQuery, $m)) {
75  /* If index exists, then drop it */
76  if (in_array($m['indexName'], $tableIndexes)) {
77  $sql[] = sprintf("DROP INDEX public.%s", pg_escape_identifier($m['indexName']));
78  }
79  }
80  if (chop($sqlQuery) != "") $sql[] = $sqlQuery;
81  }
82  /* Add SQL to load common columns data from old table */
83  $sql[] = sprintf("INSERT INTO public.%s (%s) SELECT %s FROM public.%s", pg_escape_identifier($o->dbtable) , implode(", ", array_map('pg_escape_identifier', $commonColumns)) , implode(", ", array_map('pg_escape_identifier', $commonColumns)) , pg_escape_identifier($oldTableName));
84  /* Drop old table */
85  $sql[] = sprintf("DROP TABLE public.%s", pg_escape_identifier($oldTableName));
86 }
87 /* Play SQL commands */
88 $point = uniqid(sprintf('%s/%s', $appClass, $class) , true);
89 if (($err = $o->savePoint($point)) !== '') {
90  $action->exitError($err);
91 }
93  print sprintf("Updating existing table '%s'...\n", $o->dbtable);
94  foreach ($sql as $k => $v) {
95  if (preg_match('/CREATE\s+ SEQUENCE\s+ (?:IF\s+NOT\s+EXISTS\s+)? (?P<seqName>[a-z0-9_]+)/xi', $v, $m)) {
96  /* Do not recreate sequences (keep existing sequences untouched) */
97  print sprintf("[+] (%d/%d) Skipping sequence '%s'.\n", $m['seqName'], $k + 1, count($sql));
98  continue;
99  }
100  print sprintf("[+] (%d/%d) Executing SQL:\n", $k + 1, count($sql));
101  print "\t--8<--\n";
102  print "\t" . str_replace("\n", "\n\t", $v) . "\n";
103  print "\t-->8--\n";
104  simpleQuery($o->dbaccess, $v, $res, false, false, true);
105  print "[+] Done.\n";
106  }
107 } else {
108  print sprintf("Creating table '%s'...\n", $o->dbtable);
109  /* Table does not exists: create it */
110  $o->Create();
111 }
112 if (($err = $o->commitPoint($point)) !== '') {
113  $action->exitError($err);
114 }
115 
116 print "\nDone.\n";
global $action
Definition: updateclass.php:20
$o
Definition: updateclass.php:58
static getTableIndexes($dbaccess, $schemaName, $tableName)
$appClass
Definition: updateclass.php:27
$db
Definition: updateclass.php:48
const DEFAULT_PUBDIR
Definition: Lib.Prefix.php:28
$sql
Definition: updateclass.php:60
if($updateExistingTable) $point
Definition: updateclass.php:88
print
Definition: checklist.php:49
$usage
Definition: updateclass.php:24
$phpClass
Definition: updateclass.php:52
getDbAccess()
Definition: Lib.Common.php:368
static tableExists($dbaccess, $schemaName, $tableName)
static getTableColumns($dbaccess, $schemaName, $tableName)
$updateExistingTable
Definition: updateclass.php:61
simpleQuery($dbaccess, $query, &$result=array(), $singlecolumn=false, $singleresult=false, $useStrict=null)
Definition: Lib.Common.php:484
if($file) if($subject==""&&$file) if($subject=="") $err
$class
Definition: updateclass.php:38
$value
Verify arguments for wsh programs.
← centre documentaire © anakeen