xref: /plugin/struct/meta/Assignments.php (revision 9353915d32a379ba7b6fa4d1ff68274608c5261e)
1<?php
2
3namespace plugin\struct\meta;
4
5/**
6 * Class Assignments
7 *
8 * Manages the assignment of schemas (table names) to pages and namespaces
9 *
10 * @package plugin\struct\meta
11 */
12class Assignments {
13
14    /** @var \helper_plugin_sqlite|null */
15    protected $sqlite;
16
17    /** @var  array All the assignments */
18    protected $assignments;
19
20    /**
21     * Assignments constructor.
22     */
23    public function __construct() {
24        /** @var \helper_plugin_struct_db $helper */
25        $helper = plugin_load('helper', 'struct_db');
26        $this->sqlite = $helper->getDB();
27
28        if($this->sqlite) $this->load();
29    }
30
31    /**
32     * Load existing assignments
33     */
34    protected function load() {
35        $sql = 'SELECT * FROM schema_assignments ORDER BY assign';
36        $res = $this->sqlite->query($sql);
37        $this->assignments = $this->sqlite->res2arr($res);
38        $this->sqlite->res_close($res);
39    }
40
41    /**
42     * Add a new assignment to the assignment table
43     *
44     * @param string $assign
45     * @param string $table
46     * @return bool
47     */
48    public function add($assign, $table) {
49        $sql = 'REPLACE INTO schema_assignments (assign, tbl) VALUES (?,?)';
50        return (bool) $this->sqlite->query($sql, array($assign, $table));
51    }
52
53    /**
54     * Remove an existing assignment from the assignment table
55     *
56     * @param string $assign
57     * @param string $table
58     * @return bool
59     */
60    public function remove($assign, $table) {
61        $sql = 'DELETE FROM schema_assignments WHERE assign = ? AND tbl = ?';
62        return (bool) $this->sqlite->query($sql, array($assign, $table));
63    }
64
65    /**
66     * Get the whole assignments table
67     *
68     * @return array
69     */
70    public function getAll() {
71        return $this->assignments;
72    }
73
74    /**
75     * Returns a list of table names assigned to the given page
76     *
77     * @param string $page
78     * @return string[] tables assigned
79     */
80    public function getPageAssignments($page) {
81        $tables = array();
82
83        $page = cleanID($page);
84        $pns = ':' . getNS($page) . ':';
85
86        foreach($this->assignments as $row) {
87            $ass = $row['assign'];
88            $tbl = $row['tbl'];
89
90            $ans = ':' . cleanID($ass) . ':';
91
92            if(substr($ass, -2) == '**') {
93                // upper namespaces match
94                if(strpos($pns, $ans) === 0) {
95                    $tables[] = $tbl;
96                }
97            } else if(substr($ass, -1) == '*') {
98                // namespaces match exact
99                if($ans == $pns) {
100                    $tables[] = $tbl;
101                }
102            } else {
103                // exact match
104                if(cleanID($ass) == $page) {
105                    $tables[] = $tbl;
106                }
107            }
108        }
109
110        return array_unique($tables);
111    }
112
113    /**
114     * Returns all tables of schemas that existed and stored data for the page back then
115     *
116     * @todo this is not used currently and can probably be removed again, because we're
117     *       always only interested in the current state of affairs, even when restoring.
118     *
119     * @param string $page
120     * @param string $ts
121     * @return array
122     */
123    public function getHistoricAssignments($page, $ts) {
124        $sql = "SELECT DISTINCT tbl FROM schemas WHERE ts <= ? ORDER BY ts DESC";
125        $res = $this->sqlite->query($sql, $ts);
126        $tables = $this->sqlite->res2arr($res);
127        $this->sqlite->res_close($res);
128
129        $assigned = array();
130        foreach ($tables as $row) {
131            $table = $row['tbl'];
132            $sql = "SELECT pid FROM data_$table WHERE pid = ? AND rev <= ? LIMIT 1";
133            $res = $this->sqlite->query($sql, $page, $ts);
134            $found = $this->sqlite->res2arr($res);
135            $this->sqlite->res_close($res);
136
137            if($found) $assigned[] = $table;
138        }
139
140        return $assigned;
141    }
142}
143