mirror of
https://github.com/cosmocode/dokuwiki-plugin-struct.git
synced 2025-07-29 11:59:24 +00:00
Start unifying schema types
Schemas per se are type agnostic, isLookup property is removed. Data is stored and accessed differently based on how it is entered and retrieved. The crucial change is introduction of the composite key of pid and rid. Previous page data utilizes rid = 0 to differentiate itself. Other types, notably lookup, have autoincrementing rid. Database migration is not implemented yet.
This commit is contained in:
@ -54,10 +54,11 @@ class schemaBuilder_struct_test extends StructTest {
|
|||||||
$tableSQL = $this->sqlite->res2single($res);
|
$tableSQL = $this->sqlite->res2single($res);
|
||||||
$this->sqlite->res_close($res);
|
$this->sqlite->res_close($res);
|
||||||
$expected_tableSQL = "CREATE TABLE data_testtable (
|
$expected_tableSQL = "CREATE TABLE data_testtable (
|
||||||
pid NOT NULL,
|
pid TEXT DEFAULT NULL,
|
||||||
rev INTEGER NOT NULL,
|
rid INTEGER,
|
||||||
|
rev INTEGER,
|
||||||
latest BOOLEAN NOT NULL DEFAULT 0, col1 DEFAULT '', col2 DEFAULT '',
|
latest BOOLEAN NOT NULL DEFAULT 0, col1 DEFAULT '', col2 DEFAULT '',
|
||||||
PRIMARY KEY(pid, rev)
|
PRIMARY KEY(pid, rid, rev)
|
||||||
)";
|
)";
|
||||||
|
|
||||||
$res = $this->sqlite->query("SELECT * FROM types");
|
$res = $this->sqlite->query("SELECT * FROM types");
|
||||||
|
@ -14,11 +14,12 @@ abstract class AccessTable extends meta\AccessTable {
|
|||||||
* @return meta\AccessTableLookup|AccessTableData
|
* @return meta\AccessTableLookup|AccessTableData
|
||||||
*/
|
*/
|
||||||
public static function bySchema(Schema $schema, $pid, $ts = 0) {
|
public static function bySchema(Schema $schema, $pid, $ts = 0) {
|
||||||
if($schema->isLookup()) {
|
// FIXME will we still need that?
|
||||||
return new meta\AccessTableLookup($schema, $pid, $ts); // FIXME not mocked, yet
|
// if($schema->isLookup()) {
|
||||||
} else {
|
// return new meta\AccessTableLookup($schema, $pid, $ts); // FIXME not mocked, yet
|
||||||
return new AccessTableData($schema, $pid, $ts);
|
// } else {
|
||||||
}
|
// }
|
||||||
|
return new AccessTableData($schema, $pid, $ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function byTableName($tablename, $pid, $ts = 0) {
|
public static function byTableName($tablename, $pid, $ts = 0) {
|
||||||
|
@ -116,7 +116,7 @@ class action_plugin_struct_inline extends DokuWiki_Action_Plugin {
|
|||||||
throw new StructException('inline save error: init');
|
throw new StructException('inline save error: init');
|
||||||
}
|
}
|
||||||
self::checkCSRF();
|
self::checkCSRF();
|
||||||
if(!$this->schemadata->getSchema()->isLookup()) {
|
if(!$this->schemadata->getRid()) {
|
||||||
$this->checkPage();
|
$this->checkPage();
|
||||||
$assignments = Assignments::getInstance();
|
$assignments = Assignments::getInstance();
|
||||||
$tables = $assignments->getPageAssignments($this->pid, true);
|
$tables = $assignments->getPageAssignments($this->pid, true);
|
||||||
@ -140,7 +140,7 @@ class action_plugin_struct_inline extends DokuWiki_Action_Plugin {
|
|||||||
$tosave[$this->column->getLabel()] = $value;
|
$tosave[$this->column->getLabel()] = $value;
|
||||||
|
|
||||||
// save
|
// save
|
||||||
if($this->schemadata->getSchema()->isLookup()) {
|
if($this->schemadata->getRid() && !$this->schemadata->getPid()) {
|
||||||
$revision = 0;
|
$revision = 0;
|
||||||
} else {
|
} else {
|
||||||
$revision = helper_plugin_struct::createPageRevision($this->pid, 'inline edit');
|
$revision = helper_plugin_struct::createPageRevision($this->pid, 'inline edit');
|
||||||
@ -151,7 +151,7 @@ class action_plugin_struct_inline extends DokuWiki_Action_Plugin {
|
|||||||
if(!$this->schemadata->saveData($tosave)) {
|
if(!$this->schemadata->saveData($tosave)) {
|
||||||
throw new StructException('saving failed');
|
throw new StructException('saving failed');
|
||||||
}
|
}
|
||||||
if(!$this->schemadata->getSchema()->isLookup()) {
|
if(!$this->schemadata->getRid()) {
|
||||||
// make sure this schema is assigned
|
// make sure this schema is assigned
|
||||||
/** @noinspection PhpUndefinedVariableInspection */
|
/** @noinspection PhpUndefinedVariableInspection */
|
||||||
$assignments->assignPageSchema(
|
$assignments->assignPageSchema(
|
||||||
|
@ -85,16 +85,16 @@ class action_plugin_struct_lookup extends DokuWiki_Action_Plugin
|
|||||||
{
|
{
|
||||||
global $INPUT;
|
global $INPUT;
|
||||||
$tablename = $INPUT->str('schema');
|
$tablename = $INPUT->str('schema');
|
||||||
$pid = $INPUT->int('pid');
|
$rid = $INPUT->int('rid');
|
||||||
if (!$pid) {
|
if (!$rid) {
|
||||||
throw new StructException('No pid given');
|
throw new StructException('No row id given');
|
||||||
}
|
}
|
||||||
if (!$tablename) {
|
if (!$tablename) {
|
||||||
throw new StructException('No schema given');
|
throw new StructException('No schema given');
|
||||||
}
|
}
|
||||||
action_plugin_struct_inline::checkCSRF();
|
action_plugin_struct_inline::checkCSRF();
|
||||||
|
|
||||||
$schemadata = AccessTable::byTableName($tablename, $pid);
|
$schemadata = AccessTable::byTableName($tablename, 0, 0, $rid);
|
||||||
if (!$schemadata->getSchema()->isEditable()) {
|
if (!$schemadata->getSchema()->isEditable()) {
|
||||||
throw new StructException('lookup delete error: no permission for schema');
|
throw new StructException('lookup delete error: no permission for schema');
|
||||||
}
|
}
|
||||||
@ -118,9 +118,9 @@ class action_plugin_struct_lookup extends DokuWiki_Action_Plugin
|
|||||||
$helper = plugin_load('helper', 'struct');
|
$helper = plugin_load('helper', 'struct');
|
||||||
$helper->saveLookupData($access, $data);
|
$helper->saveLookupData($access, $data);
|
||||||
|
|
||||||
$pid = $access->getPid();
|
$rid = $access->getRid();
|
||||||
$config = json_decode($INPUT->str('searchconf'), true);
|
$config = json_decode($INPUT->str('searchconf'), true);
|
||||||
$config['filter'] = array(array('%rowid%', '=', $pid, 'AND'));
|
$config['filter'] = array(array('%rowid%', '=', $rid, 'AND'));
|
||||||
$lookup = new LookupTable(
|
$lookup = new LookupTable(
|
||||||
'', // current page doesn't matter
|
'', // current page doesn't matter
|
||||||
'xhtml',
|
'xhtml',
|
||||||
|
@ -185,9 +185,11 @@ class action_plugin_struct_move extends DokuWiki_Action_Plugin {
|
|||||||
$tconf = $col->getType()->getConfig();
|
$tconf = $col->getType()->getConfig();
|
||||||
$ref = new Schema($tconf['schema']);
|
$ref = new Schema($tconf['schema']);
|
||||||
if(!$ref->getId()) return; // this schema does not exist
|
if(!$ref->getId()) return; // this schema does not exist
|
||||||
if($ref->isLookup()) return; // a lookup is referenced, nothing to do
|
// FIXME does this make sense at all? it's always a lookup, isn't it?
|
||||||
|
if(!$ref->getTimeStamp()) return; // a lookup is referenced, nothing to do
|
||||||
|
// var_dump($ref) && die();
|
||||||
|
|
||||||
$this->updateColumnID($schema, $col, $old, $new);
|
// $this->updateColumnID($schema, $col, $old, $new);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ class admin_plugin_struct_assignments extends DokuWiki_Admin_Plugin {
|
|||||||
echo '<td><input type="text" name="assignment[assign]" /></td>';
|
echo '<td><input type="text" name="assignment[assign]" /></td>';
|
||||||
echo '<td>';
|
echo '<td>';
|
||||||
echo '<select name="assignment[tbl]">';
|
echo '<select name="assignment[tbl]">';
|
||||||
foreach(Schema::getAll('page') as $table) {
|
foreach(Schema::getAll() as $table) {
|
||||||
echo '<option value="' . hsc($table) . '">' . hsc($table) . '</option>';
|
echo '<option value="' . hsc($table) . '">' . hsc($table) . '</option>';
|
||||||
}
|
}
|
||||||
echo '</select>';
|
echo '</select>';
|
||||||
|
@ -147,15 +147,10 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
|
|||||||
|
|
||||||
$table = Schema::cleanTableName($INPUT->str('table'));
|
$table = Schema::cleanTableName($INPUT->str('table'));
|
||||||
if($table) {
|
if($table) {
|
||||||
$schema = new Schema($table, 0, $INPUT->bool('lookup'));
|
$schema = new Schema($table, 0);
|
||||||
if($schema->isLookup()) {
|
|
||||||
$hl = 'edithl lookup';
|
|
||||||
} else {
|
|
||||||
$hl = 'edithl page';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $this->locale_xhtml('editor_edit');
|
echo $this->locale_xhtml('editor_edit');
|
||||||
echo '<h2>' . sprintf($this->getLang($hl), hsc($table)) . '</h2>';
|
echo '<h2>' . sprintf($this->getLang('edithl'), hsc($table)) . '</h2>';
|
||||||
|
|
||||||
echo '<ul class="tabs" id="plugin__struct_tabs">';
|
echo '<ul class="tabs" id="plugin__struct_tabs">';
|
||||||
/** @noinspection HtmlUnknownAnchorTarget */
|
/** @noinspection HtmlUnknownAnchorTarget */
|
||||||
@ -189,7 +184,6 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
|
|||||||
$form->setHiddenField('do', 'admin');
|
$form->setHiddenField('do', 'admin');
|
||||||
$form->setHiddenField('page', 'struct_schemas');
|
$form->setHiddenField('page', 'struct_schemas');
|
||||||
$form->setHiddenField('table', $schema->getTable());
|
$form->setHiddenField('table', $schema->getTable());
|
||||||
$form->setHiddenField('lookup', $schema->isLookup());
|
|
||||||
|
|
||||||
$form->addFieldsetOpen($this->getLang('export'));
|
$form->addFieldsetOpen($this->getLang('export'));
|
||||||
$form->addButton('export', $this->getLang('btn_export'));
|
$form->addButton('export', $this->getLang('btn_export'));
|
||||||
@ -254,8 +248,6 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
|
|||||||
$form->setHiddenField('do', 'admin');
|
$form->setHiddenField('do', 'admin');
|
||||||
$form->setHiddenField('page', 'struct_schemas');
|
$form->setHiddenField('page', 'struct_schemas');
|
||||||
$form->addTextInput('table', $this->getLang('schemaname'));
|
$form->addTextInput('table', $this->getLang('schemaname'));
|
||||||
$form->addRadioButton('lookup', $this->getLang('page schema'))->val('0')->attr('checked', 'checked');
|
|
||||||
$form->addRadioButton('lookup', $this->getLang('lookup schema'))->val('1');
|
|
||||||
$form->addButton('', $this->getLang('save'));
|
$form->addButton('', $this->getLang('save'));
|
||||||
$form->addHTML('<p>' . $this->getLang('createhint') . '</p>'); // FIXME is that true? we probably could
|
$form->addHTML('<p>' . $this->getLang('createhint') . '</p>'); // FIXME is that true? we probably could
|
||||||
$form->addFieldsetClose();
|
$form->addFieldsetClose();
|
||||||
@ -286,9 +278,8 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
|
|||||||
);
|
);
|
||||||
$toc[] = html_mktocitem($slink, $this->getLang('menu'), 0, '');
|
$toc[] = html_mktocitem($slink, $this->getLang('menu'), 0, '');
|
||||||
|
|
||||||
$tables = Schema::getAll('page');
|
$tables = Schema::getAll();
|
||||||
if($tables) {
|
if($tables) {
|
||||||
$toc[] = html_mktocitem($slink, $this->getLang('page schema'), 1, '');
|
|
||||||
foreach($tables as $table) {
|
foreach($tables as $table) {
|
||||||
$link = wl(
|
$link = wl(
|
||||||
$ID, array(
|
$ID, array(
|
||||||
@ -298,23 +289,7 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$toc[] = html_mktocitem($link, hsc($table), 2, '');
|
$toc[] = html_mktocitem($link, hsc($table), 1, '');
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$tables = Schema::getAll('lookup');
|
|
||||||
if($tables) {
|
|
||||||
$toc[] = html_mktocitem($slink, $this->getLang('lookup schema'), 1, '');
|
|
||||||
foreach($tables as $table) {
|
|
||||||
$link = wl(
|
|
||||||
$ID, array(
|
|
||||||
'do' => 'admin',
|
|
||||||
'page' => 'struct_schemas',
|
|
||||||
'table' => $table
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$toc[] = html_mktocitem($link, hsc($table), 2, '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
db/update0016.sql
Normal file
3
db/update0016.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-- this migration is handled in action/migration.php in migration16()
|
||||||
|
--
|
||||||
|
-- unifies page and lookup schemas
|
@ -109,10 +109,10 @@ class helper_plugin_struct extends DokuWiki_Plugin {
|
|||||||
/**
|
/**
|
||||||
* Save data row for a lookup schema
|
* Save data row for a lookup schema
|
||||||
*
|
*
|
||||||
* @param AccessTableLookup $access the table into which to save the data
|
* @param AccessTable $access the table into which to save the data
|
||||||
* @param array $data data to be saved in the form of [columnName => 'data']
|
* @param array $data data to be saved in the form of [columnName => 'data']
|
||||||
*/
|
*/
|
||||||
public function saveLookupData(AccessTableLookup $access, $data)
|
public function saveLookupData(AccessTable $access, $data)
|
||||||
{
|
{
|
||||||
if(!$access->getSchema()->isEditable()) {
|
if(!$access->getSchema()->isEditable()) {
|
||||||
throw new StructException('lookup save error: no permission for schema');
|
throw new StructException('lookup save error: no permission for schema');
|
||||||
|
@ -10,6 +10,7 @@ $lang['menu_assignments'] = 'Struct Přiřazení schémat';
|
|||||||
$lang['headline'] = 'Strukturovaná data';
|
$lang['headline'] = 'Strukturovaná data';
|
||||||
$lang['page schema'] = '\'Stránkové schéma:';
|
$lang['page schema'] = '\'Stránkové schéma:';
|
||||||
$lang['lookup schema'] = 'Vyhledávací schéma:';
|
$lang['lookup schema'] = 'Vyhledávací schéma:';
|
||||||
|
$lang['edithl'] = 'Editování schematu <i>%s</i>';
|
||||||
$lang['edithl page'] = 'Editování stránkového schematu <i>%s</i>';
|
$lang['edithl page'] = 'Editování stránkového schematu <i>%s</i>';
|
||||||
$lang['edithl lookup'] = 'Editování vyhledávacího schematu <i>%s</i>';
|
$lang['edithl lookup'] = 'Editování vyhledávacího schematu <i>%s</i>';
|
||||||
$lang['create'] = 'Vytvořit nové schéma';
|
$lang['create'] = 'Vytvořit nové schéma';
|
||||||
|
@ -13,8 +13,7 @@ $lang['menu_assignments'] = 'Struct Schema Zuweisungen';
|
|||||||
$lang['headline'] = 'Strukturierte Daten';
|
$lang['headline'] = 'Strukturierte Daten';
|
||||||
$lang['page schema'] = 'Seiten Schema';
|
$lang['page schema'] = 'Seiten Schema';
|
||||||
$lang['lookup schema'] = 'Lookup Schema';
|
$lang['lookup schema'] = 'Lookup Schema';
|
||||||
$lang['edithl page'] = 'Bearbeitung Seiten Schema <i>%s</i>';
|
$lang['edithl'] = 'Bearbeitung von Schema <i>%s</i>';
|
||||||
$lang['edithl lookup'] = 'Bearbeitung Lookup Schema <i>%s</i>';
|
|
||||||
$lang['create'] = 'Neues Schema anlegen';
|
$lang['create'] = 'Neues Schema anlegen';
|
||||||
$lang['schemaname'] = 'Schema-Name:';
|
$lang['schemaname'] = 'Schema-Name:';
|
||||||
$lang['save'] = 'Speichern';
|
$lang['save'] = 'Speichern';
|
||||||
|
@ -13,8 +13,7 @@ $lang['headline'] = 'Structured Data';
|
|||||||
|
|
||||||
$lang['page schema'] = 'Page Schema:';
|
$lang['page schema'] = 'Page Schema:';
|
||||||
$lang['lookup schema'] = 'Lookup Schema:';
|
$lang['lookup schema'] = 'Lookup Schema:';
|
||||||
$lang['edithl page'] = 'Editing Page Schema <i>%s</i>';
|
$lang['edithl'] = 'Editing schema <i>%s</i>';
|
||||||
$lang['edithl lookup'] = 'Editing Lookup Schema <i>%s</i>';
|
|
||||||
$lang['create'] = 'Create new Schema';
|
$lang['create'] = 'Create new Schema';
|
||||||
$lang['schemaname'] = 'Schema Name:';
|
$lang['schemaname'] = 'Schema Name:';
|
||||||
$lang['save'] = 'Save';
|
$lang['save'] = 'Save';
|
||||||
|
@ -17,8 +17,7 @@ $lang['menu_assignments'] = 'Struct - Affectation de schémas';
|
|||||||
$lang['headline'] = 'Données structurées';
|
$lang['headline'] = 'Données structurées';
|
||||||
$lang['page schema'] = 'Schéma de page';
|
$lang['page schema'] = 'Schéma de page';
|
||||||
$lang['lookup schema'] = 'Schéma de consultation';
|
$lang['lookup schema'] = 'Schéma de consultation';
|
||||||
$lang['edithl page'] = 'Édition du schéma de page <i>%s</i>';
|
$lang['edithl'] = 'Édition du schéma <i>%s</i>';
|
||||||
$lang['edithl lookup'] = 'Édition du schéma de consultation <i>%s</i>';
|
|
||||||
$lang['create'] = 'Créer un nouveau schéma';
|
$lang['create'] = 'Créer un nouveau schéma';
|
||||||
$lang['schemaname'] = 'Nom du schéma :';
|
$lang['schemaname'] = 'Nom du schéma :';
|
||||||
$lang['save'] = 'Sauvegarder';
|
$lang['save'] = 'Sauvegarder';
|
||||||
|
@ -7,6 +7,7 @@ abstract class AccessTable {
|
|||||||
/** @var Schema */
|
/** @var Schema */
|
||||||
protected $schema;
|
protected $schema;
|
||||||
protected $pid;
|
protected $pid;
|
||||||
|
protected $rid;
|
||||||
protected $labels = array();
|
protected $labels = array();
|
||||||
protected $ts = 0;
|
protected $ts = 0;
|
||||||
/** @var \helper_plugin_sqlite */
|
/** @var \helper_plugin_sqlite */
|
||||||
@ -21,14 +22,14 @@ abstract class AccessTable {
|
|||||||
* @param Schema $schema schema to load
|
* @param Schema $schema schema to load
|
||||||
* @param string|int $pid Page or row id to access
|
* @param string|int $pid Page or row id to access
|
||||||
* @param int $ts Time at which the data should be read or written, 0 for now
|
* @param int $ts Time at which the data should be read or written, 0 for now
|
||||||
|
* @param int $rid
|
||||||
* @return AccessTableData|AccessTableLookup
|
* @return AccessTableData|AccessTableLookup
|
||||||
*/
|
*/
|
||||||
public static function bySchema(Schema $schema, $pid, $ts = 0) {
|
public static function bySchema(Schema $schema, $pid, $ts = 0, $rid = 0) {
|
||||||
if($schema->isLookup()) {
|
if (!$pid && $ts === 0) {
|
||||||
return new AccessTableLookup($schema, $pid, $ts);
|
return new AccessTableLookup($schema, $pid, $ts, $rid);
|
||||||
} else {
|
|
||||||
return new AccessTableData($schema, $pid, $ts);
|
|
||||||
}
|
}
|
||||||
|
return new AccessTableData($schema, $pid, $ts, $rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,11 +38,12 @@ abstract class AccessTable {
|
|||||||
* @param string $tablename schema to load
|
* @param string $tablename schema to load
|
||||||
* @param string|int $pid Page or row id to access
|
* @param string|int $pid Page or row id to access
|
||||||
* @param int $ts Time at which the data should be read or written, 0 for now
|
* @param int $ts Time at which the data should be read or written, 0 for now
|
||||||
|
* @param int $rid
|
||||||
* @return AccessTableData|AccessTableLookup
|
* @return AccessTableData|AccessTableLookup
|
||||||
*/
|
*/
|
||||||
public static function byTableName($tablename, $pid, $ts = 0) {
|
public static function byTableName($tablename, $pid, $ts = 0, $rid = 0) {
|
||||||
$schema = new Schema($tablename, $ts);
|
$schema = new Schema($tablename, $ts);
|
||||||
return self::bySchema($schema, $pid, $ts);
|
return self::bySchema($schema, $pid, $ts, $rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,8 +52,9 @@ abstract class AccessTable {
|
|||||||
* @param Schema $schema The schema valid at $ts
|
* @param Schema $schema The schema valid at $ts
|
||||||
* @param string|int $pid
|
* @param string|int $pid
|
||||||
* @param int $ts Time at which the data should be read or written, 0 for now
|
* @param int $ts Time at which the data should be read or written, 0 for now
|
||||||
|
* @param int $rid Row id: 0 for pages, autoincremented for other types
|
||||||
*/
|
*/
|
||||||
public function __construct(Schema $schema, $pid, $ts = 0) {
|
public function __construct(Schema $schema, $pid, $ts = 0, $rid = 0) {
|
||||||
/** @var \helper_plugin_struct_db $helper */
|
/** @var \helper_plugin_struct_db $helper */
|
||||||
$helper = plugin_load('helper', 'struct_db');
|
$helper = plugin_load('helper', 'struct_db');
|
||||||
$this->sqlite = $helper->getDB();
|
$this->sqlite = $helper->getDB();
|
||||||
@ -62,6 +65,7 @@ abstract class AccessTable {
|
|||||||
|
|
||||||
$this->schema = $schema;
|
$this->schema = $schema;
|
||||||
$this->pid = $pid;
|
$this->pid = $pid;
|
||||||
|
$this->rid = $rid;
|
||||||
$this->setTimestamp($ts);
|
$this->setTimestamp($ts);
|
||||||
foreach($this->schema->getColumns() as $col) {
|
foreach($this->schema->getColumns() as $col) {
|
||||||
$this->labels[$col->getColref()] = $col->getType()->getLabel();
|
$this->labels[$col->getColref()] = $col->getType()->getLabel();
|
||||||
@ -86,6 +90,15 @@ abstract class AccessTable {
|
|||||||
return $this->pid;
|
return $this->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current rid
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getRid() {
|
||||||
|
return $this->rid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should remove the current data, by either deleting or ovewriting it
|
* Should remove the current data, by either deleting or ovewriting it
|
||||||
*
|
*
|
||||||
|
@ -11,19 +11,7 @@ namespace dokuwiki\plugin\struct\meta;
|
|||||||
*/
|
*/
|
||||||
class AccessTableData extends AccessTable {
|
class AccessTableData extends AccessTable {
|
||||||
|
|
||||||
/**
|
const DEFAULT_PAGE_RID = 0;
|
||||||
* AccessTableData constructor
|
|
||||||
*
|
|
||||||
* @param Schema $schema Which schema to access
|
|
||||||
* @param string $pid The page of which the data is for
|
|
||||||
* @param int $ts Time at which the data should be read or written, 0 for now
|
|
||||||
*/
|
|
||||||
public function __construct(Schema $schema, $pid, $ts = 0) {
|
|
||||||
parent::__construct($schema, $pid, $ts);
|
|
||||||
if($this->schema->isLookup()) {
|
|
||||||
throw new StructException('wrong schema type. use factory methods!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds an empty data set for this schema and page
|
* adds an empty data set for this schema and page
|
||||||
@ -64,9 +52,10 @@ class AccessTableData extends AccessTable {
|
|||||||
|
|
||||||
$colrefs = array_flip($this->labels);
|
$colrefs = array_flip($this->labels);
|
||||||
$now = $this->ts;
|
$now = $this->ts;
|
||||||
$opt = array($this->pid, $now, 1);
|
$opt = array(self::DEFAULT_PAGE_RID, $this->pid, $now, 1);
|
||||||
$multiopts = array();
|
$multiopts = array();
|
||||||
$singlecols = 'pid, rev, latest';
|
$singlecols = 'rid, pid, rev, latest';
|
||||||
|
|
||||||
foreach ($data as $colname => $value) {
|
foreach ($data as $colname => $value) {
|
||||||
if(!isset($colrefs[$colname])) {
|
if(!isset($colrefs[$colname])) {
|
||||||
throw new StructException("Unknown column %s in schema.", hsc($colname));
|
throw new StructException("Unknown column %s in schema.", hsc($colname));
|
||||||
@ -87,9 +76,11 @@ class AccessTableData extends AccessTable {
|
|||||||
$opt[] = $value;
|
$opt[] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$singlesql = "INSERT INTO $stable ($singlecols) VALUES (" . trim(str_repeat('?,',count($opt)),',') . ")";
|
|
||||||
|
$singlesql = "INSERT INTO $stable ($singlecols) VALUES (" . trim(str_repeat('?,',count($opt)),',') . ');';
|
||||||
|
|
||||||
/** @noinspection SqlResolve */
|
/** @noinspection SqlResolve */
|
||||||
$multisql = "INSERT INTO $mtable (latest, rev, pid, colref, row, value) VALUES (?, ?,?,?,?,?)";
|
$multisql = "INSERT INTO $mtable (latest, rev, pid, rid, colref, row, value) VALUES (?,?,?,?,?,?)";
|
||||||
|
|
||||||
$this->sqlite->query('BEGIN TRANSACTION');
|
$this->sqlite->query('BEGIN TRANSACTION');
|
||||||
|
|
||||||
@ -105,7 +96,7 @@ class AccessTableData extends AccessTable {
|
|||||||
|
|
||||||
// insert multi values
|
// insert multi values
|
||||||
foreach ($multiopts as $multiopt) {
|
foreach ($multiopts as $multiopt) {
|
||||||
$multiopt = array_merge(array(1, $now, $this->pid,), $multiopt);
|
$multiopt = array_merge(array(1, $now, $this->pid, self::DEFAULT_PAGE_RID), $multiopt);
|
||||||
$ok = $ok && $this->sqlite->query($multisql, $multiopt);
|
$ok = $ok && $this->sqlite->query($multisql, $multiopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,24 +17,25 @@ class AccessTableLookup extends AccessTable {
|
|||||||
* @param Schema $schema Which schema to access
|
* @param Schema $schema Which schema to access
|
||||||
* @param int $pid the row identifier (0 for new row)
|
* @param int $pid the row identifier (0 for new row)
|
||||||
* @param int $ts Time at which the data should be read or written, 0 for now
|
* @param int $ts Time at which the data should be read or written, 0 for now
|
||||||
|
* @param int $rid
|
||||||
*/
|
*/
|
||||||
public function __construct(Schema $schema, $pid = 0, $ts = 0) {
|
public function __construct(Schema $schema, $pid = 0, $ts = 0, $rid = 0) {
|
||||||
parent::__construct($schema, $pid, $ts);
|
parent::__construct($schema, $pid, $ts, $rid);
|
||||||
if(!$this->schema->isLookup()) {
|
// if(!$this->schema->isLookup()) {
|
||||||
throw new StructException('wrong schema type. use factory methods!');
|
// throw new StructException('wrong schema type. use factory methods!');
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the current data
|
* Remove the current data
|
||||||
*/
|
*/
|
||||||
public function clearData() {
|
public function clearData() {
|
||||||
if(!$this->pid) return; // no data
|
if(!$this->rid) return; // no data
|
||||||
|
|
||||||
/** @noinspection SqlResolve */
|
/** @noinspection SqlResolve */
|
||||||
$sql = "DELETE FROM ? WHERE pid = ?";
|
$sql = 'DELETE FROM ? WHERE rid = ?';
|
||||||
$this->sqlite->query($sql, 'data_'.$this->schema->getTable(), $this->pid);
|
$this->sqlite->query($sql, 'data_'.$this->schema->getTable(), $this->rid);
|
||||||
$this->sqlite->query($sql, 'multi_'.$this->schema->getTable(), $this->pid);
|
$this->sqlite->query($sql, 'multi_'.$this->schema->getTable(), $this->rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,13 +59,8 @@ class AccessTableLookup extends AccessTable {
|
|||||||
if($isempty) return false;
|
if($isempty) return false;
|
||||||
|
|
||||||
|
|
||||||
$singlecols = array();
|
$singlecols = ['rev', 'latest'];
|
||||||
$opt = array();
|
$opt = [0, 1];
|
||||||
|
|
||||||
if($this->pid) {
|
|
||||||
$singlecols[] = 'pid';
|
|
||||||
$opt[] = $this->pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
$colrefs = array_flip($this->labels);
|
$colrefs = array_flip($this->labels);
|
||||||
$multiopts = array();
|
$multiopts = array();
|
||||||
@ -88,9 +84,13 @@ class AccessTableLookup extends AccessTable {
|
|||||||
$opt[] = $value;
|
$opt[] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$singlesql = "REPLACE INTO $stable (" . join(',', $singlecols) . ") VALUES (" . trim(str_repeat('?,', count($opt)), ',') . ")";
|
|
||||||
|
$ridSingle = "(SELECT (COALESCE(MAX(rid), 0 ) + 1) FROM $stable)";
|
||||||
|
$ridMulti = "(SELECT (COALESCE(MAX(rid), 0 ) + 1) FROM $mtable)";
|
||||||
|
|
||||||
|
$singlesql = "REPLACE INTO $stable (pid, rid, " . join(',', $singlecols) . ") VALUES (NULL, $ridSingle, " . trim(str_repeat('?,', count($opt)), ',') . ")";
|
||||||
/** @noinspection SqlResolve */
|
/** @noinspection SqlResolve */
|
||||||
$multisql = "REPLACE INTO $mtable (pid, colref, row, value) VALUES (?,?,?,?)";
|
$multisql = "REPLACE INTO $mtable (pid, rid, colref, row, value) VALUES (NULL, $ridMulti, ?,?,?)";
|
||||||
|
|
||||||
$this->sqlite->query('BEGIN TRANSACTION');
|
$this->sqlite->query('BEGIN TRANSACTION');
|
||||||
$ok = true;
|
$ok = true;
|
||||||
@ -98,17 +98,17 @@ class AccessTableLookup extends AccessTable {
|
|||||||
// insert single values
|
// insert single values
|
||||||
$ok = $ok && $this->sqlite->query($singlesql, $opt);
|
$ok = $ok && $this->sqlite->query($singlesql, $opt);
|
||||||
|
|
||||||
// get new pid if this is a new insert
|
// get new rid if this is a new insert
|
||||||
if($ok && !$this->pid) {
|
if($ok && !$this->rid) {
|
||||||
$res = $this->sqlite->query('SELECT last_insert_rowid()');
|
$res = $this->sqlite->query('SELECT last_insert_rowid()');
|
||||||
$this->pid = $this->sqlite->res2single($res);
|
$this->rid = $this->sqlite->res2single($res);
|
||||||
$this->sqlite->res_close($res);
|
$this->sqlite->res_close($res);
|
||||||
if(!$this->pid) $ok = false;
|
if(!$this->rid) $ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert multi values
|
// insert multi values
|
||||||
if($ok) foreach($multiopts as $multiopt) {
|
if($ok) foreach($multiopts as $multiopt) {
|
||||||
$multiopt = array_merge(array($this->pid,), $multiopt);
|
$multiopt = array_merge(array($this->rid,), $multiopt);
|
||||||
$ok = $ok && $this->sqlite->query($multisql, $multiopt);
|
$ok = $ok && $this->sqlite->query($multisql, $multiopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ class AggregationTable {
|
|||||||
* @var string[] the result PIDs for each row
|
* @var string[] the result PIDs for each row
|
||||||
*/
|
*/
|
||||||
protected $resultPIDs;
|
protected $resultPIDs;
|
||||||
|
protected $resultRids;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array for summing up columns
|
* @var array for summing up columns
|
||||||
@ -83,6 +84,7 @@ class AggregationTable {
|
|||||||
$this->result = $this->searchConfig->execute();
|
$this->result = $this->searchConfig->execute();
|
||||||
$this->resultCount = $this->searchConfig->getCount();
|
$this->resultCount = $this->searchConfig->getCount();
|
||||||
$this->resultPIDs = $this->searchConfig->getPids();
|
$this->resultPIDs = $this->searchConfig->getPids();
|
||||||
|
$this->resultRids = $this->searchConfig->getRids();
|
||||||
$this->helper = plugin_load('helper', 'struct_config');
|
$this->helper = plugin_load('helper', 'struct_config');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,8 +362,9 @@ class AggregationTable {
|
|||||||
// add data attribute for inline edit
|
// add data attribute for inline edit
|
||||||
if($this->mode == 'xhtml') {
|
if($this->mode == 'xhtml') {
|
||||||
$pid = $this->resultPIDs[$rownum];
|
$pid = $this->resultPIDs[$rownum];
|
||||||
|
$rid = $this->resultRids[$rownum];
|
||||||
$this->renderer->doc = substr(rtrim($this->renderer->doc), 0, -1); // remove closing '>'
|
$this->renderer->doc = substr(rtrim($this->renderer->doc), 0, -1); // remove closing '>'
|
||||||
$this->renderer->doc .= ' data-pid="' . hsc($pid) . '">';
|
$this->renderer->doc .= ' data-pid="' . hsc($pid) . '" data-rid="' . hsc($rid) . '">';
|
||||||
}
|
}
|
||||||
|
|
||||||
// row number column
|
// row number column
|
||||||
|
@ -17,11 +17,11 @@ class CSVPageImporter extends CSVImporter {
|
|||||||
* @param string $table
|
* @param string $table
|
||||||
* @param string $file
|
* @param string $file
|
||||||
*/
|
*/
|
||||||
public function __construct($table, $file) {
|
// public function __construct($table, $file) {
|
||||||
parent::__construct($table, $file);
|
// parent::__construct($table, $file);
|
||||||
|
//
|
||||||
if($this->schema->isLookup()) throw new StructException($table.' is not a page schema');
|
// if($this->schema->isLookup()) throw new StructException($table.' is not a page schema');
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import page schema only when the pid header is present.
|
* Import page schema only when the pid header is present.
|
||||||
|
@ -66,15 +66,4 @@ class LookupTable extends AggregationTable {
|
|||||||
return $this->renderer->doc;
|
return $this->renderer->doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function render() {
|
|
||||||
if(!$this->searchConfig->getSchemas()[0]->isLookup()) {
|
|
||||||
msg($this->helper->getLang('no_lookup_for_page'), -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parent::render();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,14 @@ class RowColumn extends PageColumn {
|
|||||||
return '%rowid%';
|
return '%rowid%';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $enforceSingleColumn ignored
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getColName($enforceSingleColumn = true) {
|
||||||
|
return 'rid';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string preconfigured label
|
* @return string preconfigured label
|
||||||
*/
|
*/
|
||||||
|
@ -32,9 +32,6 @@ class Schema {
|
|||||||
/** @var string name of the associated table */
|
/** @var string name of the associated table */
|
||||||
protected $table = '';
|
protected $table = '';
|
||||||
|
|
||||||
/** @var bool is this a lookup schema? */
|
|
||||||
protected $islookup = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string the current checksum of this schema
|
* @var string the current checksum of this schema
|
||||||
*/
|
*/
|
||||||
@ -60,9 +57,8 @@ class Schema {
|
|||||||
*
|
*
|
||||||
* @param string $table The table this schema is for
|
* @param string $table The table this schema is for
|
||||||
* @param int $ts The timestamp for when this schema was valid, 0 for current
|
* @param int $ts The timestamp for when this schema was valid, 0 for current
|
||||||
* @param bool $islookup only used when creating a new schema, makes the new schema a lookup
|
|
||||||
*/
|
*/
|
||||||
public function __construct($table, $ts = 0, $islookup = false) {
|
public function __construct($table, $ts = 0) {
|
||||||
$baseconfig = array('allowed editors' => '');
|
$baseconfig = array('allowed editors' => '');
|
||||||
|
|
||||||
/** @var \helper_plugin_struct_db $helper */
|
/** @var \helper_plugin_struct_db $helper */
|
||||||
@ -99,11 +95,8 @@ class Schema {
|
|||||||
$this->id = $result['id'];
|
$this->id = $result['id'];
|
||||||
$this->user = $result['user'];
|
$this->user = $result['user'];
|
||||||
$this->chksum = isset($result['chksum']) ? $result['chksum'] : '';
|
$this->chksum = isset($result['chksum']) ? $result['chksum'] : '';
|
||||||
$this->islookup = $result['islookup'];
|
|
||||||
$this->ts = $result['ts'];
|
$this->ts = $result['ts'];
|
||||||
$config = json_decode($result['config'], true);
|
$config = json_decode($result['config'], true);
|
||||||
} else {
|
|
||||||
$this->islookup = $islookup;
|
|
||||||
}
|
}
|
||||||
$this->sqlite->res_close($res);
|
$this->sqlite->res_close($res);
|
||||||
$this->config = array_merge($baseconfig, $config);
|
$this->config = array_merge($baseconfig, $config);
|
||||||
@ -225,7 +218,7 @@ class Schema {
|
|||||||
$this->sqlite->query($sql, $this->table);
|
$this->sqlite->query($sql, $this->table);
|
||||||
|
|
||||||
$sql = "SELECT T.id
|
$sql = "SELECT T.id
|
||||||
FROM types T, schema_cols SC, schemas S
|
FROM types T, schema_cols SC, schemas S
|
||||||
WHERE T.id = SC.tid
|
WHERE T.id = SC.tid
|
||||||
AND SC.sid = S.id
|
AND SC.sid = S.id
|
||||||
AND S.tbl = ?";
|
AND S.tbl = ?";
|
||||||
@ -233,7 +226,7 @@ class Schema {
|
|||||||
$this->sqlite->query($sql, $this->table);
|
$this->sqlite->query($sql, $this->table);
|
||||||
|
|
||||||
$sql = "SELECT id
|
$sql = "SELECT id
|
||||||
FROM schemas
|
FROM schemas
|
||||||
WHERE tbl = ?";
|
WHERE tbl = ?";
|
||||||
$sql = "DELETE FROM schema_cols WHERE sid IN ($sql)";
|
$sql = "DELETE FROM schema_cols WHERE sid IN ($sql)";
|
||||||
$this->sqlite->query($sql, $this->table);
|
$this->sqlite->query($sql, $this->table);
|
||||||
@ -288,13 +281,6 @@ class Schema {
|
|||||||
return $this->ts;
|
return $this->ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool is this a lookup schema?
|
|
||||||
*/
|
|
||||||
public function isLookup() {
|
|
||||||
return $this->islookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +57,7 @@ class SchemaBuilder {
|
|||||||
public function __construct($table, $data) {
|
public function __construct($table, $data) {
|
||||||
$this->table = $table;
|
$this->table = $table;
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
$this->oldschema = new Schema($table, 0, $data['islookup']);
|
$this->oldschema = new Schema($table, 0);
|
||||||
|
|
||||||
$this->helper = plugin_load('helper', 'struct_db');
|
$this->helper = plugin_load('helper', 'struct_db');
|
||||||
$this->sqlite = $this->helper->getDB();
|
$this->sqlite = $this->helper->getDB();
|
||||||
@ -78,11 +78,7 @@ class SchemaBuilder {
|
|||||||
$ok = true;
|
$ok = true;
|
||||||
// create the data table if new schema
|
// create the data table if new schema
|
||||||
if(!$this->oldschema->getId()) {
|
if(!$this->oldschema->getId()) {
|
||||||
if($this->oldschema->isLookup()) {
|
$ok = $this->newDataTable();
|
||||||
$ok = $this->newLookupTable();
|
|
||||||
} else {
|
|
||||||
$ok = $this->newDataTable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new schema
|
// create a new schema
|
||||||
@ -149,7 +145,8 @@ class SchemaBuilder {
|
|||||||
|
|
||||||
/** @noinspection SqlResolve */
|
/** @noinspection SqlResolve */
|
||||||
$sql = "INSERT INTO schemas (tbl, ts, islookup, user, config) VALUES (?, ?, ?, ?, ?)";
|
$sql = "INSERT INTO schemas (tbl, ts, islookup, user, config) VALUES (?, ?, ?, ?, ?)";
|
||||||
$this->sqlite->query($sql, $this->table, $this->time, (int) $this->oldschema->isLookup(), $this->user, $config);
|
// FIXME magic 0 for islookup
|
||||||
|
$this->sqlite->query($sql, $this->table, $this->time, 0, $this->user, $config);
|
||||||
$res = $this->sqlite->query('SELECT last_insert_rowid()');
|
$res = $this->sqlite->query('SELECT last_insert_rowid()');
|
||||||
$this->newschemaid = $this->sqlite->res2single($res);
|
$this->newschemaid = $this->sqlite->res2single($res);
|
||||||
$this->sqlite->res_close($res);
|
$this->sqlite->res_close($res);
|
||||||
@ -208,6 +205,7 @@ class SchemaBuilder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the latest value from an entry in a data_ table to the corresponding multi_table
|
* Write the latest value from an entry in a data_ table to the corresponding multi_table
|
||||||
|
* FIXME handle rid
|
||||||
*
|
*
|
||||||
* @param string $table
|
* @param string $table
|
||||||
* @param int $colref
|
* @param int $colref
|
||||||
@ -302,57 +300,27 @@ class SchemaBuilder {
|
|||||||
$ok = true;
|
$ok = true;
|
||||||
|
|
||||||
$tbl = 'data_' . $this->table;
|
$tbl = 'data_' . $this->table;
|
||||||
|
// FIXME default latest in data table is 1 for lookups, 0 for pages
|
||||||
|
// FIXME because lookup data is never versioned?
|
||||||
$sql = "CREATE TABLE $tbl (
|
$sql = "CREATE TABLE $tbl (
|
||||||
pid NOT NULL,
|
pid TEXT DEFAULT NULL,
|
||||||
rev INTEGER NOT NULL,
|
rid INTEGER,
|
||||||
|
rev INTEGER,
|
||||||
latest BOOLEAN NOT NULL DEFAULT 0,
|
latest BOOLEAN NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY(pid, rev)
|
PRIMARY KEY(pid, rid, rev)
|
||||||
)";
|
)";
|
||||||
$ok = $ok && (bool) $this->sqlite->query($sql);
|
$ok = $ok && (bool) $this->sqlite->query($sql);
|
||||||
|
|
||||||
$tbl = 'multi_' . $this->table;
|
$tbl = 'multi_' . $this->table;
|
||||||
$sql = "CREATE TABLE $tbl (
|
$sql = "CREATE TABLE $tbl (
|
||||||
colref INTEGER NOT NULL,
|
colref INTEGER NOT NULL,
|
||||||
pid NOT NULL,
|
pid TEXT,
|
||||||
rev INTEGER NOT NULL,
|
rid INTEGER,
|
||||||
|
rev INTEGER,
|
||||||
latest INTEGER NOT NULL DEFAULT 0,
|
latest INTEGER NOT NULL DEFAULT 0,
|
||||||
row INTEGER NOT NULL,
|
row INTEGER NOT NULL,
|
||||||
value,
|
value,
|
||||||
PRIMARY KEY(colref, pid, rev, row)
|
PRIMARY KEY(colref, pid, rid, rev, row)
|
||||||
);";
|
|
||||||
$ok = $ok && (bool) $this->sqlite->query($sql);
|
|
||||||
|
|
||||||
return $ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new lookup table with no columns
|
|
||||||
*
|
|
||||||
* This is basically the same as @see newDataTable() but sets
|
|
||||||
* different primary keys and types
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function newLookupTable() {
|
|
||||||
$ok = true;
|
|
||||||
|
|
||||||
$tbl = 'data_' . $this->table;
|
|
||||||
$sql = "CREATE TABLE $tbl (
|
|
||||||
pid INTEGER PRIMARY KEY,
|
|
||||||
rev INTEGER NOT NULL DEFAULT 0,
|
|
||||||
latest BOOLEAN NOT NULL DEFAULT 1
|
|
||||||
)";
|
|
||||||
$ok = $ok && (bool) $this->sqlite->query($sql);
|
|
||||||
|
|
||||||
$tbl = 'multi_' . $this->table;
|
|
||||||
$sql = "CREATE TABLE $tbl (
|
|
||||||
colref INTEGER NOT NULL,
|
|
||||||
pid INTEGER NOT NULL,
|
|
||||||
rev INTEGER NOT NULL DEFAULT 0,
|
|
||||||
latest INTEGER NOT NULL DEFAULT 0,
|
|
||||||
row INTEGER NOT NULL,
|
|
||||||
value,
|
|
||||||
PRIMARY KEY(colref, pid, row)
|
|
||||||
);";
|
);";
|
||||||
$ok = $ok && (bool) $this->sqlite->query($sql);
|
$ok = $ok && (bool) $this->sqlite->query($sql);
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ class SchemaEditor {
|
|||||||
$form->setHiddenField('page', 'struct_schemas');
|
$form->setHiddenField('page', 'struct_schemas');
|
||||||
$form->setHiddenField('table', $this->schema->getTable());
|
$form->setHiddenField('table', $this->schema->getTable());
|
||||||
$form->setHiddenField('schema[id]', $this->schema->getId());
|
$form->setHiddenField('schema[id]', $this->schema->getId());
|
||||||
$form->setHiddenField('schema[islookup]', $this->schema->isLookup());
|
|
||||||
|
|
||||||
$form->addHTML('<table class="inline">');
|
$form->addHTML('<table class="inline">');
|
||||||
$form->addHTML("<tr>
|
$form->addHTML("<tr>
|
||||||
|
@ -51,6 +51,8 @@ class Search {
|
|||||||
protected $count = -1;
|
protected $count = -1;
|
||||||
/** @var string[] the PIDs of the result rows */
|
/** @var string[] the PIDs of the result rows */
|
||||||
protected $result_pids = null;
|
protected $result_pids = null;
|
||||||
|
/** @var array the row ids of the result rows */
|
||||||
|
protected $result_rids = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search constructor.
|
* Search constructor.
|
||||||
@ -75,14 +77,15 @@ class Search {
|
|||||||
throw new StructException('schema missing', $table);
|
throw new StructException('schema missing', $table);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->schemas &&
|
// FIXME is the mixing still relevant?
|
||||||
(
|
// if($this->schemas &&
|
||||||
$schema->isLookup() ||
|
// (
|
||||||
reset($this->schemas)->isLookup()
|
// $schema->isLookup() ||
|
||||||
)
|
// reset($this->schemas)->isLookup()
|
||||||
) {
|
// )
|
||||||
throw new StructException('nolookupmix');
|
// ) {
|
||||||
}
|
// throw new StructException('nolookupmix');
|
||||||
|
// }
|
||||||
|
|
||||||
$this->schemas[$schema->getTable()] = $schema;
|
$this->schemas[$schema->getTable()] = $schema;
|
||||||
if($alias) $this->aliases[$alias] = $schema->getTable();
|
if($alias) $this->aliases[$alias] = $schema->getTable();
|
||||||
@ -265,6 +268,18 @@ class Search {
|
|||||||
return $this->result_pids;
|
return $this->result_pids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the rid associated with each result row
|
||||||
|
*
|
||||||
|
* Important: this may only be called after running @see execute()
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRids() {
|
||||||
|
if($this->result_rids === null) throw new StructException('rids are only accessible after executing the search');
|
||||||
|
return $this->result_rids;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute this search and return the result
|
* Execute this search and return the result
|
||||||
*
|
*
|
||||||
@ -314,6 +329,7 @@ class Search {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->result_pids[] = $row['PID'];
|
$this->result_pids[] = $row['PID'];
|
||||||
|
$this->result_rids[] = $row['rid'];
|
||||||
$result[] = $resrow;
|
$result[] = $resrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +358,8 @@ class Search {
|
|||||||
} else {
|
} else {
|
||||||
// first table
|
// first table
|
||||||
|
|
||||||
if(!$schema->isLookup()) {
|
// FIXME this breaks page search, a different check is needed
|
||||||
|
if(false) {
|
||||||
$QB->addTable('schema_assignments');
|
$QB->addTable('schema_assignments');
|
||||||
$QB->filters()->whereAnd("$datatable.pid = schema_assignments.pid");
|
$QB->filters()->whereAnd("$datatable.pid = schema_assignments.pid");
|
||||||
$QB->filters()->whereAnd("schema_assignments.tbl = '{$schema->getTable()}'");
|
$QB->filters()->whereAnd("schema_assignments.tbl = '{$schema->getTable()}'");
|
||||||
@ -352,6 +369,7 @@ class Search {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$QB->addTable($datatable);
|
$QB->addTable($datatable);
|
||||||
|
$QB->addSelectColumn($datatable, 'rid');
|
||||||
$QB->addSelectColumn($datatable, 'pid', 'PID');
|
$QB->addSelectColumn($datatable, 'pid', 'PID');
|
||||||
$QB->addGroupByColumn($datatable, 'pid');
|
$QB->addGroupByColumn($datatable, 'pid');
|
||||||
|
|
||||||
@ -513,8 +531,9 @@ class Search {
|
|||||||
if(!$this->schemas) throw new StructException('noschemas');
|
if(!$this->schemas) throw new StructException('noschemas');
|
||||||
$schema_list = array_keys($this->schemas);
|
$schema_list = array_keys($this->schemas);
|
||||||
|
|
||||||
|
// FIXME check for page schema?
|
||||||
// add "fake" column for special col
|
// add "fake" column for special col
|
||||||
if(!(reset($this->schemas)->isLookup())) {
|
// if(!(reset($this->schemas)->isLookup())) {
|
||||||
if($colname == '%pageid%') {
|
if($colname == '%pageid%') {
|
||||||
return new PageColumn(0, new Page(), $schema_list[0]);
|
return new PageColumn(0, new Page(), $schema_list[0]);
|
||||||
}
|
}
|
||||||
@ -530,11 +549,11 @@ class Search {
|
|||||||
if ($colname == '%lastsummary%') {
|
if ($colname == '%lastsummary%') {
|
||||||
return new SummaryColumn(0, new AutoSummary(), $schema_list[0]);
|
return new SummaryColumn(0, new AutoSummary(), $schema_list[0]);
|
||||||
}
|
}
|
||||||
} else {
|
// } else {
|
||||||
if($colname == '%rowid%') {
|
if($colname == '%rowid%') {
|
||||||
return new RowColumn(0, new Decimal(), $schema_list[0]);
|
return new RowColumn(0, new Decimal(), $schema_list[0]);
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
|
|
||||||
list($colname, $table) = $this->resolveColumn($colname);
|
list($colname, $table) = $this->resolveColumn($colname);
|
||||||
|
|
||||||
|
@ -21,17 +21,17 @@ var LookupEditor = function (idx, table) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pid = $me.data('pid');
|
var rid = $me.data('rid');
|
||||||
|
|
||||||
// empty header cells
|
// empty header cells
|
||||||
if (!pid) {
|
if (!rid) {
|
||||||
$me.append('<th class="action"></th>');
|
$me.append('<th class="action"></th>');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete buttons for rows
|
// delete buttons for rows
|
||||||
var $td = jQuery('<td class="action"></td>');
|
var $td = jQuery('<td class="action"></td>');
|
||||||
if (pid === '') return;
|
if (rid === '') return;
|
||||||
|
|
||||||
var $btn = jQuery('<button><i class="ui-icon ui-icon-trash"></i></button>')
|
var $btn = jQuery('<button><i class="ui-icon ui-icon-trash"></i></button>')
|
||||||
.addClass('delete')
|
.addClass('delete')
|
||||||
@ -45,7 +45,7 @@ var LookupEditor = function (idx, table) {
|
|||||||
{
|
{
|
||||||
call: 'plugin_struct_lookup_delete',
|
call: 'plugin_struct_lookup_delete',
|
||||||
schema: schema,
|
schema: schema,
|
||||||
pid: pid,
|
rid: rid,
|
||||||
sectok: $me.parents('.structlookup').find('.struct_entry_form input[name=sectok]').val()
|
sectok: $me.parents('.structlookup').find('.struct_entry_form input[name=sectok]').val()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -39,10 +39,25 @@ class syntax_plugin_struct_lookup extends syntax_plugin_struct_table {
|
|||||||
$config = parent::handle($match, $state, $pos, $handler);
|
$config = parent::handle($match, $state, $pos, $handler);
|
||||||
if(is_null($config)) return null;
|
if(is_null($config)) return null;
|
||||||
|
|
||||||
|
$config = $this->addTypeFilter($config);
|
||||||
|
|
||||||
// adjust some things for the lookup editor
|
// adjust some things for the lookup editor
|
||||||
$config['cols'] = array('*'); // always select all columns
|
$config['cols'] = array('*'); // always select all columns
|
||||||
if(isset($config['rownumbers'])) unset($config['rownumbers']); // this annoying to update dynamically
|
if(isset($config['rownumbers'])) unset($config['rownumbers']); // this annoying to update dynamically
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter based on primary key columns
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function addTypeFilter($config)
|
||||||
|
{
|
||||||
|
$config['filter'][] = ['%rowid%', '!=', (string)\dokuwiki\plugin\struct\meta\AccessTableData::DEFAULT_PAGE_RID, 'AND'];
|
||||||
|
$config['filter'][] = ['%pageid%', '=*', '^(?![\s\S])', 'AND'];
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,9 @@ class syntax_plugin_struct_table extends DokuWiki_Syntax_Plugin {
|
|||||||
try {
|
try {
|
||||||
$parser = new ConfigParser($lines);
|
$parser = new ConfigParser($lines);
|
||||||
$config = $parser->getConfig();
|
$config = $parser->getConfig();
|
||||||
|
|
||||||
|
$config = $this->addTypeFilter($config);
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
} catch(StructException $e) {
|
} catch(StructException $e) {
|
||||||
msg($e->getMessage(), -1, $e->getLine(), $e->getFile());
|
msg($e->getMessage(), -1, $e->getLine(), $e->getFile());
|
||||||
@ -113,4 +116,16 @@ class syntax_plugin_struct_table extends DokuWiki_Syntax_Plugin {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter based on primary key columns
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function addTypeFilter($config)
|
||||||
|
{
|
||||||
|
$config['filter'][] = ['%rowid%', '=', (string)\dokuwiki\plugin\struct\meta\AccessTableData::DEFAULT_PAGE_RID, 'AND'];
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,8 @@ class Tag extends AbstractMultiBaseType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$schema = new Schema($context->getTable());
|
$schema = new Schema($context->getTable());
|
||||||
if (!$schema->isLookup()) {
|
// FIXME do not break lookup autocompletion, whatever that is
|
||||||
|
if (true) {
|
||||||
$sql .= "AND PAGEEXISTS(D.pid) = 1\n";
|
$sql .= "AND PAGEEXISTS(D.pid) = 1\n";
|
||||||
$sql .= "AND GETACCESSLEVEL(D.pid) > 0\n";
|
$sql .= "AND GETACCESSLEVEL(D.pid) > 0\n";
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user