Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
data_source_db.inc
1 <?php
18 require_once SQ_INCLUDE_PATH.'/asset.inc';
19 require_once SQ_CORE_PACKAGE_PATH.'/data_source/data_source/data_source.inc';
20 require_once SQ_LIB_PATH.'/html_form/html_form.inc';
21 require_once SQ_CORE_PACKAGE_PATH.'/files/image/image.inc';
22 
35 {
36 
37 
44  function __construct($assetid=0)
45  {
46  parent::__construct($assetid);
47 
48  }//end constructor
49 
50 
64  function _getAllowedLinks()
65  {
66  // any link is allowed
67  $allowed_link['asset']['card'] = 'M';
68  $allowed_link['asset']['exclusive'] = FALSE;
69 
70  $links[SQ_LINK_TYPE_1] = $allowed_link;
71  $links[SQ_LINK_TYPE_2] = $allowed_link;
72  $links[SQ_LINK_TYPE_3] = $allowed_link;
73  $links[SQ_LINK_NOTICE] = $allowed_link;
74 
75  return $links;
76 
77  }//end _getAllowedLinks()
78 
79 
87  {
88  $fields = $this->attr('fields');
89  if ($fields != '*') {
90  $fields = explode(', ', $fields);
91  return $fields;
92  } else {
93  $tables = explode(', ', $this->attr('tables'));
94  $fields = Array();
95  $conn = $this->connectToDB();
96  foreach ($tables as $table) {
97  try {
98  $sql = 'select * from '.$table;
99  $result = MatrixDAL::executeSqlAssoc($sql);
100 
101  if (!empty($result)) {
102  $record = $result(0);
103  foreach ($record as $key => $value) {
104  $field[] = $key;
105  }
106  }
107 
108  } catch (DALException $e) {
109  trigger_localised_error('DATA0001', E_USER_WARNING, $e->getMessage(), $sql);
110  $empty = Array();
111  return $empty;
112  }
113 
114  }//end foreach
115  }//end if
116 
117  }//end getFieldNamesFromRecordSet()
118 
119 
126  function &getResultSet()
127  {
128  $GLOBALS['SQ_SYSTEM']->pm->startTimer($this);
129  $query_string = $this->_getExecutableQueryString();
130  if (!empty($query_string)) {
131  $hash = md5($query_string);
132 
133  // Check the local cache
134  if (!isset($this->_tmp[$hash])) {
135 
136  // Check the system cache
137  $result = $this->getCachedResultSet($hash);
138  if ($result !== FALSE) {
139  $this->_tmp[$hash] = $result;
140  } else {
141  // Not cached at all, so hit the DB
142  $this->_tmp[$hash] = $this->_executeQuery($query_string);
143  $this->cacheResultSet($this->_tmp[$hash], $hash);
144  }
145  }
146  $GLOBALS['SQ_SYSTEM']->pm->stopTimer($this);
147  return $this->_tmp[$hash];
148  }
149 
150  $GLOBALS['SQ_SYSTEM']->pm->stopTimer($this);
151  // Fall-through failure case
152  $res = Array();
153  return $res;
154 
155  }//end getResultSet()
156 
157 
167  {
168  $sql = $this->attr('sql');
169 
170  $keyword_wrapper = '%%';
171  $keyword_pattern = '('.$keyword_wrapper.'([a-zA-Z_\-0-9\.]+)'.$keyword_wrapper.')';
172 
173  // insert the dynamic parameters into the query
174  preg_match_all ('/'.$keyword_pattern.'/', $sql, $matches, PREG_PATTERN_ORDER);
175  if (empty($matches[1])) {
176  return $sql;
177  }
178 
179  $raw_keywords =& $matches[1];
180  $keywords =& $matches[2];
181 
182  $db = $this->connectToDB();
183  if ($db === FALSE) return $sql;
184 
185  foreach ($keywords as $keyword) {
186  $value = $this->getDynamicVariableValue($keyword);
187  $value = MatrixDAL::quote($value);
188  $replacements[] = str_replace('$', '\$', $value);
189  $patterns[] = '/('.$keyword_wrapper.$keyword.$keyword_wrapper.')/';
190  }
191 
192  $sql = preg_replace($patterns, $replacements, $sql);
193 
194  return $sql;
195 
196  }//end _getExecutableQueryString()
197 
198 
207  function _executeQuery($sql)
208  {
209  $db = $this->connectToDB();
210  if ($db === FALSE) return Array();
211  $sql = trim($sql, '; ');
212  try {
213  MatrixDAL::changeDb('data_source_db_'.$this->id);
214  $empty_result = TRUE;
215  if (MatrixDAL::getDbType() === 'oci' && preg_match('/^\s*(:?delete )|(:?insert )|(:?update )/msi', $sql)) {
219  } else {
220  $result = MatrixDAL::executeSqlAssoc($sql);
221  // if query returns a non-empty result but with empty rows, like when using
222  // delete, update and insert queries, then make this result empty altogether
223  foreach($result as $row) {
224  if (!empty($row)) {
225  $empty_result = FALSE;
226  break;
227  }
228  }
229  }//end else
231  } catch (Exception $e) {
232  trigger_localised_error('DATA0001', E_USER_WARNING, $e->getMessage(), $sql);
234  return Array();
235  }
236 
237  return $empty_result ? Array() : $result;
238 
239  }//end _executeQuery()
240 
241 
248  function connectToDB()
249  {
250  if (isset($this->_tmp['db_connection'])) {
251  return $this->_tmp['db_connection'];
252  }
253 
254  $dsn = $this->getDSN();
255  if (empty($dsn)) return FALSE;
256 
257  // If there is an "oci:" prefix, strip it and store this data in the DB type index
258  $dsn_lower = strtolower($dsn['DSN']);
259  if (substr($dsn_lower, 0, 4) == 'oci:') {
260  $dsn['DSN'] = substr($dsn['DSN'], 4);
261  $dsn['type'] = 'oci';
262 
263  // Also we may have arrived from the separate fields interface or manually entered a "dbname=" PDO_OCI-type DSN
264  // In such cases we will be nice and strip the leading "dbname=" for a simple PHP OCI-friendly format
265  $dsn_lower = strtolower($dsn['DSN']);
266  if (substr($dsn_lower, 0, 7) == 'dbname=') {
267  $dsn['DSN'] = substr($dsn['DSN'], 7);
268  }
269  }
270 
271  try {
272  $this->_tmp['db_connection'] = MatrixDAL::dbConnect($dsn, 'data_source_db_'.$this->id);
273  } catch (Exception $e) {
274  $this->_tmp['db_conection_exception'] = $e;
275  return FALSE;
276  }
277 
278 
279  return $this->_tmp['db_connection'];
280 
281  }//end connectToDB()
282 
283 
290  function getDSN()
291  {
292  if (isset($this->_tmp['db_DSN'])) {
293  return $this->_tmp['db_DSN'];
294  }
295 
296  $dsn = '';
297 
298  $connector_asset = $this->_getConnectorAsset();
299  if (!empty($connector_asset)) {
300  $dsn = $connector_asset->getDSN();
301  }
302 
303  if (empty($dsn)) {
304  $dsn = $this->constructDSNArray($this);
305  }
306 
307  $this->_tmp['db_DSN'] = $dsn;
308 
309  return $dsn;
310 
311  }//end getDSN()
312 
313 
322  function constructDSNArray($asset)
323  {
324  $dsn = $asset->attr('dsn');
325  $user = $asset->attr('user');
326  $password = $asset->attr('password');
327  $type = $asset->attr('db_type');
328  switch ($type) {
329  case 'mysql':
330  $type = 'mysql';
331  break;
332  case 'oracle':
333  case 'oci':
334  $type = 'oci';
335  break;
336  case 'pgsql':
337  $type = 'pgsql';
338  break;
339  default:
340  $type = 'pgsql';
341  break;
342  }
343 
344  // If there is an "oci:" prefix, strip it and store this data in the DB type index
345  $dsn_lower = strtolower($dsn);
346  if (substr($dsn_lower, 0, 4) == 'oci:') {
347  $dsn = substr($dsn, 4);
348  $type = 'oci';
349  // Also we may have arrived from the separate fields interface or manually entered a "dbname=" PDO_OCI-type DSN
350  // In such cases we will be nice and strip the leading "dbname=" for a simple PHP OCI-friendly format
351  $dsn_lower = strtolower($dsn);
352  if (substr($dsn_lower, 0, 7) == 'dbname=') {
353  $dsn = substr($dsn, 7);
354  }
355  }
356 
357  return Array('DSN' => $dsn, 'user' => $user, 'password' => $password, 'type' => $type);
358 
359  }//end constructDSNArray()
360 
361 
369  {
370  $connector_asset = NULL;
371 
372  $connector_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_NOTICE, 'db_connector', FALSE, 'db_connector');
373  if (empty($connector_link)) {
374  $connector_asset_id = NULL;
375  } else {
376  $connector_asset_id = $connector_link['minorid'];
377  }
378 
379  if (!empty($connector_asset_id)) {
380  $connector_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($connector_asset_id);
381  }
382 
383  return $connector_asset;
384 
385  }//end _getConnectorAsset()
386 
387 
388 }//end class
389 
390 ?>