mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-21 12:54:26 +02:00
db: Add tables and models for config storage
This commit is contained in:
parent
67285ce262
commit
f9ee442274
@ -14,3 +14,23 @@ ALTER TABLE `icingaweb_user_preference`
|
||||
MODIFY COLUMN `username` varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
MODIFY COLUMN `section` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
MODIFY COLUMN `name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL;
|
||||
|
||||
CREATE TABLE `icingaweb_config_scope`(
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`module` varchar(254) NOT NULL DEFAULT 'default',
|
||||
`type` varchar(64) NOT NULL,
|
||||
`name` varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`hash` binary(20) NOT NULL COMMENT 'sha1(all option tuples)',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_module_type_name` (`module`, `type`, `name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `icingaweb_config_option`(
|
||||
`scope_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(254) NOT NULL,
|
||||
`value` text DEFAULT NULL,
|
||||
UNIQUE KEY `idx_scope_id_name` (`scope_id`, `name`),
|
||||
CONSTRAINT `fk_scope_id_config_scope` FOREIGN KEY (`scope_id`)
|
||||
REFERENCES `icingaweb_config_scope` (`id`)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
@ -52,3 +52,23 @@ CREATE TABLE `icingaweb_rememberme`(
|
||||
mtime timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
CREATE TABLE `icingaweb_config_scope`(
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`module` varchar(254) NOT NULL DEFAULT 'default',
|
||||
`type` varchar(64) NOT NULL,
|
||||
`name` varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`hash` binary(20) NOT NULL COMMENT 'sha1(all option tuples)',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_module_type_name` (`module`, `type`, `name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `icingaweb_config_option`(
|
||||
`scope_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(254) NOT NULL,
|
||||
`value` text DEFAULT NULL,
|
||||
UNIQUE KEY `idx_scope_id_name` (`scope_id`, `name`),
|
||||
CONSTRAINT `fk_scope_id_config_scope` FOREIGN KEY (`scope_id`)
|
||||
REFERENCES `icingaweb_config_scope` (`id`)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
48
etc/schema/pgsql-upgrades/2.11.0.sql
Normal file
48
etc/schema/pgsql-upgrades/2.11.0.sql
Normal file
@ -0,0 +1,48 @@
|
||||
CREATE EXTENSION IF NOT EXISTS citext;
|
||||
CREATE DOMAIN bytea20 AS bytea CONSTRAINT exactly_20_bytes_long CHECK ( VALUE IS NULL OR octet_length(VALUE) = 20 );
|
||||
|
||||
CREATE TABLE "icingaweb_config_scope" (
|
||||
"id" serial,
|
||||
"module" character varying(254) NOT NULL DEFAULT 'default',
|
||||
"type" character varying(64) NOT NULL,
|
||||
"name" citext NOT NULL,
|
||||
"hash" bytea20 NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN icingaweb_config_scope.hash IS 'sha1(all option tuples)';
|
||||
|
||||
ALTER TABLE ONLY "icingaweb_config_scope"
|
||||
ADD CONSTRAINT pk_icingaweb_config_scope
|
||||
PRIMARY KEY (
|
||||
"id"
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_module_type_name
|
||||
ON "icingaweb_config_scope"
|
||||
USING btree (
|
||||
lower((module)::text),
|
||||
lower((type)::text),
|
||||
lower((name)::text)
|
||||
);
|
||||
|
||||
CREATE TABLE "icingaweb_config_option" (
|
||||
"scope_id" int NOT NULL,
|
||||
"name" character varying(254) NOT NULL,
|
||||
"value" text DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_scope_id_name
|
||||
ON "icingaweb_config_option"
|
||||
USING btree (
|
||||
scope_id,
|
||||
lower((name)::text)
|
||||
);
|
||||
|
||||
ALTER TABLE ONLY "icingaweb_config_option"
|
||||
ADD CONSTRAINT fk_scope_id_config_scope
|
||||
FOREIGN KEY (
|
||||
"scope_id"
|
||||
)
|
||||
REFERENCES "icingaweb_config_scope" (
|
||||
"id"
|
||||
) ON DELETE CASCADE;
|
@ -4,6 +4,9 @@ CREATE OR REPLACE FUNCTION unix_timestamp(timestamp with time zone) RETURNS bigi
|
||||
SELECT EXTRACT(EPOCH FROM $1)::bigint AS result
|
||||
' LANGUAGE sql;
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS citext;
|
||||
CREATE DOMAIN bytea20 AS bytea CONSTRAINT exactly_20_bytes_long CHECK ( VALUE IS NULL OR octet_length(VALUE) = 20 );
|
||||
|
||||
CREATE TABLE "icingaweb_group" (
|
||||
"id" serial,
|
||||
"name" character varying(64) NOT NULL,
|
||||
@ -117,3 +120,49 @@ ALTER TABLE ONLY "icingaweb_rememberme"
|
||||
PRIMARY KEY (
|
||||
"id"
|
||||
);
|
||||
|
||||
CREATE TABLE "icingaweb_config_scope" (
|
||||
"id" serial,
|
||||
"module" character varying(254) NOT NULL DEFAULT 'default',
|
||||
"type" character varying(64) NOT NULL,
|
||||
"name" citext NOT NULL,
|
||||
"hash" bytea20 NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN icingaweb_config_scope.hash IS 'sha1(all option tuples)';
|
||||
|
||||
ALTER TABLE ONLY "icingaweb_config_scope"
|
||||
ADD CONSTRAINT pk_icingaweb_config_scope
|
||||
PRIMARY KEY (
|
||||
"id"
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_module_type_name
|
||||
ON "icingaweb_config_scope"
|
||||
USING btree (
|
||||
lower((module)::text),
|
||||
lower((type)::text),
|
||||
lower((name)::text)
|
||||
);
|
||||
|
||||
CREATE TABLE "icingaweb_config_option" (
|
||||
"scope_id" int NOT NULL,
|
||||
"name" character varying(254) NOT NULL,
|
||||
"value" text DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_scope_id_name
|
||||
ON "icingaweb_config_option"
|
||||
USING btree (
|
||||
scope_id,
|
||||
lower((name)::text)
|
||||
);
|
||||
|
||||
ALTER TABLE ONLY "icingaweb_config_option"
|
||||
ADD CONSTRAINT fk_scope_id_config_scope
|
||||
FOREIGN KEY (
|
||||
"scope_id"
|
||||
)
|
||||
REFERENCES "icingaweb_config_scope" (
|
||||
"id"
|
||||
) ON DELETE CASCADE;
|
||||
|
56
library/Icinga/Model/ConfigOption.php
Normal file
56
library/Icinga/Model/ConfigOption.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
|
||||
|
||||
namespace Icinga\Model;
|
||||
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Orm\Relations;
|
||||
|
||||
class ConfigOption extends Model
|
||||
{
|
||||
public function getTableName()
|
||||
{
|
||||
return 'icingaweb_config_option';
|
||||
}
|
||||
|
||||
public function getKeyName()
|
||||
{
|
||||
return [
|
||||
'scope_id',
|
||||
'name'
|
||||
];
|
||||
}
|
||||
|
||||
public function getColumns()
|
||||
{
|
||||
return [
|
||||
'scope_id',
|
||||
'name',
|
||||
'value'
|
||||
];
|
||||
}
|
||||
|
||||
public function getMetaData()
|
||||
{
|
||||
return [
|
||||
'name' => t('Config Option Name'),
|
||||
'value' => t('Config Option Value')
|
||||
];
|
||||
}
|
||||
|
||||
public function getSearchColumns()
|
||||
{
|
||||
return ['name'];
|
||||
}
|
||||
|
||||
public function getDefaultSort()
|
||||
{
|
||||
return 'icingaweb_config_option.name';
|
||||
}
|
||||
|
||||
public function createRelations(Relations $relations)
|
||||
{
|
||||
$relations->belongsTo('scope', ConfigScope::class)
|
||||
->setCandidateKey('scope_id');
|
||||
}
|
||||
}
|
102
library/Icinga/Model/ConfigScope.php
Normal file
102
library/Icinga/Model/ConfigScope.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
|
||||
|
||||
namespace Icinga\Model;
|
||||
|
||||
use ipl\Orm\Behaviors;
|
||||
use ipl\Orm\Contract\PropertyBehavior;
|
||||
use ipl\Orm\Contract\QueryAwareBehavior;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Orm\Query;
|
||||
use ipl\Orm\Relations;
|
||||
use ipl\Sql\Adapter\Pgsql;
|
||||
|
||||
use function ipl\Stdlib\get_php_type;
|
||||
|
||||
class ConfigScope extends Model
|
||||
{
|
||||
public function getTableName()
|
||||
{
|
||||
return 'icingaweb_config_scope';
|
||||
}
|
||||
|
||||
public function getKeyName()
|
||||
{
|
||||
return 'id';
|
||||
}
|
||||
|
||||
public function getColumns()
|
||||
{
|
||||
return [
|
||||
'module',
|
||||
'type',
|
||||
'name',
|
||||
'hash'
|
||||
];
|
||||
}
|
||||
|
||||
public function getMetaData()
|
||||
{
|
||||
return [
|
||||
'module' => t('Config Scope Module'),
|
||||
'type' => t('Config Scope Type'),
|
||||
'name' => t('Config Scope Name'),
|
||||
'hash' => t('Config Scope Hash')
|
||||
];
|
||||
}
|
||||
|
||||
public function getSearchColumns()
|
||||
{
|
||||
return ['name'];
|
||||
}
|
||||
|
||||
public function getDefaultSort()
|
||||
{
|
||||
return 'icingaweb_config_scope.name';
|
||||
}
|
||||
|
||||
public function createBehaviors(Behaviors $behaviors)
|
||||
{
|
||||
$binary = new class (['hash']) extends PropertyBehavior implements QueryAwareBehavior {
|
||||
public function setQuery(Query $query)
|
||||
{
|
||||
if (! $query->getDb()->getAdapter() instanceof Pgsql) {
|
||||
$this->properties = [];
|
||||
}
|
||||
}
|
||||
|
||||
public function fromDb($value, $key, $context)
|
||||
{
|
||||
if ($value !== null) {
|
||||
if (! is_resource($value)) {
|
||||
throw new \UnexpectedValueException(
|
||||
sprintf('%s should be a resource got %s instead', $key, get_php_type($value))
|
||||
);
|
||||
}
|
||||
|
||||
return stream_get_contents($value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toDb($value, $key, $context)
|
||||
{
|
||||
if (is_resource($value)) {
|
||||
throw new \UnexpectedValueException(sprintf('Unexpected resource for %s', $key));
|
||||
}
|
||||
|
||||
return sprintf('\\x%s', bin2hex($value));
|
||||
}
|
||||
};
|
||||
|
||||
$behaviors->add($binary);
|
||||
}
|
||||
|
||||
public function createRelations(Relations $relations)
|
||||
{
|
||||
$relations->hasMany('option', ConfigOption::class)
|
||||
->setForeignKey('scope_id')
|
||||
->setJoinType('LEFT');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user