From abd38899f6f1fcf7c8f16eb83356c8ce1070cf71 Mon Sep 17 00:00:00 2001 From: dakkar Date: Thu, 17 Mar 2011 00:01:25 +0000 Subject: import from http://tobyelliott.wordpress.com/2009/09/11/weave-minimal-server/ --- weave_storage.php | 787 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 787 insertions(+) create mode 100644 weave_storage.php (limited to 'weave_storage.php') diff --git a/weave_storage.php b/weave_storage.php new file mode 100644 index 0000000..c82873d --- /dev/null +++ b/weave_storage.php @@ -0,0 +1,787 @@ +_username = $username; + $path = explode('/', $_SERVER['SCRIPT_FILENAME']); + $db_name = 'weave_db'; + array_pop($path); + array_push($path, $db_name); + $db_name = implode('/', $path); + + $create_tables = !file_exists($db_name); + + try + { + $this->_dbh = new PDO('sqlite:' . $db_name); + $this->_dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + catch( PDOException $exception ) + { + throw new Exception("Database unavailable", 503); + } + + if ($create_tables) + $this->setup_db(); + } + + function get_connection() + { + return $this->_dbh; + } + + function begin_transaction() + { + try + { + $this->_dbh->beginTransaction(); + } + catch( PDOException $exception ) + { + error_log("begin_transaction: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + return 1; + } + + function commit_transaction() + { + $this->_dbh->commit(); + return 1; + } + + function get_max_timestamp($collection) + { + if (!$collection) + { + return 0; + } + + try + { + $select_stmt = 'select max(modified) from wbo where username = :username and collection = :collection'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->bindParam(':collection', $collection); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("get_max_timestamp: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + $result = $sth->fetchColumn(); + return round((float)$result, 2); + } + + function get_collection_list() + { + try + { + $select_stmt = 'select distinct(collection) from wbo where username = :username'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("get_collection_list: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + + $collections = array(); + while ($result = $sth->fetchColumn()) + { + $collections[] = $result; + } + + return $collections; + } + + + function get_collection_list_with_timestamps() + { + try + { + $select_stmt = 'select collection, max(modified) as timestamp from wbo where username = :username group by collection'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("get_collection_list: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + $collections = array(); + while ($result = $sth->fetch(PDO::FETCH_NUM)) + { + $collections[$result[0]] = (float)$result[1]; + } + + return $collections; + } + + function get_collection_list_with_counts() + { + try + { + $select_stmt = 'select collection, count(*) as ct from wbo where username = :username group by collection'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("get_collection_list_with_counts: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + + $collections = array(); + while ($result = $sth->fetch(PDO::FETCH_NUM)) + { + $collections[$result[0]] = (int)$result[1]; + } + + return $collections; + } + + function store_object(&$wbo) + { + + try + { + $insert_stmt = 'replace into wbo (username, id, collection, parentid, predecessorid, sortindex, modified, payload, payload_size, depth) + values (:username, :id, :collection, :parentid, :predecessorid, :sortindex, :modified, :payload, :payload_size, :depth)'; + $sth = $this->_dbh->prepare($insert_stmt); + $sth->bindParam(':username', $this->_username); + $sth->bindParam(':id', $wbo->id()); + $sth->bindParam(':collection', $wbo->collection()); + $sth->bindParam(':parentid', $wbo->parentid()); + $sth->bindParam(':predecessorid', $wbo->predecessorid()); + $sth->bindParam(':depth', $wbo->depth()); + $sth->bindParam(':sortindex', $wbo->sortindex()); + $sth->bindParam(':modified', $wbo->modified()); + $sth->bindParam(':payload', $wbo->payload()); + $sth->bindParam(':payload_size', $wbo->payload_size()); + + $sth->execute(); + + } + catch( PDOException $exception ) + { + error_log("store_object: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + return 1; + } + + + function update_object(&$wbo) + { + $update = "update wbo set "; + $params = array(); + $update_list = array(); + + #make sure we have an id and collection. No point in continuing otherwise + if (!$wbo->id() || !$wbo->collection()) + { + error_log('Trying to update without a valid id or collection!'); + return 0; + } + + if ($wbo->parentid_exists()) + { + $update_list[] = "parentid = ?"; + $params[] = $wbo->parentid(); + } + + if ($wbo->parentid_exists()) + { + $update_list[] = "predecessorid = ?"; + $params[] = $wbo->predecessorid(); + } + + if ($wbo->depth_exists()) + { + $update_list[] = "depth = ?"; + $params[] = $wbo->depth(); + } + + if ($wbo->sortindex_exists()) + { + $update_list[] = "sortindex = ?"; + $params[] = $wbo->sortindex(); + } + + if ($wbo->payload_exists()) + { + $update_list[] = "payload = ?"; + $update_list[] = "payload_size = ?"; + $params[] = $wbo->payload(); + $params[] = $wbo->payload_size(); + } + + # Don't modify the timestamp on a depth-only change + if ($wbo->parentid_exists() || $wbo->payload_exists()) + { + #better make sure we have a modified date. Should have been handled earlier + if (!$wbo->modified_exists()) + { + error_log("Called update_object with no defined timestamp. Please check"); + $wbo->modified(microtime(1)); + } + $update_list[] = "modified = ?"; + $params[] = $wbo->modified(); + + } + + + if (count($params) == 0) + { + return 0; + } + + $update .= join($update_list, ","); + + $update .= " where username = ? and collection = ? and id = ?"; + $params[] = $this->_username; + $params[] = $wbo->collection(); + $params[] = $wbo->id(); + + try + { + $sth = $this->_dbh->prepare($update); + $sth->execute($params); + } + catch( PDOException $exception ) + { + error_log("update_object: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + return 1; + } + + function delete_object($collection, $id) + { + try + { + $delete_stmt = 'delete from wbo where username = :username and collection = :collection and id = :id'; + $sth = $this->_dbh->prepare($delete_stmt); + $sth->bindParam(':username', $this->_username); + $sth->bindParam(':collection', $collection); + $sth->bindParam(':id', $id); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("delete_object: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + return 1; + } + + function delete_objects($collection, $id = null, $parentid = null, $predecessorid = null, $newer = null, + $older = null, $sort = null, $limit = null, $offset = null, $ids = null, + $index_above = null, $index_below = null) + { + $params = array(); + $select_stmt = ''; + + if ($limit || $offset || $sort) + { + #sqlite can't do sort or limit deletes without special compiled versions + #so, we need to grab the set, then delete it manually. + + $params = $this->retrieve_objects($collection, $id, 0, 0, $parentid, $predecessorid, $newer, $older, $sort, $limit, $offset, $ids, $index_above, $index_below); + if (!count($params)) + { + return 1; #nothing to delete + } + $paramqs = array(); + $select_stmt = "delete from wbo where username = ? and collection = ? and id in (" . join(", ", array_pad($paramqs, count($params), '?')) . ")"; + array_unshift($params, $collection); + array_unshift($params, $username); + } + else + { + + $select_stmt = "delete from wbo where username = ? and collection = ?"; + $params[] = $this->_username; + $params[] = $collection; + + + if ($id) + { + $select_stmt .= " and id = ?"; + $params[] = $id; + } + + if ($ids && count($ids) > 0) + { + $qmarks = array(); + $select_stmt .= " and id in ("; + foreach ($ids as $temp) + { + $params[] = $temp; + $qmarks[] = '?'; + } + $select_stmt .= implode(",", $qmarks); + $select_stmt .= ')'; + } + + if ($parentid) + { + $select_stmt .= " and parentid = ?"; + $params[] = $parentid; + } + + if ($predecessorid) + { + $select_stmt .= " and predecessorid = ?"; + $params[] = $parentid; + } + + if ($index_above) + { + $select_stmt .= " and sortindex > ?"; + $params[] = $parentid; + } + + if ($index_below) + { + $select_stmt .= " and sortindex < ?"; + $params[] = $parentid; + } + + if ($newer) + { + $select_stmt .= " and modified > ?"; + $params[] = $newer; + } + + if ($older) + { + $select_stmt .= " and modified < ?"; + $params[] = $older; + } + + if ($sort == 'index') + { + $select_stmt .= " order by sortindex desc"; + } + else if ($sort == 'newest') + { + $select_stmt .= " order by modified desc"; + } + else if ($sort == 'oldest') + { + $select_stmt .= " order by modified"; + } + + if ($limit) + { + $select_stmt .= " limit " . intval($limit); + if ($offset) + { + $select_stmt .= " offset " . intval($offset); + } + } + } + + try + { + $sth = $this->_dbh->prepare($select_stmt); + $sth->execute($params); + } + catch( PDOException $exception ) + { + error_log("delete_objects: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + return 1; + } + + function retrieve_object($collection, $id) + { + try + { + $select_stmt = 'select * from wbo where username = :username and collection = :collection and id = :id'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->bindParam(':collection', $collection); + $sth->bindParam(':id', $id); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("retrieve_object: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + $result = $sth->fetch(PDO::FETCH_ASSOC); + + $wbo = new wbo(); + $wbo->populate($result); + return $wbo; + } + + function retrieve_objects($collection, $id = null, $full = null, $direct_output = null, $parentid = null, + $predecessorid = null, $newer = null, $older = null, $sort = null, + $limit = null, $offset = null, $ids = null, + $index_above = null, $index_below = null, $depth = null) + { + $full_list = $full ? '*' : 'id'; + + + $select_stmt = "select $full_list from wbo where username = ? and collection = ?"; + $params[] = $this->_username; + $params[] = $collection; + + + if ($id) + { + $select_stmt .= " and id = ?"; + $params[] = $id; + } + + if ($ids && count($ids) > 0) + { + $qmarks = array(); + $select_stmt .= " and id in ("; + foreach ($ids as $temp) + { + $params[] = $temp; + $qmarks[] = '?'; + } + $select_stmt .= implode(",", $qmarks); + $select_stmt .= ')'; + } + + if ($ids && count($ids) > 0) + { + $qmarks = array(); + $select_stmt .= " and id in ("; + foreach ($ids as $temp) + { + $params[] = $temp; + $qmarks[] = '?'; + } + $select_stmt .= implode(",", $qmarks); + $select_stmt .= ')'; + } + + if ($parentid) + { + $select_stmt .= " and parentid = ?"; + $params[] = $parentid; + } + + + if ($predecessorid) + { + $select_stmt .= " and predecessorid = ?"; + $params[] = $predecessorid; + } + + if ($index_above) + { + $select_stmt .= " and sortindex > ?"; + $params[] = $parentid; + } + + if ($index_below) + { + $select_stmt .= " and sortindex < ?"; + $params[] = $parentid; + } + + if ($newer) + { + $select_stmt .= " and modified > ?"; + $params[] = $newer; + } + + if ($older) + { + $select_stmt .= " and modified < ?"; + $params[] = $older; + } + + + if ($depth) + { + $select_stmt .= " and depth = ?"; + $params[] = $depth; + } + + if ($sort == 'index') + { + $select_stmt .= " order by sortindex desc"; + } + else if ($sort == 'newest') + { + $select_stmt .= " order by modified desc"; + } + else if ($sort == 'oldest') + { + $select_stmt .= " order by modified"; + } + + if ($limit) + { + $select_stmt .= " limit " . intval($limit); + if ($offset) + { + $select_stmt .= " offset " . intval($offset); + } + } + + try + { + $sth = $this->_dbh->prepare($select_stmt); + $sth->execute($params); + } + catch( PDOException $exception ) + { + error_log("retrieve_collection: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + if ($direct_output) + return $direct_output->output($sth); + + $ids = array(); + while ($result = $sth->fetch(PDO::FETCH_ASSOC)) + { + if ($full) + { + $wbo = new wbo(); + $wbo->populate($result); + $ids[] = $wbo; + } + else + $ids[] = $result{'id'}; + } + return $ids; + } + + function get_storage_total() + { + try + { + $select_stmt = 'select round(sum(length(payload))/1024) from wbo where username = :username'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("get_storage_total: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + return (int)$sth->fetchColumn(); + } + + function get_user_quota() + { + return null; + } + + function delete_user($username) + { + if (!$username) + { + throw new Exception("3", 404); + } + + try + { + $delete_stmt = 'delete from users where username = :username'; + $sth = $this->_dbh->prepare($delete_stmt); + $sth->bindParam(':username', $username); + $sth->execute(); + $sth->closeCursor(); + + $delete_wbo_stmt = 'delete from wbo where username = :username'; + $sth = $this->_dbh->prepare($delete_wbo_stmt); + $sth->bindParam(':username', $username); + $sth->execute(); + + } + catch( PDOException $exception ) + { + error_log("delete_user: " . $exception->getMessage()); + return 0; + } + return 1; + } + + function create_user($username, $password) + { + try + { + $create_statement = "insert into users values (:username, :md5)"; + + $sth = $this->_dbh->prepare($create_statement); + $sth->bindParam(':username', $username); + $sth->bindParam(':md5', md5($password)); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("create_user:" . $exception->getMessage()); + return 0; + } + return 1; + } + + function change_password($username, $password) + { + try + { + $update_statement = "update users set md5 = :md5 where username = :username"; + + $sth = $this->_dbh->prepare($update_statement); + $sth->bindParam(':username', $username); + $sth->bindParam(':md5', md5($password)); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("change_password:" . $exception->getMessage()); + return 0; + } + return 1; + } + + function authenticate_user($password) + { + try + { + $select_stmt = 'select username from users where username = :username and md5 = :md5'; + $sth = $this->_dbh->prepare($select_stmt); + $sth->bindParam(':username', $this->_username); + $sth->bindParam(':md5', md5($password)); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("authenticate_user: " . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + + if (!$result = $sth->fetch(PDO::FETCH_ASSOC)) + { + return null; + } + + return 1; + } + + function setup_db() + { + + try + { + $create_statement = <<< end +create table wbo +( + username text, + id text, + collection text, + parentid text, + predecessorid int, + modified real, + sortindex int, + depth int, + payload text, + payload_size int, + primary key (username,collection,id) +) +end; + + $create_statement2 = <<< end +create table users +( + username text, + md5 text, + primary key (username) +) +end; + + $index1 = 'create index parentindex on wbo (username, parentid)'; + $index2 = 'create index predecessorindex on wbo (username, predecessorid)'; + $index3 = 'create index modifiedindex on wbo (username, collection, modified)'; + + + $sth = $this->_dbh->prepare($create_statement); + $sth->execute(); + $sth = $this->_dbh->prepare($create_statement2); + $sth->execute(); + $sth = $this->_dbh->prepare($index1); + $sth->execute(); + $sth = $this->_dbh->prepare($index2); + $sth->execute(); + $sth = $this->_dbh->prepare($index3); + $sth->execute(); + } + catch( PDOException $exception ) + { + error_log("initialize_user_db:" . $exception->getMessage()); + throw new Exception("Database unavailable", 503); + } + } +} + + + ?> \ No newline at end of file -- cgit v1.2.3