Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.VaultDiskDir.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @package FDL
5 */
6 /**
7  * Directories for vault files
8  * @author Anakeen
9  * @package FDL
10  */
11 // ---------------------------------------------------------------
12 // $Id: Class.VaultDiskDir.php,v 1.10 2006/12/06 11:12:13 eric Exp $
13 // $Source: /home/cvsroot/anakeen/freedom/vault/Class/Class.VaultDiskDir.php,v $
14 // ---------------------------------------------------------------
15 //
16 // ---------------------------------------------------------------
17 include_once ("Class.QueryDb.php");
18 
19 define("VAULT_MAXENTRIESBYDIR", 1000);
20 define("VAULT_MAXDIRBYDIR", 100);
21 class VaultDiskDir extends DbObj
22 {
23 
24  public $fields = array(
25  "id_dir",
26  "id_fs",
27  "isfull",
28  "size",
29  "l_path"
30  );
31  public $id_fields = array(
32  "id_dir"
33  );
34  public $id_dir;
35  public $id_fs;
36  public $l_path;
37 
38  public $dbtable_tmpl = "vaultdiskdir%s";
39  public $order_by = "";
40  public $seq_tmpl = "seq_id_vaultdiskdir%s";
41  public $sqlcreate_tmpl = <<<'SQL'
42 
43  create table vaultdiskdir:specific: ( id_dir int not null,
44  primary key (id_dir),
45  id_fs int,
46  isfull bool,
47  size bigint,
48  l_path varchar(2048)
49  );
50  create sequence seq_id_vaultdiskdir:specific: start 10;
51  CREATE INDEX vault_isfull:specific: on vaultdiskdir:specific: (isfull);
53 
54  public $specific;
55  public $seq;
56  public $isfull;
57  public $size;
58  protected $dirsToClose = [];
59  // --------------------------------------------------------------------
60  function __construct($dbaccess, $id_dir = '', $def = '')
61  {
62  // --------------------------------------------------------------------
63  $this->specific = $def;
64  $this->dbtable = sprintf($this->dbtable_tmpl, $this->specific);
65  $this->sqlcreate = str_replace(":specific:", $this->specific, $this->sqlcreate_tmpl);
66  $this->seq = sprintf($this->seq_tmpl, $this->specific);
67 
68  parent::__construct($dbaccess, $id_dir);
69  }
70  /**
71  * return name of next directory
72  * 1/1 => 1/2
73  * 1/10 => 2/1
74  * 1/2 = 1/3
75  *
76  * @param string $d path to file
77  * @param int $max
78  *
79  * @return string
80  */
81  function nextdir($d, $max = VAULT_MAXDIRBYDIR)
82  {
83  $td = explode('/', $d);
84  $dend = intval(end($td));
85  $ak = array_keys($td);
86  $lastkey = end($ak);
87  if ($dend < $max) {
88  $td[$lastkey]++;
89  } else {
90  $good = false;;
91  $key = $lastkey;
92  while (($key >= 0) && (!$good)) {
93  $prev = intval(prev($td));
94  $td[$key] = 1;
95  $key--;
96  if ($prev) {
97  if ($prev < $max) {
98  $td[$key]++;
99  $good = true;
100  }
101  }
102  }
103  if (!$good) $td = array_fill(0, count($td) + 1, 1);
104  }
105  return implode('/', $td);
106  }
107 
108  public function complete()
109  {
110  $this->isfull = ($this->isfull === 't');
111  }
112  // --------------------------------------------------------------------
113  function SetFreeDir($fs)
114  {
115  // --------------------------------------------------------------------
116  $query = new QueryDb($this->dbaccess, $this->dbtable);
117  $id_fs = $fs["id_fs"];
118  $query->basic_elem->sup_where = array(
119  "id_fs=" . $id_fs,
120  "not isfull"
121  );
122  $query->order_by = "id_dir";
123  // Lock directory : force each process to use its proper dir
124  $sql = sprintf("select * from %s where id_fs=%d and not isfull and pg_try_advisory_xact_lock(id_dir, %d) order by id_fs limit 1 for update;", pg_escape_identifier($this->dbtable) , $id_fs, unpack("i", "VLCK") [1]);
125 
126  $err = "";
127  $dirs = $query->Query(0, 0, "TABLE", $sql);
128 
129  $this->dirsToClose = [];
130  if ($query->nb > 0) {
131  $needNewOneDir = true;
132  foreach ($dirs as $dir) {
133  $this->Select($dir["id_dir"]);
134 
135  $sql = sprintf("SELECT count(*) FROM vaultdiskstorage WHERE id_dir=%d", $this->id_dir);
136  $t = $query->Query(0, 0, "TABLE", $sql);
137 
138  $count = intval($t[0]["count"]);
139  if ($count >= (VAULT_MAXENTRIESBYDIR - 1)) {
140  $this->dirsToClose[] = $this->id_dir;
141  if ($count < VAULT_MAXENTRIESBYDIR) {
142  $needNewOneDir = false;
143  break;
144  }
145  } else {
146  $needNewOneDir = false;
147  break;
148  }
149  }
150  if ($needNewOneDir) {
151  $err = $this->createDirectory($fs);
152  }
153  } else {
154  $err = $this->createDirectory($fs);
155  }
156  return $err;
157  }
158 
159  public function closeDir()
160  {
161  $err = '';
162  foreach ($this->dirsToClose as $dirid) {
163  if ($dirid) {
164  $query = new QueryDb($this->dbaccess, $this->dbtable);
165  $sql = sprintf("SELECT sum(size) FROM vaultdiskstorage WHERE id_dir=%d", $dirid);
166  $t = $query->Query(0, 0, "TABLE", $sql);
167  if ($query->nb > 0) {
168  $this->select($dirid);
169  $this->isfull = 't';
170  $this->size = $t[0]["sum"];
171  $err.= $this->modify();
172  }
173  }
174  }
175  $this->dirsToClose = [];
176  return $err;
177  }
178 
179  protected function createDirectory($fs)
180  {
181  $id_fs = $fs["id_fs"];
182  $query = new QueryDb($this->dbaccess, $this->dbtable);
183  $t = $query->Query(0, 0, "TABLE", "SELECT * from vaultdiskdirstorage where id_fs=" . intval($id_fs) . " order by id_dir desc limit 1");
184  $lpath = $t[0]["l_path"];
185  $npath = $this->nextdir($lpath);
186  $rpath = $fs["r_path"];
187 
188  $absDir = sprintf("%s/%s", $rpath, $npath);
189 
190  while (is_dir($absDir)) {
191  $npath = $this->nextdir($npath);
192  $absDir = sprintf("%s/%s", $rpath, $npath);
193  }
194 
195  $this->id_dir = "";
196  $this->id_fs = $id_fs;
197  $this->l_path = $npath;
198  $this->isfull = 'f';
199  $this->size = null;
200  $err = $this->Add();
201  if ($err == "") {
202  $dirpath = $rpath . "/" . $npath;
203  if (!is_dir($dirpath)) {
204  mkdir($dirpath, VaultFile::VAULT_DMODE, true);
205  }
206  } else {
207  error_log("Vault dirs full");
208  return sprintf(_("cannot extend vault: %s") , $err);
209  }
210  return $err;
211  }
212  // --------------------------------------------------------------------
213  function PreInsert()
214  {
215  // --------------------------------------------------------------------
216  if ($this->Exists($this->l_path, $this->id_fs)) return (_("Directory already exists"));
217  $this->exec_query("select nextval ('" . $this->seq . "')");
218  $arr = $this->fetch_array(0);
219  $this->id_dir = $arr["nextval"];
220  return '';
221  }
222  // --------------------------------------------------------------------
223  function Exists($path, $id_fs)
224  {
225  // --------------------------------------------------------------------
226  $query = new QueryDb($this->dbaccess, $this->dbtable);
227  $query->basic_elem->sup_where = array(
228  "l_path='" . $path . "'",
229  "id_fs=" . $id_fs
230  );
231  $query->Query(0, 0, "TABLE");
232  return ($query->nb > 0);
233  }
234  // --------------------------------------------------------------------
235  function DelEntry()
236  {
237  if ($this->isfull) {
238  $this->isfull = false;
239  $this->Modify();
240  }
241  }
242 }
__construct($dbaccess, $id_dir= '', $def= '')
exec_query($sql, $lvl=0, $prepare=false)
const VAULT_DMODE
Add($nopost=false, $nopre=false)
nextdir($d, $max=VAULT_MAXDIRBYDIR)
Select($id)
const VAULT_MAXENTRIESBYDIR
$d
Definition: dav.php:77
fetch_array($c, $type=PGSQL_ASSOC)
CREATE INDEX vault_isfull
modify($nopost=false, $sfields="", $nopre=false)
$path
Definition: dav.php:39
Exists($path, $id_fs)
const VAULT_MAXDIRBYDIR
$s start
$dir
Definition: resizeimg.php:144
create sequence seq_id_vaultdiskdir
if(($docid!==0)&&(!is_numeric($docid))) $query
if($file) if($subject==""&&$file) if($subject=="") $err
← centre documentaire © anakeen