00001 <?php
00002
00013 abstract class SnapDBI extends SObject {
00015 private static $CONN = null;
00017 private static $RCOOKIE = null;
00019 private static $QUERY_COUNT = 0;
00020
00022 private static $transLevel = 0;
00023
00024 private static $alreadyRegistered = false;
00025
00036 public static function connect($user, $pass, $host, $db) {
00037 self::$CONN = @mysql_pconnect($host, $user, $pass);
00038 if(self::$CONN === false) {
00039 self::setStaticError("DB Connection Error");
00040 return false;
00041 }
00042
00043 if(!mysql_select_db($db, self::$CONN)) {
00044 self::setStaticError("Error selecting database '$db': "
00045 . mysql_error());
00046 self::$CONN = null;
00047 return false;
00048 }
00049
00050 if(!self::$alreadyRegistered) {
00051 register_shutdown_function(array('SnapDBI', 'cleanupTransactions'));
00052 self::$alreadyRegistered = true;
00053 }
00054
00055 return true;
00056 }
00057
00065 public static function disconnect() {
00066 if(self::$CONN) {
00067 self::cleanupTransactions();
00068 mysql_close(self::$CONN);
00069 }
00070 self::$CONN = null;
00071 self::$RCOOKIE = null;
00072 }
00073
00081 public static function cleanupTransactions() {
00082 if(self::$transLevel > 0) {
00083 @mysql_query("ROLLBACK", self::$CONN);
00084 }
00085 }
00086
00098 public static function query($query, $getResult = false) {
00099 if(!Snap2::checkInit()) return false;
00100
00101 self::$RCOOKIE = mysql_query($query, self::$CONN);
00102 if(self::$RCOOKIE === false) {
00103 self::setStaticError("Invalid query: " . mysql_error(self::$CONN));
00104 self::setStaticError("Query was: " . $query);
00105 return false;
00106 }
00107
00108
00109
00110
00111 if(!$getResult || self::$RCOOKIE === true) {
00112 return true;
00113 }
00114
00115 $numRows = mysql_num_rows(self::$RCOOKIE);
00116 if($numRows > 0) {
00117 $ret = range(0, $numRows - 1, 1);
00118 for($i = 0; $i < $numRows; $i++)
00119 $ret[$i] = mysql_fetch_assoc(self::$RCOOKIE);
00120 }
00121 else
00122 $ret = array();
00123
00124 if(is_resource(self::$RCOOKIE))
00125 mysql_free_result(self::$RCOOKIE);
00126
00127 return $ret;
00128 }
00129
00135 public static function getInsertId() {
00136 if(!Snap2::checkInit()) return false;
00137 return mysql_insert_id(self::$CONN);
00138 }
00139
00146 public static function getRow($rowNum = false) {
00147 if(!Snap2::checkInit()) return false;
00148 if($rowNum === false)
00149 return mysql_fetch_assoc(self::$RCOOKIE);
00150
00151 mysql_data_seek(self::$RCOOKIE, $rowNum);
00152 return mysql_fetch_assoc(self::$RCOOKIE);
00153 }
00154
00161 public static function firstRow($reset = false) {
00162 if(!Snap2::checkInit()) return false;
00163 if($reset)
00164 mysql_data_seek(self::$RCOOKIE, 0);
00165 return mysql_fetch_assoc(self::$RCOOKIE);
00166 }
00167
00173 public static function getNumRows() {
00174 if(!Snap2::checkInit()) return false;
00175 return mysql_num_rows(self::$RCOOKIE);
00176 }
00177
00185 public static function freeResult() {
00186 if(!Snap2::checkInit()) return false;
00187 if(is_resource(self::$RCOOKIE))
00188 mysql_free_result(self::$RCOOKIE);
00189 self::$RCOOKIE = true;
00190 }
00191
00200 public static function startTransaction() {
00201 if(!Snap2::checkInit()) return false;
00202 if(self::$transLevel == 0) {
00203 if(!@mysql_query("START TRANSACTION", self::$CONN)) {
00204 self::setStaticError("Could not start database transaction: " . mysql_error(self::$CONN));
00205 return false;
00206 }
00207 }
00208
00209 self::$transLevel++;
00210
00211 return true;
00212 }
00213
00227 public static function commitTransaction() {
00228 if(!Snap2::checkInit()) return false;
00229 if(self::$transLevel == 1) {
00230 if(!@mysql_query("COMMIT", self::$CONN)) {
00231 self::setStaticError("Could not commit transaction: " . mysql_error(self::$CONN));
00232 return false;
00233 }
00234 }
00235
00236 if(self::$transLevel > 0)
00237 self::$transLevel--;
00238
00239 return self::$transLevel;
00240 }
00241
00248 public static function cancelTransaction() {
00249 if(!Snap2::checkInit()) return false;
00250 if(!@mysql_query("ROLLBACK", self::$CONN)) {
00251 self::setStaticError("Could not rollback transaction: " . mysql_error(self::$CONN));
00252 return false;
00253 }
00254
00255 self::$transLevel = 0;
00256
00257 return true;
00258 }
00259
00269 public static function criteriaToString($arr, $attributes) {
00270 if(is_string($arr))
00271 return $arr;
00272 else if(!is_array($arr)) {
00273 self::setStaticError('Criteria must be string or array!');
00274 return false;
00275 }
00276 else if(count($arr) == 0)
00277 return '';
00278
00279 $collect = "";
00280 $op = "=";
00281 $conj = "AND";
00282 foreach($arr as $k => $v) {
00283
00284 if(ctype_digit((string) $k)) {
00285
00286 if(is_string($v)) {
00287 switch(strtoupper($v)) {
00288 case 'AND':
00289 case 'OR':
00290 $conj = $v;
00291 break;
00292 case '=':
00293 case '>=':
00294 case '<=':
00295 case '<':
00296 case '>':
00297 case '<>':
00298 case 'LIKE':
00299 case 'LIKE BINARY':
00300 case 'IS':
00301 case 'IS NOT':
00302 case 'IS NULL':
00303 case 'IS NOT NULL':
00304 $op = $v;
00305 break;
00306 default:
00307 self::setStaticError("Invalid operator or conjunction in criteria: $v");
00308 return false;
00309 }
00310 }
00311
00312 else if(is_array($v)) {
00313 $res = self::criteriaToString($v, $attributes);
00314 if($res === false)
00315 return false;
00316 if($collect != "")
00317
00318 $collect .= " $conj " . $res;
00319 else
00320 $collect .= $res;
00321 }
00322
00323 else {
00324 self::setStaticError("Invalid operator or conjunction in criteria: $v");
00325 return false;
00326 }
00327 }
00328
00329 else if(is_string($k)) {
00330
00331 if(!in_array($k, $attributes)) {
00332 self::setStaticError("Invalid field '$k' in criteria");
00333 return false;
00334 }
00335
00336
00337 if(is_array($v)) {
00338 foreach($v as $value) {
00339
00340
00341
00342 if($op == 'IS NULL' || $op == 'IS NOT NULL') {
00343 if($collect != "")
00344 $collect .= " $conj $k $op";
00345 else
00346 $collect = "$k $op";
00347 }
00348 else {
00349
00350 if($collect != "")
00351 $collect .= " $conj $k $op '$value'";
00352 else
00353 $collect = "$k $op '$value'";
00354 }
00355 }
00356 }
00357 else {
00358
00359 if($op == 'IS NULL' || $op == 'IS NOT NULL') {
00360 if($collect != "")
00361 $collect .= " $conj $k $op";
00362 else
00363 $collect = "$k $op";
00364 }
00365 else {
00366 if($collect != "")
00367 $collect .= " $conj $k $op '$v'";
00368 else
00369 $collect = "$k $op '$v'";
00370 }
00371 }
00372 }
00373 }
00374
00375
00376 if($collect != "")
00377 $collect = "($collect)";
00378
00379 return $collect;
00380 }
00381
00391 public static function limitToString($limit) {
00392 if($limit == "" || count($limit) == 0)
00393 return '';
00394
00395 if(is_array($limit)) {
00396 if(count($limit) == 2) {
00397 if(!ctype_digit((string) $limit[0]) || $limit[0] < 0 || !ctype_digit((string) $limit[1]) || $limit[1] < 0) {
00398 self::setStaticError('Invalid limit values');
00399 return false;
00400 }
00401 return " LIMIT $limit[0], $limit[1]";
00402 }
00403 else if(count($limit) == 1) {
00404 if(!ctype_digit((string) $limit[0]) || $limit[0] < 0) {
00405 self::setStaticError('Invalid limit values');
00406 return false;
00407 }
00408 return " LIMIT $limit[0]";
00409 }
00410 }
00411 else if(ctype_digit((string) $limit)) {
00412 if($limit < 0) {
00413 self::setStaticError('Invalid limit values');
00414 return false;
00415 }
00416 return " LIMIT $limit";
00417 }
00418
00419 self::setStaticError('Invalid limit array!');
00420 return false;
00421 }
00422
00434 public static function orderToString($order, $attributes) {
00435 if($order == "" || count($order) == 0)
00436 return '';
00437
00438 if(is_array($order)) {
00439 $orderStr = ' ORDER BY ';
00440 foreach($order as $key => $value) {
00441 if(ctype_digit((string) $key)) {
00442 if(!in_array($value, $attributes)) {
00443 self::setStaticError('Invalid attribute \'' . $value . '\'');
00444 return false;
00445 }
00446 $orderStr .= $value . ', ';
00447 }
00448 else {
00449 if(!in_array($key, $attributes)) {
00450 self::setStaticError('Invalid attribute \'' . $key . '\'');
00451 return false;
00452 }
00453 $value = strtoupper($value);
00454 if($value != 'ASC' && $value != 'DESC') {
00455 self::setStaticError('Ordering must be ASC or DESC');
00456 return false;
00457 }
00458 $orderStr .= $key . ' ' . $value . ', ';
00459 }
00460 }
00461 return rtrim($orderStr, ', ');
00462 }
00463 else if(is_string($order)) {
00464 return " ORDER BY $order";
00465 }
00466 else {
00467 self::setStaticError('Invalid order by array');
00468 return false;
00469 }
00470 }
00471 }
00472
00473 ?>