/** * takes a simple list of item ids and pushes those items to the top of the list * starting with the first item id. doesn't need to be every item in the inventory. * just the ones you want sorted to the top of the list. * makes sense from an api standpoint but may not be perfect from an app standpoint. */ public function sort(array $item_ids) { if (count($item_ids) < 1) { return FALSE; } rsort($item_ids); $user_id = $this->user(); $pos = $this->maxPos(); $min = $this->minCustomPos(); if (bccomp($pos, $min) < 0) { $pos = $min; } if ($this->cacher) { $timeout = $this->cacheTimeout(); foreach ($item_ids as $item_id) { $pos = bcadd($pos, 1); $this->cacher->set($item_id, $pos, 0, $timeout); if ($this->inTran()) { Transaction::onRollback(array($this->cacher, 'delete'), array($item_id)); } } } try { $this->storage('sorter')->sort($pos, $item_ids); } catch (Exception $e) { throw $this->handle($e); } return TRUE; }
protected function create($table) { $cache = \Gaia\Souk\Storage::cacher(); $key = 'souk/storage/__create/' . md5($this->dsn . '/' . get_class($this) . '/' . $table); if ($cache->get($key)) { return; } if (!$cache->add($key, 1, 60)) { return; } $rs = $rs = $this->execute("SELECT `name` FROM `sqlite_master` WHERE `type` = 'table' and `name` = %s", $table); $row = $rs->fetch(); $rs->free(); if (!$row) { Transaction::onRollback(array($cache, 'delete'), array($key)); $rs = $this->execute("CREATE TABLE IF NOT EXISTS {$table} (\n `row_id` INTEGER PRIMARY KEY AUTOINCREMENT,\n `seller` BIGINT NOT NULL,\n `buyer` BIGINT NOT NULL DEFAULT '0',\n `item_id` INTEGER NOT NULL DEFAULT '0',\n `quantity` BIGINT NOT NULL DEFAULT '0',\n `price` BIGINT default '0',\n `pricesort` BIGINT default '0',\n `step` BIGINT default '0',\n `bid` BIGINT default '0',\n `proxybid` BIGINT default '0',\n `bidcount` INTEGER default '0',\n `bidder` BIGINT default '0',\n `reserve` BIGINT default NULL,\n `closed` INTEGER NOT NULL DEFAULT '0',\n `created` INTEGER,\n `expires` INTEGER,\n `touch` INTEGER\n )"); foreach (array('closed', 'created', 'expires', 'pricesort', 'item_id', 'step', 'seller', 'bidder', 'buyer') as $idx) { $idx_name = $table . '_idx_' . $idx; $this->execute("CREATE INDEX IF NOT EXISTS `{$idx_name}` ON `{$table}` (`{$idx}`)"); } } $table_attr = $table . '_attr'; $rs = $this->execute("SELECT `name` FROM `sqlite_master` WHERE `type` = 'table' and `name` = %s", $table_attr); $row = $rs->fetch(); $rs->free(); if (!$row) { Transaction::onRollback(array($cache, 'delete'), array($key)); $this->execute("CREATE TABLE IF NOT EXISTS {$table_attr} (\n `row_id` INTEGER NOT NULL,\n `attributes` TEXT,\n PRIMARY KEY (`row_id`)\n )"); } }
/** * @see Stockpile_Interface::add(); * on insert, set the pos column of the sort table to match current time. * on dupe key violation, update the pos column to match current time */ public function add($item_id, $quantity = 1, array $data = NULL) { $res = $this->core->add($item_id, $quantity, $data); try { $this->storage('sorter')->sort(Base::time(), array($item_id)); } catch (Exception $e) { throw $this->handle($e); } if ($this->cacher) { $this->cacher->set($item_id, $now, $this->cacheTimeout()); Transaction::onRollback(array($this->cacher, 'delete'), array($item_id)); } return $res; }
public function store($id, $name, $strict = FALSE) { Transaction::onRollback(array($this, 'clearCache'), array($id, $name)); $namecheck = $this->cacher('id')->get($id); $idcheck = $this->cacher('name')->get($name); $res = parent::store($id, $name, $strict); $this->cacher('id')->set($id, $name, $this->ttl); $this->cacher('name')->set($name, $id, $this->ttl); if ($namecheck != $name && $namecheck !== null) { $this->cacher('name')->delete($namecheck); } if ($id != $idcheck && $idcheck !== null) { $this->cacher('id')->delete($idcheck); } return $res; }
/** * @see Stockpile_Interface::add(); * only bump up to the top the first time we add this item id to the inventory. * after that, just let it slide. */ public function add($item_id, $quantity = 1, array $data = NULL) { $res = $this->core->add($item_id, $quantity, $data); $now = Base::time(); try { $ct = $this->storage('sorter')->sort($now, array($item_id), $ignore = TRUE); } catch (\Exception $e) { throw $this->handle($e); } if ($ct < 1 || !$this->cacher) { return $res; } $this->cacher->set($item_id, $now, 0, $this->cacheTimeout()); if ($this->inTran()) { Transaction::onRollback(array($cache, 'delete'), array($item_id)); } return $res; }
/** * Write the item_id => total quantity pairing into the cache. * @param int item id * @param int total count, after db write * if the total is less than zero, write it in as undefined in the cache so it doesn't hit the * db again. With tally, the total is a number, but the serial total will be a quantity object. * no matter. we can get it's total value easily enough by just getting strval of it. * if there is a transaction attached, set up a callback to delete this key if the transaction doesn't work. * can't delete the cache key for history since variations are endless, but we can bust the key * using last touch. if we aren't in a transaction, just bust last touch right away. * check the id index so we can update it in the cache. * if nothing left of a given item, remove it from the index. * if the item id is in the index, no more work needed. * make sure the index is sorted the way it is supposed to be. * always sorted in numeric order of item id. */ protected function writeToCache($item_id, $total) { $cache = $this->cacher; $timeout = $this->cacheTimeout(); $cache->set($item_id, Base::quantify($total) > 0 ? $total : Store\Callback::UNDEF, $timeout); if ($this->inTran()) { Transaction::onRollback(array($cache, 'delete'), array($item_id)); Transaction::onRollback(array($this, 'lastTouch'), array(TRUE)); Transaction::onCommit(array($this, 'lastTouch'), array(TRUE)); } else { $this->lastTouch(TRUE); } $index = $cache->get(self::INDEX_CACHEKEY); if (!is_array($index)) { return; } if (Base::quantify($total) > 0) { if (in_array($item_id, $index)) { return; } $index[] = $item_id; sort($index, SORT_NUMERIC); } else { $found = array_keys($index, $item_id); if (count($found) < 1) { return; } foreach ($found as $k) { unset($index[$k]); } } $cache->set(self::INDEX_CACHEKEY, $index, $timeout); }
/** * write the record into the cache. */ protected function writeToCache(Listing $listing) { $cache = $this->cache(); $timeout = $this->cacheTimeout(); $cache->set($listing->id, $listing, 0, $timeout); if (!Transaction::atStart()) { Transaction::onRollback(array($cache, 'delete'), array($listing->id)); } $this->updateListingSearchVectors($listing); return $listing; }