summaryrefslogtreecommitdiffstats
path: root/config-db/OpenSLX
diff options
context:
space:
mode:
authorOliver Tappe2008-01-04 17:50:15 +0100
committerOliver Tappe2008-01-04 17:50:15 +0100
commit9507d838668846666d2c790a0a1e6e51eb8670de (patch)
tree2c843db4b2865319b8d26604c212c5fea07e5bbc /config-db/OpenSLX
parentmore work at refactoring of the way attributes are handled: (diff)
downloadcore-9507d838668846666d2c790a0a1e6e51eb8670de.tar.gz
core-9507d838668846666d2c790a0a1e6e51eb8670de.tar.xz
core-9507d838668846666d2c790a0a1e6e51eb8670de.zip
more refactoring (not limited to attribute handling)
* completed separation of attributes and standard (column) values * improved tests a lot That work is still not finished, so expect things to fail horribly. git-svn-id: http://svn.openslx.org/svn/openslx/trunk@1443 95ad53e4-c205-0410-b2fa-d234c58c8868
Diffstat (limited to 'config-db/OpenSLX')
-rw-r--r--config-db/OpenSLX/ConfigDB.pm301
-rw-r--r--config-db/OpenSLX/DBSchema.pm173
-rw-r--r--config-db/OpenSLX/MetaDB/DBI.pm543
3 files changed, 661 insertions, 356 deletions
diff --git a/config-db/OpenSLX/ConfigDB.pm b/config-db/OpenSLX/ConfigDB.pm
index 95183c95..289f6f7f 100644
--- a/config-db/OpenSLX/ConfigDB.pm
+++ b/config-db/OpenSLX/ConfigDB.pm
@@ -561,6 +561,15 @@ sub fetchSystemByFilter
$filter, $resultCols, $attrFilter
);
+ # unless specific result cols have been given, we mix in the attributes
+ # of each system, too:
+ if (!defined $resultCols) {
+ foreach my $system (@systems) {
+ $system->{attrs}
+ = $self->{'meta-db'}->fetchSystemAttrs($system->{id});
+ }
+ }
+
return wantarray() ? @systems : shift @systems;
}
@@ -596,91 +605,16 @@ sub fetchSystemByID
# unless specific result cols have been given, we mix in the attributes
# of each system, too:
-# if (!defined $resultCols) {
-# foreach my $system (@systems) {
-# $system->{attrs}
-# = $self->{'meta-db'}->fetchSystemAttrs($system->{id});
-# }
-# }
+ if (!defined $resultCols) {
+ foreach my $system (@systems) {
+ $system->{attrs}
+ = $self->{'meta-db'}->fetchSystemAttrs($system->{id});
+ }
+ }
return wantarray() ? @systems : shift @systems;
}
-=item C<fetchSystemAttrs($systemID, [$attrNames])>
-
-Fetches and returns the information about the attributes of the system
-with the given ID.
-
-=over
-
-=item Param C<$systemID>
-
-The ID of the system whose attributes you are interested in.
-
-=item Param C<$attrNames> [Optional]
-
-A comma-separated list of attribute names that shall be returned. If not
-defined,all available attributes will be returned.
-
-=item Return Value
-
-An array of hash-refs containing the resulting data rows (or a single hash-ref
-mapping all attribute names to the respective value).
-
-=back
-
-=cut
-
-sub fetchSystemAttrs
-{
- my $self = shift;
- my $systemID = shift;
- my $attrNames = shift;
-
- my @attrs = $self->{'meta-db'}->fetchSystemAttrs($systemID, $attrNames);
-
- return wantarray() ? @attrs : shift @attrs;
-}
-
-=item C<fetchSystemAttrsAsHash($systemID, [$attrNames])>
-
-Fetches and returns the information about the attributes of the system
-with the given ID.
-
-=over
-
-=item Param C<$systemID>
-
-The ID of the system whose attributes you are interested in.
-
-=item Param C<$attrNames> [Optional]
-
-A comma-separated list of attribute names that shall be returned. If not
-defined,all available attributes will be returned.
-
-=item Return Value
-
-A single hash-ref mapping all attribute names to their respective value.
-
-=back
-
-=cut
-
-sub fetchSystemAttrsAsHash
-{
- my $self = shift;
- my $systemID = shift;
- my $attrNames = shift;
-
- my @attrs = $self->{'meta-db'}->fetchSystemAttrs($systemID, $attrNames);
-
- my $Result = {};
- foreach my $attr (@attrs) {
- $Result->{$attr->{name}} = $attr->{value};
- }
- return $Result;
-}
-
=item C<fetchSystemIDsOfExport($id)>
Fetches the IDs of all systems that make use of the export with the given ID.
@@ -787,10 +721,23 @@ An array of hash-refs containing the resulting data rows.
sub fetchClientByFilter
{
- my $self = shift;
- my $filter = shift;
+ my $self = shift;
+ my $filter = shift;
+ my $resultCols = shift;
+ my $attrFilter = shift;
- my @clients = $self->{'meta-db'}->fetchClientByFilter($filter);
+ my @clients = $self->{'meta-db'}->fetchClientByFilter(
+ $filter, $resultCols, $attrFilter
+ );
+
+ # unless specific result cols have been given, we mix in the attributes
+ # of each client, too:
+ if (!defined $resultCols) {
+ foreach my $client (@clients) {
+ $client->{attrs}
+ = $self->{'meta-db'}->fetchClientAttrs($client->{id});
+ }
+ }
return wantarray() ? @clients : shift @clients;
}
@@ -825,6 +772,15 @@ sub fetchClientByID
my @clients = $self->{'meta-db'}->fetchClientByID($ids, $resultCols);
+ # unless specific result cols have been given, we mix in the attributes
+ # of each client, too:
+ if (!defined $resultCols) {
+ foreach my $client (@clients) {
+ $client->{attrs}
+ = $self->{'meta-db'}->fetchClientAttrs($client->{id});
+ }
+ }
+
return wantarray() ? @clients : shift @clients;
}
@@ -911,8 +867,20 @@ sub fetchGroupByFilter
my $self = shift;
my $filter = shift;
my $resultCols = shift;
+ my $attrFilter = shift;
- my @groups = $self->{'meta-db'}->fetchGroupByFilter($filter, $resultCols);
+ my @groups = $self->{'meta-db'}->fetchGroupByFilter(
+ $filter, $resultCols, $attrFilter
+ );
+
+ # unless specific result cols have been given, we mix in the attributes
+ # of each group, too:
+ if (!defined $resultCols) {
+ foreach my $group (@groups) {
+ $group->{attrs}
+ = $self->{'meta-db'}->fetchGroupAttrs($group->{id});
+ }
+ }
return wantarray() ? @groups : shift @groups;
}
@@ -947,6 +915,15 @@ sub fetchGroupByID
my @groups = $self->{'meta-db'}->fetchGroupByID($ids, $resultCols);
+ # unless specific result cols have been given, we mix in the attributes
+ # of each group, too:
+ if (!defined $resultCols) {
+ foreach my $group (@groups) {
+ $group->{attrs}
+ = $self->{'meta-db'}->fetchGroupAttrs($group->{id});
+ }
+ }
+
return wantarray() ? @groups : shift @groups;
}
@@ -1707,6 +1684,43 @@ sub changeClient
return $self->{'meta-db'}->changeClient($clientIDs, $valRows);
}
+=item C<setClientAttr($clientID, $attrName, $attrValue)>
+
+Sets a value for an attribute of the given client. If the client already
+has a value for this attribute, it will be overwritten.
+
+=over
+
+=item Param C<clientID>
+
+The ID of the client whose attribute shall be changed.
+
+=item Param C<attrName>
+
+The name of the attribute to change.
+
+=item Param C<attrValue>
+
+The new value for the attribute.
+
+=item Return Value
+
+C<1> if the attribute could be set, C<undef> if not.
+
+=back
+
+=cut
+
+sub setClientAttr
+{
+ my $self = shift;
+ my $clientID = shift;
+ my $attrName = shift;
+ my $attrValue = shift;
+
+ return $self->{'meta-db'}->setClientAttr($clientID, $attrName, $attrValue);
+}
+
=item C<setSystemIDsOfClient($clientID, @$systemIDs)>
Specifies all systems that should be offered for booting by the given client.
@@ -1987,6 +2001,43 @@ sub removeGroup
return $self->{'meta-db'}->removeGroup($groupIDs);
}
+=item C<setGroupAttr($groupID, $attrName, $attrValue)>
+
+Sets a value for an attribute of the given group. If the group already
+has a value for this attribute, it will be overwritten.
+
+=over
+
+=item Param C<groupID>
+
+The ID of the group whose attribute shall be changed.
+
+=item Param C<attrName>
+
+The name of the attribute to change.
+
+=item Param C<attrValue>
+
+The new value for the attribute.
+
+=item Return Value
+
+C<1> if the attribute could be set, C<undef> if not.
+
+=back
+
+=cut
+
+sub setGroupAttr
+{
+ my $self = shift;
+ my $groupID = shift;
+ my $attrName = shift;
+ my $attrValue = shift;
+
+ return $self->{'meta-db'}->setGroupAttr($groupID, $attrName, $attrValue);
+}
+
=item C<changeGroup(@$groupIDs, @$valRows)>
Changes the data of one or more groups.
@@ -2588,13 +2639,17 @@ sub mergeAttributes
my $target = shift;
my $source = shift;
- foreach my $key (keys %$source) {
- next if !isAttribute($key);
- my $sourceVal = $source->{$key} || '';
- my $targetVal = $target->{$key} || '';
- if (length($sourceVal) && !length($targetVal)) {
- vlog(3, _tr("merging %s (val=%s)", $key, $sourceVal));
- $target->{$key} = $sourceVal;
+ my $sourceAttrs = $source->{attrs} || {};
+
+ $target->{attrs} ||= {};
+ my $targetAttrs = $target->{attrs};
+
+ foreach my $key (keys %$sourceAttrs) {
+ my $sourceVal = $sourceAttrs->{$key};
+ my $targetVal = $targetAttrs->{$key};
+ if (defined $sourceVal && !defined $targetVal) {
+ vlog(0, _tr("merging %s (val=%s)", $key, $sourceVal));
+ $targetAttrs->{$key} = $sourceVal;
}
}
@@ -2628,11 +2683,16 @@ sub pushAttributes
my $target = shift;
my $source = shift;
- foreach my $key (grep { isAttribute($_) } keys %$source) {
- my $sourceVal = $source->{$key} || '';
- if (length($sourceVal)) {
+ my $sourceAttrs = $source->{attrs} || {};
+
+ $target->{attrs} ||= {};
+ my $targetAttrs = $target->{attrs};
+
+ foreach my $key (keys %$sourceAttrs) {
+ my $sourceVal = $sourceAttrs->{$key};
+ if (defined $sourceVal) {
vlog(3, _tr("pushing %s (val=%s)", $key, $sourceVal));
- $target->{$key} = $sourceVal;
+ $targetAttrs->{$key} = $sourceVal;
}
}
@@ -2826,54 +2886,7 @@ sub _checkAndUpgradeDBSchemaIfNecessary
$DbSchema->{version}, $currVersion
)
);
- foreach my $v (sort { $a <=> $b } keys %DbSchemaHistory) {
- next if $v <= $currVersion;
- my $changeSet = $DbSchemaHistory{$v};
- foreach my $c (0 .. scalar(@$changeSet) - 1) {
- my $changeDescr = @{$changeSet}[$c];
- my $cmd = $changeDescr->{cmd};
- if ($cmd eq 'add-table') {
- $metaDB->schemaAddTable(
- $changeDescr->{'table'},
- $changeDescr->{'cols'},
- $changeDescr->{'vals'}
- );
- } elsif ($cmd eq 'drop-table') {
- $metaDB->schemaDropTable($changeDescr->{'table'});
- } elsif ($cmd eq 'rename-table') {
- $metaDB->schemaRenameTable(
- $changeDescr->{'old-table'},
- $changeDescr->{'new-table'},
- $changeDescr->{'cols'}
- );
- } elsif ($cmd eq 'add-columns') {
- $metaDB->schemaAddColumns(
- $changeDescr->{'table'},
- $changeDescr->{'new-cols'},
- $changeDescr->{'new-default-vals'},
- $changeDescr->{'cols'}
- );
- } elsif ($cmd eq 'drop-columns') {
- $metaDB->schemaDropColumns(
- $changeDescr->{'table'},
- $changeDescr->{'drop-cols'},
- $changeDescr->{'cols'}
- );
- } elsif ($cmd eq 'rename-columns') {
- $metaDB->schemaRenameColumns(
- $changeDescr->{'table'},
- $changeDescr->{'col-renames'},
- $changeDescr->{'cols'}
- );
- } elsif ($cmd eq 'perl-func') {
- if (!$changeDescr->{code}->($self)) {
- croak _tr('problem in perl-func cmd!');
- }
- } else {
- croak _tr('UnknownDbSchemaCommand', $cmd);
- }
- }
- }
+ $metaDB->schemaUpgradeDBFrom($currVersion);
$metaDB->schemaSetDBVersion($DbSchema->{version});
vlog(1, _tr('upgrade done'));
} else {
diff --git a/config-db/OpenSLX/DBSchema.pm b/config-db/OpenSLX/DBSchema.pm
index 54596c9f..801f50a9 100644
--- a/config-db/OpenSLX/DBSchema.pm
+++ b/config-db/OpenSLX/DBSchema.pm
@@ -33,12 +33,7 @@ use OpenSLX::Basics;
use POSIX qw(locale_h);
my $lang = setlocale(LC_MESSAGES);
-my $country;
-if ($lang =~ m[^\w\w_(\w\w)]) {
- $country = lc($1);
-} else {
- $country = 'us';
-}
+my $country = $lang =~ m[^\w\w_(\w\w)] ? lc($1) : 'us';
################################################################################
### DB-schema definition
@@ -73,12 +68,22 @@ $DbSchema = {
],
'vals' => [
{ # add default client
- 'id' => 0,
- 'name' => '<<<default>>>',
- 'comment' => 'internal client that holds default values',
+ 'id' => 0,
+ 'name' => '<<<default>>>',
+ 'comment' => 'internal client that holds default values',
+ 'unbootable' => 0,
},
],
},
+ 'client_attr' => {
+ # attributes of clients
+ 'cols' => [
+ 'id:pk', # primary key
+ 'client_id:fk', # foreign key to client
+ 'name:s.128', # attribute name
+ 'value:s.255', # attribute value
+ ],
+ },
'client_system_ref' => {
# clients referring to the systems they should offer for booting
'cols' => [
@@ -134,6 +139,15 @@ $DbSchema = {
'comment:s.1024', # internal comment (optional, for admins)
],
},
+ 'group_attr' => {
+ # attributes of groups
+ 'cols' => [
+ 'id:pk', # primary key
+ 'group_id:fk', # foreign key to group
+ 'name:s.128', # attribute name
+ 'value:s.255', # attribute value
+ ],
+ },
'group_client_ref' => {
# groups referring to their clients
'cols' => [
@@ -394,146 +408,9 @@ $DbSchema = {
};
################################################################################
-### DB-schema history
-###
-### This hash contains a description of all the different changes that have
-### taken place on the schema. Each version contains a changeset (array)
-### with the commands that take the schema from the last version to the
-### current.
-###
-### The following 'cmd'-types are supported:
-###
-### add-table => creates a new table
-### 'table' => contains the name of the new table
-### 'cols' => contains a list of column descriptions
-### 'vals' => optional, contains list of data hashes to be inserted
-### into new table
-###
-### drop-table => drops an existing table
-### 'table => contains the name of the table to be dropped
-###
-### rename-table => renames a table
-### 'old-table' => contains the old name of the table
-### 'new-table' => contains the new name of the table
-### 'cols' => contains a full list of column descriptions
-###
-### add-columns => adds columns to a table
-### 'table' => the name of the table the columns should be added to
-### 'new-cols' => contains a list of new column descriptions
-### 'new-default-vals' => optional, a list of data hashes to be used
-### as default values for the new columns
-### 'cols' => contains a full list of resulting column descriptions
-###
-### drop-columns => drops columns from a table
-### 'table' => the name of the table the columns should be dropped from
-### 'drop-cols' => a list of column names to be dropped
-### 'cols' => contains a full list of resulting column descriptions
-###
-### perl-func => a perl function invoked with config-DB object as param
-### 'code' => the function (sub) that shall be executed
-###
-################################################################################
-
-%DbSchemaHistory = (
- '0.01' => [
- # there's no need to upgrade to the initial schema version, as we
- # create the newest schema automatically if none exists yet.
- ],
- '0.2' => [
- # move attributes into separate tables ...
- #
- # ... system attributes ...
- {
- 'cmd' => 'add-table',
- 'table' => 'system_attr',
- 'cols' => [
- 'id:pk',
- 'system_id:fk',
- 'name:s.128',
- 'value:s.255',
- ],
- },
- {
- 'cmd' => 'perl-func',
- 'code' => sub {
- my $configDB = shift;
- foreach my $system ($configDB->fetchSystemByFilter()) {
- foreach my $key (keys %$system) {
- next if substr($key, 0, 5) ne 'attr_';
- my $attrValue = $system->{$key} || '';
- next if $system->{id}>0 && !length($attrValue);
- my $newAttrName = substr($key, 5);
- $configDB->setSystemAttr(
- $system->{id}, $newAttrName, $attrValue
- );
- }
- }
- 1;
- }
- },
- {
- 'cmd' => 'drop-columns',
- 'table' => 'system',
- 'drop-cols' => [
- 'attr_automnt_dir',
- 'attr_automnt_src',
- 'attr_country',
- 'attr_dm_allow_shutdown',
- 'attr_hw_graphic',
- 'attr_hw_monitor',
- 'attr_hw_mouse',
- 'attr_late_dm',
- 'attr_netbios_workgroup',
- 'attr_nis_domain',
- 'attr_nis_servers',
- 'attr_ramfs_fsmods',
- 'attr_ramfs_miscmods',
- 'attr_ramfs_nicmods',
- 'attr_ramfs_screen',
- 'attr_sane_scanner',
- 'attr_scratch',
- 'attr_slxgrp',
- 'attr_start_alsasound',
- 'attr_start_atd',
- 'attr_start_cron',
- 'attr_start_dreshal',
- 'attr_start_ntp',
- 'attr_start_nfsv4',
- 'attr_start_printer',
- 'attr_start_samba',
- 'attr_start_snmp',
- 'attr_start_sshd',
- 'attr_start_syslog',
- 'attr_start_x',
- 'attr_start_xdmcp',
- 'attr_tex_enable',
- 'attr_timezone',
- 'attr_tvout',
- 'attr_vmware',
- ],
- 'cols' => [
- 'id:pk',
- 'export_id:fk',
- 'name:s.64',
- 'label:s.64',
- 'kernel:s.128',
- 'kernel_params:s.512',
- 'hidden:b',
- 'comment:s.1024',
- ],
- },
- #
- # ... client attributes ...
- #
- # ... group attributes ...
- ],
-);
-
-
-################################################################################
###
-### Load all available AttrInfo modules and build the complete hash containing
-### info about all known attributes from that.
+### Load the available AttrInfo-modules and build a hash containing info about
+### all known attributes from the data contained in those modules.
###
################################################################################
diff --git a/config-db/OpenSLX/MetaDB/DBI.pm b/config-db/OpenSLX/MetaDB/DBI.pm
index 774ab90e..98754777 100644
--- a/config-db/OpenSLX/MetaDB/DBI.pm
+++ b/config-db/OpenSLX/MetaDB/DBI.pm
@@ -78,14 +78,13 @@ sub _trim
sub _buildFilterClause
{
- my $self = shift;
- my $filter = shift || {};
- my $connector = shift;
+ my $self = shift;
+ my $filter = shift || {};
+ my $filterClause = shift || '';
- my $filterClause = '';
- my ($quotedVal);
+ my ($connector, $quotedVal);
foreach my $col (keys %$filter) {
- $connector = !defined $connector ? 'WHERE' : 'AND';
+ $connector = !length($filterClause) ? 'WHERE' : 'AND';
if (defined $filter->{$col}) {
$quotedVal = $self->{dbh}->quote($filter->{$col});
$filterClause .= " $connector $col = $quotedVal";
@@ -94,42 +93,48 @@ sub _buildFilterClause
}
}
- return $filterClause;
+ return $filterClause || '';
}
sub _buildAttrFilterClause
{
- my $self = shift;
- my $attrFilter = shift || {};
- my $connector = shift;
+ my $self = shift;
+ my $attrFilter = shift || {};
+ my $table = shift;
+ my $filterClause = shift || '';
+
+ my %tableMap = (
+ 'client' => 'client',
+ 'group' => 'groups',
+ 'system' => 'system',
+ );
- my $attrFilterClause = '';
- my ($quotedName, $quotedValue);
+ my ($connector, $quotedName, $quotedValue);
foreach my $name (keys %$attrFilter) {
- $connector = !defined $connector ? 'WHERE' : 'AND';
+ $connector = !length($filterClause) ? 'WHERE' : 'AND';
$quotedName = $self->{dbh}->quote($name);
if (defined $attrFilter->{$name}) {
$quotedValue = $self->{dbh}->quote($attrFilter->{$name});
- $attrFilterClause .= <<" End-of-Here";
+ $filterClause .= <<" End-of-Here";
$connector EXISTS (
- SELECT name FROM system_attr
+ SELECT name FROM ${table}_attr
WHERE name = $quotedName
AND value = $quotedValue
- AND system_id = system.id
+ AND ${table}_id = $tableMap{$table}.id
)
End-of-Here
} else {
- $attrFilterClause .= <<" End-of-Here";
+ $filterClause .= <<" End-of-Here";
$connector NOT EXISTS (
- SELECT name FROM system_attr
+ SELECT name FROM ${table}_attr
WHERE name = $quotedName
- AND system_id = system.id
+ AND ${table}_id = $tableMap{$table}.id
)
End-of-Here
}
}
- return $attrFilterClause;
+ return $filterClause;
}
sub _doSelect
@@ -245,13 +250,13 @@ sub fetchSystemByFilter
my $attrFilter = shift;
$resultCols = '*' unless (defined $resultCols);
- my $filterClause = $self->_buildFilterClause($filter, 'AND');
- my $attrFilterClause = $self->_buildAttrFilterClause($attrFilter, 'AND');
+ my $filterClause = $self->_buildFilterClause($filter);
+ $filterClause = $self->_buildAttrFilterClause(
+ $attrFilter, 'system', $filterClause
+ );
my $sql = <<" End-of-Here";
SELECT $resultCols FROM system
- WHERE 1=1
$filterClause
- $attrFilterClause
End-of-Here
return $self->_doSelect($sql);
}
@@ -273,17 +278,17 @@ sub fetchSystemAttrs
{
my $self = shift;
my $systemID = $self->{dbh}->quote(shift);
- my $attrNames = shift;
my $sql = <<" End-of-Here";
- SELECT id, name, value FROM system_attr
+ SELECT name, value FROM system_attr
WHERE system_id = $systemID
End-of-Here
- if (defined $attrNames) {
- my $attrList = join ',', map { $self->{dbh}->quote($_) } @$attrNames;
- $sql .= " AND name IN ($attrList)";
+ my @attrs = $self->_doSelect($sql);
+ my $Result = {};
+ foreach my $attr (@attrs) {
+ $Result->{$attr->{name}} = $attr->{value};
}
- return $self->_doSelect($sql);
+ return $Result;
}
sub fetchSystemIDsOfExport
@@ -324,10 +329,17 @@ sub fetchClientByFilter
my $self = shift;
my $filter = shift;
my $resultCols = shift;
+ my $attrFilter = shift;
$resultCols = '*' unless (defined $resultCols);
my $filterClause = $self->_buildFilterClause($filter);
- my $sql = "SELECT $resultCols FROM client $filterClause";
+ $filterClause = $self->_buildAttrFilterClause(
+ $attrFilter, 'client', $filterClause
+ );
+ my $sql = <<" End-of-Here";
+ SELECT $resultCols FROM client
+ $filterClause
+ End-of-Here
return $self->_doSelect($sql);
}
@@ -344,6 +356,23 @@ sub fetchClientByID
return $self->_doSelect($sql);
}
+sub fetchClientAttrs
+{
+ my $self = shift;
+ my $clientID = $self->{dbh}->quote(shift);
+
+ my $sql = <<" End-of-Here";
+ SELECT name, value FROM client_attr
+ WHERE client_id = $clientID
+ End-of-Here
+ my @attrs = $self->_doSelect($sql);
+ my $Result = {};
+ foreach my $attr (@attrs) {
+ $Result->{$attr->{name}} = $attr->{value};
+ }
+ return $Result;
+}
+
sub fetchClientIDsOfSystem
{
my $self = shift;
@@ -371,10 +400,17 @@ sub fetchGroupByFilter
my $self = shift;
my $filter = shift;
my $resultCols = shift;
+ my $attrFilter = shift;
$resultCols = '*' unless (defined $resultCols);
my $filterClause = $self->_buildFilterClause($filter);
- my $sql = "SELECT $resultCols FROM groups $filterClause";
+ $filterClause = $self->_buildAttrFilterClause(
+ $attrFilter, 'group', $filterClause
+ );
+ my $sql = <<" End-of-Here";
+ SELECT $resultCols FROM groups
+ $filterClause
+ End-of-Here
return $self->_doSelect($sql);
}
@@ -391,6 +427,23 @@ sub fetchGroupByID
return $self->_doSelect($sql);
}
+sub fetchGroupAttrs
+{
+ my $self = shift;
+ my $groupID = $self->{dbh}->quote(shift);
+
+ my $sql = <<" End-of-Here";
+ SELECT name, value FROM group_attr
+ WHERE group_id = $groupID
+ End-of-Here
+ my @attrs = $self->_doSelect($sql);
+ my $Result = {};
+ foreach my $attr (@attrs) {
+ $Result->{$attr->{name}} = $attr->{value};
+ }
+ return $Result;
+}
+
sub fetchGroupIDsOfSystem
{
my $self = shift;
@@ -505,20 +558,22 @@ sub _doUpdate
my $dbh = $self->{'dbh'};
my $valRow = (@$valRows)[0];
- return if !defined $valRow || !scalar keys %$valRow;
+ return 1 if !defined $valRow || !scalar keys %$valRow;
my $idx = 0;
foreach my $valRow (@$valRows) {
my $id = $IDs->[$idx++];
my %valData = %$valRow;
- delete $valData{'id'};
- # filter column 'id' if present, as we don't want to update it
+ # fail if asked to change the column 'id', as that is bogus
+ return if exists $valData{id} && $valData{id} ne $id;
+ # filter column 'id' if present, as we don't want to write it
+ delete $valData{id};
my @cols = map { "$_ = " . $self->quote($valRow->{$_}) }
grep { $_ ne 'id' }
# filter column 'id' if present, as we don't want
# to update it!
keys %$valRow;
- return if !@cols;
+ next if !@cols;
my $cols = join ', ', @cols;
my $sql = "UPDATE $table SET $cols";
if (defined $id) {
@@ -661,7 +716,26 @@ sub addSystem
my $self = shift;
my $valRows = shift;
- return $self->_doInsert('system', $valRows);
+ # separate the attribute hashes ...
+ my @attrValRows
+ = map {
+ my $attrs = $_->{attrs};
+ delete $_->{attrs};
+ $attrs;
+ }
+ @$valRows;
+
+ # ... store the systems to get the IDs ...
+ my @systemIDs = $self->_doInsert('system', $valRows);
+
+ # ... finally store the individual attribute sets
+ foreach my $id (@systemIDs) {
+ my $attrs = shift @attrValRows;
+ next if !defined $attrs;
+ return if !$self->setSystemAttrs($id, $attrs);
+ }
+
+ return @systemIDs;
}
sub removeSystem
@@ -678,37 +752,44 @@ sub changeSystem
my $systemIDs = shift;
my $valRows = shift;
+ # separate the attribute hashes and store them individually
+ my @attrValRows
+ = map {
+ my $attrs = $_->{attrs};
+ delete $_->{attrs};
+ $attrs;
+ }
+ @$valRows;
+ foreach my $id (@$systemIDs) {
+ my $attrs = shift @attrValRows;
+ next if !defined $attrs;
+ return if !$self->setSystemAttrs($id, $attrs);
+ }
+
+ # finally update all systems in one go
return $self->_doUpdate('system', $systemIDs, $valRows);
}
-sub setSystemAttr
+sub setSystemAttrs
{
- my $self = shift;
- my $systemID = shift;
- my $attrName = shift;
- my $attrValue = shift;
-
- my $quotedSystemID = $self->{dbh}->quote($systemID);
- my $quotedAttrName = $self->{dbh}->quote($attrName);
-
- my $sql = <<" End-of-Here";
- SELECT id FROM system_attr
- WHERE system_id = $quotedSystemID
- AND name = $quotedAttrName
- End-of-Here
- my $id = $self->_doSelect($sql, 'id');
- if ($id) {
- return $self->_doUpdate(
- 'system_attr', [ $id ], [ { value => $attrValue } ]
+ my $self = shift;
+ my $systemID = shift;
+ my $attrs = shift;
+
+ # we take the simple path and remove all attributes ...
+ return if !$self->_doDelete('system_attr', [ $systemID ], 'system_id');
+
+ # ... and (re-)insert the given ones
+ foreach my $key (keys %$attrs) {
+ return if !$self->_doInsert(
+ 'system_attr', [ {
+ system_id => $systemID,
+ name => $key,
+ value => $attrs->{$key},
+ } ]
);
}
- return $self->_doInsert(
- 'system_attr', [ {
- system_id => $systemID,
- name => $attrName,
- value => $attrValue,
- } ]
- );
+ return 1;
}
sub setClientIDsOfSystem
@@ -742,7 +823,26 @@ sub addClient
my $self = shift;
my $valRows = shift;
- return $self->_doInsert('client', $valRows);
+ # separate the attribute hashes ...
+ my @attrValRows
+ = map {
+ my $attrs = $_->{attrs};
+ delete $_->{attrs};
+ $attrs;
+ }
+ @$valRows;
+
+ # ... store the clients to get the IDs ...
+ my @clientIDs = $self->_doInsert('client', $valRows);
+
+ # ... finally store the individual attribute sets
+ foreach my $id (@clientIDs) {
+ my $attrs = shift @attrValRows;
+ next if !defined $attrs;
+ return if !$self->setClientAttrs($id, $attrs);
+ }
+
+ return @clientIDs;
}
sub removeClient
@@ -759,9 +859,46 @@ sub changeClient
my $clientIDs = shift;
my $valRows = shift;
+ # separate the attribute hashes and store them individually
+ my @attrValRows
+ = map {
+ my $attrs = $_->{attrs};
+ delete $_->{attrs};
+ $attrs;
+ }
+ @$valRows;
+ foreach my $id (@$clientIDs) {
+ my $attrs = shift @attrValRows;
+ next if !defined $attrs;
+ return if !$self->setClientAttrs($id, $attrs);
+ }
+
+ # finally update all systems in one go
return $self->_doUpdate('client', $clientIDs, $valRows);
}
+sub setClientAttrs
+{
+ my $self = shift;
+ my $clientID = shift;
+ my $attrs = shift;
+
+ # we take the simple path and remove all attributes ...
+ return if !$self->_doDelete('client_attr', [ $clientID ], 'client_id');
+
+ # ... and (re-)insert the given ones
+ foreach my $key (keys %$attrs) {
+ return if !$self->_doInsert(
+ 'client_attr', [ {
+ client_id => $clientID,
+ name => $key,
+ value => $attrs->{$key},
+ } ]
+ );
+ }
+ return 1;
+}
+
sub setSystemIDsOfClient
{
my $self = shift;
@@ -793,7 +930,26 @@ sub addGroup
my $self = shift;
my $valRows = shift;
- return $self->_doInsert('groups', $valRows);
+ # separate the attribute hashes ...
+ my @attrValRows
+ = map {
+ my $attrs = $_->{attrs};
+ delete $_->{attrs};
+ $attrs;
+ }
+ @$valRows;
+
+ # ... store the groups to get the IDs ...
+ my @groupIDs = $self->_doInsert('groups', $valRows);
+
+ # ... finally store the individual attribute sets
+ foreach my $id (@groupIDs) {
+ my $attrs = shift @attrValRows;
+ next if !defined $attrs;
+ return if !$self->setGroupAttrs($id, $attrs);
+ }
+
+ return @groupIDs;
}
sub removeGroup
@@ -810,9 +966,46 @@ sub changeGroup
my $groupIDs = shift;
my $valRows = shift;
+ # separate the attribute hashes and store them individually
+ my @attrValRows
+ = map {
+ my $attrs = $_->{attrs};
+ delete $_->{attrs};
+ $attrs;
+ }
+ @$valRows;
+ foreach my $id (@$groupIDs) {
+ my $attrs = shift @attrValRows;
+ next if !defined $attrs;
+ return if !$self->setGroupAttrs($id, $attrs);
+ }
+
+ # finally update all groups in one go
return $self->_doUpdate('groups', $groupIDs, $valRows);
}
+sub setGroupAttrs
+{
+ my $self = shift;
+ my $groupID = shift;
+ my $attrs = shift;
+
+ # we take the simple path and remove all attributes ...
+ return if !$self->_doDelete('group_attr', [ $groupID ], 'group_id');
+
+ # ... and (re-)insert the given ones
+ foreach my $key (keys %$attrs) {
+ return if !$self->_doInsert(
+ 'group_attr', [ {
+ group_id => $groupID,
+ name => $key,
+ value => $attrs->{$key},
+ } ]
+ );
+ }
+ return 1;
+}
+
sub setClientIDsOfGroup
{
my $self = shift;
@@ -896,6 +1089,16 @@ sub schemaFetchDBVersion
return $row->{schema_version};
}
+sub schemaUpgradeDBFrom
+{
+ my $self = shift;
+ my $currVersion = shift;
+
+ $self->_upgradeDBTo0_2() if $currVersion < 0.2;
+
+ return 1;
+}
+
sub schemaSetDBVersion
{
my $self = shift;
@@ -1114,6 +1317,218 @@ sub schemaChangeColumns
return;
}
+sub _upgradeDBTo0_2
+{
+ my $self = shift;
+
+ # move attributes into separate tables ...
+ #
+ # ... system attributes ...
+ $self->schemaAddTable(
+ 'system_attr',
+ [
+ 'id:pk',
+ 'system_id:fk',
+ 'name:s.128',
+ 'value:s.255',
+ ]
+ );
+ foreach my $system ($self->fetchSystemByFilter()) {
+ my %attrs;
+ foreach my $key (keys %$system) {
+ next if substr($key, 0, 5) ne 'attr_';
+ my $attrValue = $system->{$key} || '';
+ next if $system->{id} > 0 && !length($attrValue);
+ my $newAttrName = substr($key, 5);
+ $attrs{$newAttrName} = $attrValue;
+ }
+ $self->setSystemAttrs($system->{id}, \%attrs);
+ }
+ $self->schemaDropColumns(
+ 'system',
+ [
+ 'attr_automnt_dir',
+ 'attr_automnt_src',
+ 'attr_country',
+ 'attr_dm_allow_shutdown',
+ 'attr_hw_graphic',
+ 'attr_hw_monitor',
+ 'attr_hw_mouse',
+ 'attr_late_dm',
+ 'attr_netbios_workgroup',
+ 'attr_nis_domain',
+ 'attr_nis_servers',
+ 'attr_ramfs_fsmods',
+ 'attr_ramfs_miscmods',
+ 'attr_ramfs_nicmods',
+ 'attr_ramfs_screen',
+ 'attr_sane_scanner',
+ 'attr_scratch',
+ 'attr_slxgrp',
+ 'attr_start_alsasound',
+ 'attr_start_atd',
+ 'attr_start_cron',
+ 'attr_start_dreshal',
+ 'attr_start_ntp',
+ 'attr_start_nfsv4',
+ 'attr_start_printer',
+ 'attr_start_samba',
+ 'attr_start_snmp',
+ 'attr_start_sshd',
+ 'attr_start_syslog',
+ 'attr_start_x',
+ 'attr_start_xdmcp',
+ 'attr_tex_enable',
+ 'attr_timezone',
+ 'attr_tvout',
+ 'attr_vmware',
+ ],
+ [
+ 'id:pk',
+ 'export_id:fk',
+ 'name:s.64',
+ 'label:s.64',
+ 'kernel:s.128',
+ 'kernel_params:s.512',
+ 'hidden:b',
+ 'comment:s.1024',
+ ]
+ );
+ #
+ # ... client attributes ...
+ $self->schemaAddTable(
+ 'client_attr',
+ [
+ 'id:pk',
+ 'client_id:fk',
+ 'name:s.128',
+ 'value:s.255',
+ ]
+ );
+ foreach my $client ($self->fetchClientByFilter()) {
+ my %attrs;
+ foreach my $key (keys %$client) {
+ next if substr($key, 0, 5) ne 'attr_';
+ my $attrValue = $client->{$key} || '';
+ next if !length($attrValue);
+ my $newAttrName = substr($key, 5);
+ $attrs{$newAttrName} = $attrValue;
+ }
+ $self->setClientAttrs($client->{id}, \%attrs);
+ }
+ $self->schemaDropColumns(
+ 'client',
+ [
+ 'attr_automnt_dir',
+ 'attr_automnt_src',
+ 'attr_country',
+ 'attr_dm_allow_shutdown',
+ 'attr_hw_graphic',
+ 'attr_hw_monitor',
+ 'attr_hw_mouse',
+ 'attr_late_dm',
+ 'attr_netbios_workgroup',
+ 'attr_nis_domain',
+ 'attr_nis_servers',
+ 'attr_sane_scanner',
+ 'attr_scratch',
+ 'attr_slxgrp',
+ 'attr_start_alsasound',
+ 'attr_start_atd',
+ 'attr_start_cron',
+ 'attr_start_dreshal',
+ 'attr_start_ntp',
+ 'attr_start_nfsv4',
+ 'attr_start_printer',
+ 'attr_start_samba',
+ 'attr_start_snmp',
+ 'attr_start_sshd',
+ 'attr_start_syslog',
+ 'attr_start_x',
+ 'attr_start_xdmcp',
+ 'attr_tex_enable',
+ 'attr_timezone',
+ 'attr_tvout',
+ 'attr_vmware',
+ ],
+ [
+ 'id:pk',
+ 'name:s.128',
+ 'mac:s.20',
+ 'boot_type:s.20',
+ 'unbootable:b',
+ 'kernel_params:s.128',
+ 'comment:s.1024',
+ ]
+ );
+ #
+ # ... group attributes ...
+ $self->schemaAddTable(
+ 'group_attr',
+ [
+ 'id:pk',
+ 'group_id:fk',
+ 'name:s.128',
+ 'value:s.255',
+ ]
+ );
+ foreach my $group ($self->fetchGroupByFilter()) {
+ my %attrs;
+ foreach my $key (keys %$group) {
+ next if substr($key, 0, 5) ne 'attr_';
+ my $attrValue = $group->{$key} || '';
+ next if !length($attrValue);
+ my $newAttrName = substr($key, 5);
+ $attrs{$newAttrName} = $attrValue;
+ }
+ $self->setGroupAttrs($group->{id}, \%attrs);
+ }
+ $self->schemaDropColumns(
+ 'groups',
+ [
+ 'attr_automnt_dir',
+ 'attr_automnt_src',
+ 'attr_country',
+ 'attr_dm_allow_shutdown',
+ 'attr_hw_graphic',
+ 'attr_hw_monitor',
+ 'attr_hw_mouse',
+ 'attr_late_dm',
+ 'attr_netbios_workgroup',
+ 'attr_nis_domain',
+ 'attr_nis_servers',
+ 'attr_sane_scanner',
+ 'attr_scratch',
+ 'attr_slxgrp',
+ 'attr_start_alsasound',
+ 'attr_start_atd',
+ 'attr_start_cron',
+ 'attr_start_dreshal',
+ 'attr_start_ntp',
+ 'attr_start_nfsv4',
+ 'attr_start_printer',
+ 'attr_start_samba',
+ 'attr_start_snmp',
+ 'attr_start_sshd',
+ 'attr_start_syslog',
+ 'attr_start_x',
+ 'attr_start_xdmcp',
+ 'attr_tex_enable',
+ 'attr_timezone',
+ 'attr_tvout',
+ 'attr_vmware',
+ ],
+ [
+ 'id:pk',
+ 'name:s.128',
+ 'priority:i',
+ 'comment:s.1024',
+ ]
+ );
+
+ return 1;
+}
+
1;
=head1 NAME