· 8 years ago · Jul 31, 2018, 04:02 PM
1<?php
2
3class DBStorageStream
4{
5 const DDL = <<<EOF
6CREATE TABLE IF NOT EXISTS `table_dbfs` (
7 `path` VARCHAR(255) NOT NULL PRIMARY KEY,
8 `data` LONGTEXT,
9 `is_dir` CHAR(1) NOT NULL DEFAULT 'N',
10 `created_at` DATETIME,
11 `updated_at` DATETIME
12);
13EOF;
14
15 private $pdo;
16 private $mode;
17 private $path;
18 private $row;
19 private $posotion = 0;
20
21 public function stream_open($path, $mode, $options, &$opened_path)
22 {
23 $parsed = parse_url($path);
24 $dbinfo = $GLOBALS['__dbfs_' . $parsed['host']];
25 if (!isset($dbinfo))
26 throw new Exception($parsed['host'] . ' is not mounted');
27
28 $this->pdo = new PDO($dbinfo['dsn'], $dbinfo['username'], $dbinfo['password']);
29 $this->mode = $mode;
30 $this->path = $parsed['path'];
31 if ($mode == 'r') {
32 try {
33 $sql = "SELECT * FROM `table_dbfs` WHERE `path`=?";
34 $stmt = $this->pdo->prepare($sql);
35 $stmt->execute(array($this->path));
36 $this->row = $stmt->fetch();
37 $this->position = 0;
38 } catch (PDOException $e) {
39 return false;
40 }
41 }
42 return true;
43 }
44
45 private function create_table()
46 {
47 $this->pdo->execute(self::DDL);
48 }
49
50 public function stream_read($count)
51 {
52 if (!$this->row)
53 return false;
54 $bytes = substr($this->row['data'], $this->position, $count);
55 $this->position += $count;
56 return $bytes;
57 }
58
59 public function stream_write($data)
60 {
61 if ($this->mode != 'w')
62 return 0;
63 $sql = "INSERT INTO `table_dbfs` (`path`, `data`, `created_at`, `updated_at`)" .
64 "VALUES(?, ?, NOW(), NOW())";
65 $stmt = $this->pdo->prepare($sql);
66 $stmt->execute(array($this->path, $data));
67 return strlen($data);
68 }
69
70 public function stream_eof()
71 {
72 if (null === $this->row)
73 return true;
74 return ($this->position == sizeof($this->row['data']));
75 }
76
77 public function stream_stat()
78 {
79 $stat = array();
80
81 $stat[0] = $stat['dev'] = 0;
82 $stat[1] = $stat['ino'] = 0;
83 $stat[2] = $stat['mode'] = 0;
84 $stat[3] = $stat['nlink'] = 0;
85 $stat[4] = $stat['uid'] = 0;
86 $stat[5] = $stat['gid'] = 0;
87 $stat[6] = $stat['rdev'] = 0;
88 if ($this->row) {
89 $stat[7] = $stat['size'] = strlen($this->row['data']);
90 $stat[8] = $stat['atime'] = date('U');
91 $stat[9] = $stat['mtime'] = $this->row['updated_at'];
92 $stat[10] = $stat['ctime'] = $this->row['created_at'];
93 }
94 $stat[11] = $stat['blksize'] = -1;
95 $stat[12] = $stat['blocks'] = -1;
96 return $stat;
97 }
98
99 public function stream_close()
100 {
101 // TODO: close pdo handle
102 $this->pdo = null;
103 }
104
105 public function unlink($path)
106 {
107 $sql = "DELETE FROM `table_dbfs` WHERE `path`=?";
108 $stmt = $this->pdo->prepare($sql);
109 $rows = $stmt->execute(array($path));
110 return ($rows == 1);
111 }
112
113 public function rename($path_from, $path_to)
114 {
115 $sql = "UPDATE `table_dbfs` SET `path`=? WHERE `path`=?";
116 $stmt = $this->pdo->prepare($sql);
117 $rows = $stmt->execute(array($path_to, $path_from));
118 return ($rows == 1);
119 }
120
121 public function mkdir($path, $mode, $options)
122 {
123 $sql = "INSERT INTO `table_dbfs` (`path`, `is_dir`, `created_at`, `updated_at`) " .
124 "VALUES (?, 'Y', NOW(), NOW())";
125 $stmt = $this->pdo->prepare($sql);
126 $rows = $stmt->execute(array($path));
127 return ($row == 1);
128 }
129
130 public function rmdir($path)
131 {
132 return $this->unlink($path);
133 }
134}
135
136function dbfs_mount($local, $path)
137{
138 $parsed = parse_url($path);
139 $GLOBALS['__dbfs_' . $local] = $dbinfo = array(
140 'dsn' => $parsed['scheme'] . ':host=' . $parsed['host'] .
141 ';dbname=' . substr($parsed['path'], 1),
142 'username' => $parsed['user'],
143 'password' => $parsed['pass']
144 );
145
146 // check if table exists
147 try {
148 $fp = fopen('dbfs://' . $local . '/foo', 'r');
149 $waste = fread($fp, 1);
150 fclose($fp);
151 } catch (PDOException $e) {
152 if (1146 == $e->getCode()) { // XXX: mysql only for now
153 $pdo = new PDO($dbinfo['dsn'], $dbinfo['username'], $dbinfo['password']);
154 $pdo->exec(DBStorageStream::DDL);
155 // catch exception again?
156 }
157 }
158}
159stream_register_wrapper('dbfs', 'DBStorageStream');
160?>