Created
May 23, 2011 06:14
-
-
Save comfuture/986309 to your computer and use it in GitHub Desktop.
using database as filesystem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class DBStorageStream | |
{ | |
const DDL = <<<EOF | |
CREATE TABLE IF NOT EXISTS `table_dbfs` ( | |
`path` VARCHAR(255) NOT NULL PRIMARY KEY, | |
`data` LONGTEXT, | |
`is_dir` CHAR(1) NOT NULL DEFAULT 'N', | |
`created_at` DATETIME, | |
`updated_at` DATETIME | |
); | |
EOF; | |
private $pdo; | |
private $mode; | |
private $path; | |
private $row; | |
private $posotion = 0; | |
public function stream_open($path, $mode, $options, &$opened_path) | |
{ | |
$parsed = parse_url($path); | |
$dbinfo = $GLOBALS['__dbfs_' . $parsed['host']]; | |
if (!isset($dbinfo)) | |
throw new Exception($parsed['host'] . ' is not mounted'); | |
$this->pdo = new PDO($dbinfo['dsn'], $dbinfo['username'], $dbinfo['password']); | |
$this->mode = $mode; | |
$this->path = $parsed['path']; | |
if ($mode == 'r') { | |
try { | |
$sql = "SELECT * FROM `table_dbfs` WHERE `path`=?"; | |
$stmt = $this->pdo->prepare($sql); | |
$stmt->execute(array($this->path)); | |
$this->row = $stmt->fetch(); | |
$this->position = 0; | |
} catch (PDOException $e) { | |
return false; | |
} | |
} | |
return true; | |
} | |
private function create_table() | |
{ | |
$this->pdo->execute(self::DDL); | |
} | |
public function stream_read($count) | |
{ | |
if (!$this->row) | |
return false; | |
$bytes = substr($this->row['data'], $this->position, $count); | |
$this->position += $count; | |
return $bytes; | |
} | |
public function stream_write($data) | |
{ | |
if ($this->mode != 'w') | |
return 0; | |
$sql = "INSERT INTO `table_dbfs` (`path`, `data`, `created_at`, `updated_at`)" . | |
"VALUES(?, ?, NOW(), NOW())"; | |
$stmt = $this->pdo->prepare($sql); | |
$stmt->execute(array($this->path, $data)); | |
return strlen($data); | |
} | |
public function stream_eof() | |
{ | |
if (null === $this->row) | |
return true; | |
return ($this->position == sizeof($this->row['data'])); | |
} | |
public function stream_stat() | |
{ | |
$stat = array(); | |
$stat[0] = $stat['dev'] = 0; | |
$stat[1] = $stat['ino'] = 0; | |
$stat[2] = $stat['mode'] = 0; | |
$stat[3] = $stat['nlink'] = 0; | |
$stat[4] = $stat['uid'] = 0; | |
$stat[5] = $stat['gid'] = 0; | |
$stat[6] = $stat['rdev'] = 0; | |
if ($this->row) { | |
$stat[7] = $stat['size'] = strlen($this->row['data']); | |
$stat[8] = $stat['atime'] = date('U'); | |
$stat[9] = $stat['mtime'] = $this->row['updated_at']; | |
$stat[10] = $stat['ctime'] = $this->row['created_at']; | |
} | |
$stat[11] = $stat['blksize'] = -1; | |
$stat[12] = $stat['blocks'] = -1; | |
return $stat; | |
} | |
public function stream_close() | |
{ | |
// TODO: close pdo handle | |
$this->pdo = null; | |
} | |
public function unlink($path) | |
{ | |
$sql = "DELETE FROM `table_dbfs` WHERE `path`=?"; | |
$stmt = $this->pdo->prepare($sql); | |
$rows = $stmt->execute(array($path)); | |
return ($rows == 1); | |
} | |
public function rename($path_from, $path_to) | |
{ | |
$sql = "UPDATE `table_dbfs` SET `path`=? WHERE `path`=?"; | |
$stmt = $this->pdo->prepare($sql); | |
$rows = $stmt->execute(array($path_to, $path_from)); | |
return ($rows == 1); | |
} | |
public function mkdir($path, $mode, $options) | |
{ | |
$sql = "INSERT INTO `table_dbfs` (`path`, `is_dir`, `created_at`, `updated_at`) " . | |
"VALUES (?, 'Y', NOW(), NOW())"; | |
$stmt = $this->pdo->prepare($sql); | |
$rows = $stmt->execute(array($path)); | |
return ($row == 1); | |
} | |
public function rmdir($path) | |
{ | |
return $this->unlink($path); | |
} | |
} | |
function dbfs_mount($local, $path) | |
{ | |
$parsed = parse_url($path); | |
$GLOBALS['__dbfs_' . $local] = $dbinfo = array( | |
'dsn' => $parsed['scheme'] . ':host=' . $parsed['host'] . | |
';dbname=' . substr($parsed['path'], 1), | |
'username' => $parsed['user'], | |
'password' => $parsed['pass'] | |
); | |
// check if table exists | |
try { | |
$fp = fopen('dbfs://' . $local . '/foo', 'r'); | |
$waste = fread($fp, 1); | |
fclose($fp); | |
} catch (PDOException $e) { | |
if (1146 == $e->getCode()) { // XXX: mysql only for now | |
$pdo = new PDO($dbinfo['dsn'], $dbinfo['username'], $dbinfo['password']); | |
$pdo->exec(DBStorageStream::DDL); | |
// catch exception again? | |
} | |
} | |
} | |
stream_register_wrapper('dbfs', 'DBStorageStream'); | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once 'DBStorageStream.php'; | |
dbfs_mount('test', 'mysql://user:pass@localhost/dbfs'); | |
$fp = fopen('dbfs://test/image.jpg', 'w'); | |
fwrite($fp, file_get_contents('image.jpg')); | |
fclose($fp); | |
$fp = fopen('dbfs://test/image.jpg', 'r'); | |
echo fread($fp, 1024); | |
fclose($fp); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment