protected function claimStart()
 {
     if (!Transaction::claimStart()) {
         return FALSE;
     }
     Transaction::add($this->db);
     return TRUE;
 }
 protected function execute($query)
 {
     if (!Transaction::atStart()) {
         Transaction::add($this->db);
     }
     $args = func_get_args();
     array_shift($args);
     $rs = $this->db->execute($qs = $this->db->prep_args($query, $args));
     if (!$rs) {
         throw new Exception('database error', array('db' => $this->db, 'query' => $qs, 'error' => $this->db->error()));
     }
     return $rs;
 }
 public function beginTransaction($auth = NULL)
 {
     if ($auth == Transaction::SIGNATURE) {
         if ($this->lock) {
             return FALSE;
         }
         $this->txn = TRUE;
         return parent::beginTransaction();
     }
     Transaction::start();
     if (!Transaction::add($this)) {
         return FALSE;
     }
     return TRUE;
 }
 public function trans_start($auth = NULL)
 {
     if ($auth == Transaction::SIGNATURE) {
         if ($this->lock) {
             return FALSE;
         }
         $this->txn = TRUE;
         $this->core->trans_start();
         return TRUE;
     }
     Transaction::start();
     if (!Transaction::add($this)) {
         return FALSE;
     }
     return TRUE;
 }
 protected function db()
 {
     if ($this->db instanceof \Closure) {
         $mapper = $this->db;
         $db = $mapper($this->table());
     } elseif (is_scalar($this->db)) {
         $db = DB\Connection::instance($this->db);
     } else {
         $db = $this->db;
     }
     if (!$db instanceof DB\Iface) {
         throw new Exception('invalid db');
     }
     if (!$db->isa('mysql')) {
         throw new Exception('invalid db');
     }
     if (!$db->isa('gaia\\db\\extendediface')) {
         throw new Exception('invalid db');
     }
     if (!$db->isa('Gaia\\DB\\Except')) {
         $db = new DB\Except($db);
     }
     if (!Transaction::atStart()) {
         Transaction::add($db);
     }
     return $db;
 }
 /**
  * Utility function used mainly by other functions to derive values, but can be used by
  * the application if you know what you are doing.
  * Returns a count of how many entries are in each shard.
  */
 public function shardSequences()
 {
     $table = $this->table('index');
     $db = $this->db($table);
     if (DB\Transaction::inProgress()) {
         DB\Transaction::add($db);
     }
     $sql = "SELECT `shard`, `sequence` FROM {$table} WHERE `thread` = %s ORDER BY `shard` DESC";
     $rs = $db->execute($sql, $this->thread);
     $result = array();
     while ($row = $rs->fetch()) {
         $result[$row['shard']] = $row['sequence'];
     }
     $rs->free();
     return $result;
 }
 public function query(array $params = array())
 {
     $search = NULL;
     $min = NULL;
     $max = NULL;
     $sort = 'ASC';
     $limit = NULL;
     $result = array();
     if (isset($params['search'])) {
         $search = $params['search'];
     }
     if (isset($params['min'])) {
         $min = $params['min'];
     }
     if (isset($params['max'])) {
         $max = $params['max'];
     }
     if (isset($params['sort'])) {
         $sort = $params['sort'];
     }
     if (isset($params['limit'])) {
         $limit = $params['limit'];
     }
     if ($limit !== NULL) {
         $limit = str_replace(' ', '', $limit);
     }
     $sort = strtoupper($sort);
     if ($sort != 'DESC') {
         $sort = 'ASC';
     }
     $db = $this->db();
     $table = $this->table();
     if (DB\Transaction::inProgress()) {
         DB\Transaction::add($db);
     }
     $where = array();
     if ($search !== NULL) {
         $where[] = $db->prep_args("`stratum` IN( %s )", array($search));
     }
     if ($min !== NULL) {
         $where[] = $db->prep_args("`stratum` >= %i", array($min));
     }
     if ($max !== NULL) {
         $where[] = $db->prep_args("`stratum` <= %i", array($max));
     }
     $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
     $sql = "SELECT `constraint`, `stratum` FROM `{$table}` {$where} ORDER BY `stratum` {$sort}";
     if ($limit !== NULL && preg_match("#^([0-9]+)((,[0-9]+)?)\$#", $limit)) {
         $sql .= " LIMIT " . $limit;
     }
     //print "\n$sql\n";
     $rs = $db->execute($sql);
     while ($row = $rs->fetch()) {
         $result[$row['constraint']] = $row['stratum'];
     }
     $rs->free();
     return $result;
 }
 public function _joinRelated(array $related)
 {
     $affiliation = NULL;
     foreach ($related as $identifier => $affiliation) {
         if ($affiliation) {
             break;
         }
     }
     if (!$affiliation) {
         $affiliation = Util::newID();
     }
     $db = $this->db();
     $table = $this->table();
     $local_txn = DB\Transaction::claimStart();
     DB\Transaction::add($db);
     $sql_insert = "INSERT OR IGNORE INTO `{$table}` (`identifier`, `affiliation`) VALUES (%s, %i)";
     $sql_update = "UPDATE `{$table}` set `affiliation` = %i WHERE `identifier` = %s";
     foreach ($related as $identifier => $_id) {
         if ($_id == $affiliation) {
             continue;
         }
         $related[$identifier] = $affiliation;
         $rs = $db->execute($sql_insert, $identifier, $affiliation);
         if ($rs->affected() < 1) {
             $db->execute($sql_update, $affiliation, $identifier);
         }
     }
     if ($local_txn && !DB\Transaction::commit()) {
         throw new Exception('database error: unable to commit transaction', $db);
     }
     return $related;
 }
 /**
  * start a new transaction.
  * connected to the Transaction singleton to support multi-database transactions.
  */
 public function start()
 {
     $args = func_get_args();
     $auth = isset($args[0]) ? $args[0] : NULL;
     if ($this->core instanceof Iface) {
         return $this->core->start($auth);
     }
     if ($auth == Transaction::SIGNATURE) {
         if ($this->lock) {
             return FALSE;
         }
         $this->txn = TRUE;
         $f = $this->_[__FUNCTION__];
         return (bool) $f($auth);
     }
     Transaction::start();
     if (!Transaction::add($this)) {
         return FALSE;
     }
     return TRUE;
 }
 public function close($listing)
 {
     // grab the shard and row id.
     list($shard, $row_id) = Souk\Util::parseId($listing->id);
     // update the listing.
     $table = $this->table($shard);
     if (\Gaia\Souk\Storage::isAutoSchemaEnabled()) {
         $this->create($table);
     }
     if (!Transaction::atStart()) {
         Transaction::add($this->db);
     }
     $sql = "UPDATE {$table} SET buyer = %i, touch = %i, closed = 1, pricesort = NULL WHERE row_id = %i";
     $rs = $this->execute($sql, $listing->buyer, $listing->touch, $row_id);
     // should have affected a row. if it didn't toss an exception.
     if ($rs->affected() < 1) {
         throw new Exception('failed', $this->db);
     }
 }
 public function start($auth = NULL)
 {
     if ($auth == Transaction::SIGNATURE) {
         if ($this->lock) {
             return FALSE;
         }
         $this->txn = TRUE;
         return parent::query('START TRANSACTION');
     }
     Transaction::start();
     if (!Transaction::add($this)) {
         return FALSE;
     }
     return TRUE;
 }
 public function delete(array $identifiers)
 {
     $db = $this->db();
     $table = $this->table();
     if (!DB\Transaction::atStart()) {
         DB\Transaction::add($db);
     }
     $hashes = array();
     foreach ($identifiers as $identifier) {
         $hashes[] = sha1($identifier, true);
     }
     $db->execute("DELETE FROM `{$table}` WHERE `hash` IN ( %s )", $hashes);
 }