Open Journal Systems  3.3.0
DBDataXMLParser.inc.php
1 <?php
2 
18 import('lib.pkp.classes.xml.XMLParser');
19 
22  var $dbconn;
23 
25  var $sql;
26 
30  function __construct() {
31  $this->sql = array();
32  }
33 
39  function setDBConn($dbconn) {
40  $this->dbconn = $dbconn;
41  }
42 
48  function parseData($file) {
49  $this->sql = array();
50  $parser = new XMLParser();
51  $tree = $parser->parse($file);
52  if (!$tree) return array();
53 
54  $allTables = $this->dbconn->MetaTables();
55  foreach ($tree->getChildren() as $type) switch($type->getName()) {
56  case 'table':
57  $fieldDefaultValues = array();
58 
59  // Match table element
60  foreach ($type->getChildren() as $row) {
61  switch ($row->getName()) {
62  case 'row':
63  // Match a row element
64  $fieldValues = array();
65 
66  foreach ($row->getChildren() as $field) {
67  // Get the field names and values for this INSERT
68  list($fieldName, $value) = $this->_getFieldData($field);
69  $fieldValues[$fieldName] = $value;
70  }
71 
72  $fieldValues = array_merge($fieldDefaultValues, $fieldValues);
73 
74  if (count($fieldValues) > 0) {
75  $this->sql[] = sprintf(
76  'INSERT INTO %s (%s) VALUES (%s)',
77  $type->getAttribute('name'),
78  join(', ', array_keys($fieldValues)),
79  join(', ', array_values($fieldValues)));
80  }
81  break;
82  default: assert(false);
83  }
84  }
85  break;
86  case 'sql':
87  // Match sql element (set of SQL queries)
88  foreach ($type->getChildren() as $child) switch ($child->getName()) {
89  case 'drop':
90  if (!isset($dbdict)) {
91  $dbdict = @NewDataDictionary($this->dbconn);
92  }
93  $table = $child->getAttribute('table');
94  $column = $child->getAttribute('column');
95  if ($column) {
96  // NOT PORTABLE; do not use this
97  $this->sql[] = $dbdict->DropColumnSql($table, $column);
98  } else {
99  $this->sql[] = $dbdict->DropTableSQL($table);
100  }
101  break;
102  case 'rename':
103  if (!isset($dbdict)) {
104  $dbdict = @NewDataDictionary($this->dbconn);
105  }
106  $table = $child->getAttribute('table');
107  $column = $child->getAttribute('column');
108  $to = $child->getAttribute('to');
109  if ($column) {
110  // Make sure the target column does not yet exist.
111  // This is to guarantee idempotence of upgrade scripts.
112  $run = false;
113  if (in_array($table, $allTables)) {
114  $columns = $this->dbconn->MetaColumns($table, true);
115  if (!isset($columns[strtoupper($to)])) {
116  // Only run if the column has not yet been
117  // renamed.
118  $run = true;
119  }
120  } else {
121  // If the target table does not exist then
122  // we assume that another rename entry will still
123  // rename it and we should run after it.
124  $run = true;
125  }
126 
127  if ($run) {
128  $colId = strtoupper($column);
129  $flds = '';
130  if (isset($columns[$colId])) {
131  $col = $columns[$colId];
132  if ($col->max_length == "-1") {
133  $max_length = '';
134  } else {
135  $max_length = $col->max_length;
136  }
137  $fld = array('NAME' => $col->name, 'TYPE' => $dbdict->MetaType($col), 'SIZE' => $max_length);
138  if ($col->primary_key) $fld['KEY'] = 'KEY';
139  if ($col->auto_increment) $fld['AUTOINCREMENT'] = 'AUTOINCREMENT';
140  if ($col->not_null) $fld['NOTNULL'] = 'NOTNULL';
141  if ($col->has_default) $fld['DEFAULT'] = $col->default_value;
142  $flds = array($colId => $fld);
143  } else assert(false);
144 
145  $this->sql[] = $dbdict->RenameColumnSQL($table, $column, $to, $flds);
146  }
147  } else {
148  // Make sure the target table does not yet exist.
149  // This is to guarantee idempotence of upgrade scripts.
150  if (!in_array($to, $allTables)) {
151  $this->sql[] = $dbdict->RenameTableSQL($table, $to);
152  }
153  }
154  break;
155  case 'dropindex':
156  if (!isset($dbdict)) {
157  $dbdict = @NewDataDictionary($this->dbconn);
158  }
159  $table = $child->getAttribute('table');
160  $index = $child->getAttribute('index');
161  if (!$table || !$index) {
162  throw new Exception('dropindex called without table or index');
163  }
164  $indexes = array_map('strtoupper', array_keys($this->dbconn->MetaIndexes($table)));
165  if (in_array(strtoupper($index), $indexes)) {
166  $this->sql[] = $dbdict->DropIndexSQL($index, $table);
167  }
168  break;
169  case 'query':
170  // If a "driver" attribute is specified, multiple drivers can be
171  // specified with a comma separator.
172  $driver = $child->getAttribute('driver');
173  if (empty($driver) || in_array($this->dbconn->databaseType, array_map('trim', explode(',', $driver)))) {
174  $this->sql[] = $child->getValue();
175  }
176  break;
177  }
178  break;
179  }
180  return $this->sql;
181  }
182 
188  function executeData($continueOnError = false) {
189  $this->errorMsg = null;
190  $dbconn = $this->dbconn == null ? DBConnection::getConn() : $this->dbconn;
191  foreach ($this->sql as $stmt) {
192  $dbconn->execute($stmt);
193  if (!$continueOnError && $dbconn->errorNo() != 0) {
194  return false;
195  }
196  }
197  return true;
198  }
199 
204  function getSQL() {
205  return $this->sql;
206  }
207 
213  function quoteString($str) {
214  return $this->dbconn->qstr($str);
215  }
216 
217 
218  //
219  // Private helper methods
220  //
227  function _getFieldData($fieldNode) {
228  $fieldName = $fieldNode->getAttribute('name');
229  $fieldValue = $fieldNode->getValue();
230 
231  // Is this field empty? If so: do we want NULL or
232  // an empty string?
233  $isEmpty = $fieldNode->getAttribute('null');
234  if (!is_null($isEmpty)) {
235  assert(is_null($fieldValue));
236  switch($isEmpty) {
237  case 1:
238  $fieldValue = null;
239  break;
240 
241  case 0:
242  $fieldValue = '';
243  break;
244  }
245  }
246 
247  // Translate null to 'NULL' for SQL use.
248  if (is_null($fieldValue)) {
249  $fieldValue = 'NULL';
250  } else {
251  // Quote the value.
252  if (!is_numeric($fieldValue)) {
253  $fieldValue = $this->quoteString($fieldValue);
254  }
255  }
256 
257  return array($fieldName, $fieldValue);
258  }
259 }
260 
261 
DBDataXMLParser\$sql
$sql
Definition: DBDataXMLParser.inc.php:31
DBDataXMLParser\parseData
parseData($file)
Definition: DBDataXMLParser.inc.php:54
DBDataXMLParser
Class to import and export database data from an XML format. See dbscripts/xml/dtd/xmldata....
Definition: DBDataXMLParser.inc.php:20
DBDataXMLParser\_getFieldData
_getFieldData($fieldNode)
Definition: DBDataXMLParser.inc.php:233
DBDataXMLParser\executeData
executeData($continueOnError=false)
Definition: DBDataXMLParser.inc.php:194
DBConnection\getConn
static & getConn()
Definition: DBConnection.inc.php:257
DBDataXMLParser\__construct
__construct()
Definition: DBDataXMLParser.inc.php:36
XMLParser
Generic class for parsing an XML document into a data structure.
Definition: XMLParser.inc.php:28
DBDataXMLParser\setDBConn
setDBConn($dbconn)
Definition: DBDataXMLParser.inc.php:45
DBDataXMLParser\getSQL
getSQL()
Definition: DBDataXMLParser.inc.php:210
DBDataXMLParser\$dbconn
$dbconn
Definition: DBDataXMLParser.inc.php:25
DBDataXMLParser\quoteString
quoteString($str)
Definition: DBDataXMLParser.inc.php:219