Accéder au contenu.
Menu Sympa

fr - Re: [sympa-fr] Update from 6.1.9 to sympa 6.1.11

Objet : Pour les administrateurs de serveurs de listes utilisant le logiciel Sympa

Archives de la liste

Chronologique Discussions  
  • From: David Verdin <adresse@cachée>
  • To: adresse@cachée
  • Subject: Re: [sympa-fr] Update from 6.1.9 to sympa 6.1.11
  • Date: Mon, 14 May 2012 10:39:38 +0200

Merci de cette précision. Je vais corriger la requête.

Pourrais-tu m'expliquer un ou deux détails ?
  • La succession des deux requêtes (création du type ENUM, puis création de la table avec le nouveau type) ne marchera donc qu'avec PostgreSQL 8.3 ?
  • La version 8.3 est-elle la plus répandue ? Si elle est très utilisée, nous pourrons préciser dans les notes de version qu'elle est désormais la version minimale pour Sympa.
  • Sans ce type enum, y a-t-il un moyen, avec PostgreSQL de contrôler les valeurs acceptées par un champs ? Si c'est le cas et que c'est un mécanisme plus générique (accepté par toutes les versions) on aurait sans doute intérêt à utiliser celui-là

Notre problème principal vis à vis des bases de données, jusqu'ici, était de maintenir cinq versions des scripts de création de la base.
Par ailleurs, étant donné que ce sont des scripts de création et non de mise à jours, un changement de type de champ ou de clé est particulièrement pénible pour les utilisateurs.
Or, notre expertise se limite à MySQL. Pour toutes les autres SGBD, nous nous appuyons sur les contributions de la communauté. Il n'y a donc de mise à jour automatique que pour MySQL (et pour SQLite grâce à un contributeur particulièrement actif).

Pour résoudre ce problème, nous avons, dans la version 6.2, factorisé le code de mise à jour de la base en s'appuyant sur des modules spécifiques à chaque SGBD, nommés "DBManipulator<nom du SGBD>.pm. En gros, ces modules contiennent tous des fonctions, ayant le même nom d'un module à l'autre (add_table(), add_field(), set_primary_key(), etc.) que l'on appelle à partir de Sympa. Ce sont ces modules qui contiennent les requêtes spécifiques à chaque SGBD.
De cette manière, on découple la partie spécifique à Sympa (quel champ créer, quelle clé positionner) de la connaissance d'un SGBD spécifique. De cette manière, nous comptons trouver plus facilement de l'aide pour le support des opérations plus exotiques de bases de données (en gros tout ce qui concerne le DDL).

À titre d'exemple, je joins le module de PostgreSQL. Toute ce que les contributeurs ont à faire, c'est donner les requêtes qui permettent de faire l'opération prévue par chaque méthode. On espère que cela permette à court terme une mise à jour automatique pour chaque SGBD supporté, et l'ajout facile de nouveaux SGBD si nécessaire.
On va déjà devoir modifier les fonctions de création et de mise à jour de champ pour PG et le type enum.

Bonne journée !

David

Le 14/05/12 08:17, Alexis Michon a écrit :
adresse@cachée"> Merci !

Deux petites précisions :
- Le type enum est supporté à partir de la version 8.3.
- Avant la création de la table il faut créer le type :
CREATE TYPE type_list_status AS ENUM ('open', 'closed', 'pending', 'error_config', 'family_closed');
CREATE TABLE list_table (
..
	status_list   type_list_status
...

Alexis
Le 11/05/12 15:52, David Verdin a écrit :
adresse@cachée"> Note : une fois la table créée, il faut ré-exécuter l'upgrade.
Pour cela, éditer le fichier <répertoire d'installation de Sympa>/etc/data_structure.version et remplacer 6.1.10 par 6.1.9, puis relancer la commande sympa.pl --upgrade

cordialement,

David Verdin

Le 11/05/12 15:23, David Verdin a écrit :
adresse@cachée"> Bonjour,

La table "list_table" n'existe pas dans la base. En effet, Sympa ne met pas à jour automatiquement les bases de données Postgres.
il faut la créer à l'aide la requête suivante :

CREATE TABLE list_table (
	creation_email_list	varchar(100),

	creation_epoch_list	timestamptz,

	editors_list		varchar(100),

	name_list		varchar(100) NOT NULL,

	owners_list		varchar(100),

	path_list		varchar(100),

	robot_list		varchar(100) NOT NULL,

	status_list		enum('open', 'closed', 'pending', 'error_config', 'family_closed'),

	subject_list		varchar(100),

	topics_list		varchar(100),

	web_archive_list	int2,

	constraint ind_list primary key (name_list,robot_list)
);
Je constate que la requête de création de la table n'a pas été mise à jour dans la version distribuée. Je vais corriger le package pour que ces requêtes soient à jour.

Voici qui nous fera apprécier encore plus la version 6.2 dans laquelle la mise à jour est automatique pour les bd postgres.

Cordialement,

David Verdin

Le 11/05/12 14:49, Alexis Michon a écrit :
adresse@cachée">
Bonjour,

Lors de la mise à jour de sympa (/home/sympa/bin/sympa.pl --upgrade)
depuis la version 6.1.9 à la version 6.1.11, j'ai obtenu le message
d'erreur suivant :
...
notice Upgrade::upgrade() Caching all lists config subset to database
DBD::Pg::st execute failed: ERROR:  relation "list_table" does not exist
err List::_flush_list_db() Unable to execute SQL statement 'TRUNCATE
TABLE list_table' : ERROR:  relation "list_table" does not exist

DBD::Pg::db do failed: ERROR:  relation "list_table" does not exist
DBD::Pg::db do failed: ERROR:  relation "list_table" does not exist
err List::_update_list_db() Unable to execute SQL statement "UPDATE
list_table SET status_list = 'pending', name_list = 'test', robot_list =
'listes.ibcp.fr', subject_list = 'test', web_archive_list = 1,
topics_list = '', owners_list = 'adresse@cachée', editors_list =
'' WHERE robot_list = 'listes.ibcp.fr' AND name_list = 'test'" : ERROR: 
relation "list_table" does not exist
...

Une idée de la cause du dysfonctionnement ?

Alexis


-- 
Alexis MICHON                  
CNRS BMSSI, 7 passage du vercors, 69007 LYON, France
Mail : adresse@cachée  Tel : 04.72.72.26.03
Equipe BioInformatique : Structure et Interactions (BISI) 
-> http://www.ibcp.fr/bmssi/-Bioinformatique-structures-et-
CNRS BMSSI - UMR 5086 - http://www.ibcp.fr/bmssi/
Empreinte : C9:45:2D:7C:79:7F:0B:79:CA:C8:0B:68:41:A2:8C:EE:EA:72:82:34
# DBManipulatorPostgres.pm - This module contains the code specific to using
a Postgres server.
#<!-- RCS Identication ; $Revision: 7016 $ -->
#
# Sympa - SYsteme de Multi-Postage Automatique
# Copyright (c) 1997, 1998, 1999, 2000, 2001 Comite Reseau des Universites
# Copyright (c) 1997,1998, 1999 Institut Pasteur & Christophe Wolfhugel
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Softwarec
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

package DBManipulatorPostgres;

use strict;
use Data::Dumper;

use Carp;
use Log;

use DBManipulatorDefault;

our @ISA = qw(DBManipulatorDefault);

#######################################################
####### Beginning the RDBMS-specific code. ############
#######################################################

our %date_format = (
'read' => {
'Pg' => 'date_part(\'epoch\',%s)',
},
'write' => {
'Pg' => '\'epoch\'::timestamp with time zone + \'%d
sec\'',
}
);

# Builds the string to be used by the DBI to connect to the database.
#
# IN: Nothing
#
# OUT: Nothing
sub build_connect_string{
my $self = shift;
&Log::do_log('debug','Building connect string');
$self->{'connect_string'} =
"DBI:Pg:dbname=$self->{'db_name'};host=$self->{'db_host'}";
}

## Returns an SQL clause to be inserted in a query.
## This clause will compute a substring of max length
## $param->{'substring_length'} starting from the first character equal
## to $param->{'separator'} found in the value of field
$param->{'source_field'}.
sub get_substring_clause {
my $self = shift;
my $param = shift;
&Log::do_log('debug2','Building a substring clause');
return "SUBSTRING(".$param->{'source_field'}." FROM
position('".$param->{'separator'}."' IN ".$param->{'source_field'}.") FOR
".$param->{'substring_length'}.")";
}

## Returns an SQL clause to be inserted in a query.
## This clause will limit the number of records returned by the query to
## $param->{'rows_count'}. If $param->{'offset'} is provided, an offset of
## $param->{'offset'} rows is done from the first record before selecting
## the rows to return.
sub get_limit_clause {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Building limit clause');
if ($param->{'offset'}) {
return "LIMIT ".$param->{'rows_count'}." OFFSET ".$param->{'offset'};
}else{
return "LIMIT ".$param->{'rows_count'};
}
}

# Returns a character string corresponding to the expression to use in a query
# involving a date.
# IN: A ref to hash containing the following keys:
# * 'mode'
# authorized values:
# - 'write': the sub returns the expression to use in 'INSERT'
or 'UPDATE' queries
# - 'read': the sub returns the expression to use in 'SELECT'
queries
# * 'target': the name of the field or the value to be used in the query
#
# OUT: the formatted date or undef if the date format mode is unknonw.
sub get_formatted_date {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Building SQL date formatting');
if (lc($param->{'mode'}) eq 'read') {
return sprintf 'date_part(\'epoch\',%s)',$param->{'target'};
}elsif(lc($param->{'mode'}) eq 'write') {
return sprintf '\'epoch\'::timestamp with time zone + \'%d
sec\'',$param->{'target'};
}else {
&Log::do_log('err',"Unknown date format mode %s", $param->{'mode'});
return undef;
}
}

# Checks whether a field is an autoincrement field or not.
# IN: A ref to hash containing the following keys:
# * 'field' : the name of the field to test
# * 'table' : the name of the table to add
#
# OUT: Returns true if the field is an autoincrement field, false otherwise
sub is_autoinc {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Checking whether field %s.%s is an
autoincrement',$param->{'table'},$param->{'field'});
my $seqname = $param->{'table'}.'_'.$param->{'field'}.'_seq';
my $sth;
unless ($sth = $self->do_query("SELECT relname FROM pg_class WHERE
relname = '%s' AND relkind = 'S' AND relnamespace IN ( SELECT oid FROM
pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname !=
'information_schema' )",$seqname)) {
&Log::do_log('err','Unable to gather autoincrement field named %s for
table %s',$param->{'field'},$param->{'table'});
return undef;
}
my $field = $sth->fetchrow();
return ($field eq $seqname);
}

# Defines the field as an autoincrement field
# IN: A ref to hash containing the following keys:
# * 'field' : the name of the field to set
# * 'table' : the name of the table to add
#
# OUT: 1 if the autoincrement could be set, undef otherwise.
sub set_autoinc {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Setting field %s.%s as an auto
increment',$param->{'table'},$param->{'field'});
my $seqname = $param->{'table'}.'_'.$param->{'field'}.'_seq';
unless ($self->do_query("CREATE SEQUENCE %s",$seqname)) {
&Log::do_log('err','Unable to create sequence %s',$seqname);
return undef;
}
unless ($self->do_query("ALTER TABLE %s ALTER COLUMN %s TYPE
BIGINT",$param->{'table'},$param->{'field'})) {
&Log::do_log('err','Unable to set type of field %s in table %s as
bigint',$param->{'field'},$param->{'table'});
return undef;
}
unless ($self->do_query("ALTER TABLE %s ALTER COLUMN %s SET DEFAULT
NEXTVAL('%s')",$param->{'table'},$param->{'field'},$seqname)) {
&Log::do_log('err','Unable to set default value of field %s in table
%s as next value of sequence table
%',$param->{'field'},$param->{'table'},$seqname);
return undef;
}
unless ($self->do_query("UPDATE %s SET %s =
NEXTVAL('%s')",$param->{'table'},$param->{'field'},$seqname)) {
&Log::do_log('err','Unable to set sequence %s as value for field %s,
table %s',$seqname,$param->{'field'},$param->{'table'});
return undef;
}
return 1;
}

# Returns the list of the tables in the database.
# Returns undef if something goes wrong.
#
# OUT: a ref to an array containing the list of the tables names in the
database, undef if something went wrong
sub get_tables {
my $self = shift;
&Log::do_log('debug','Getting the list of tables in database
%s',$self->{'db_name'});
my @raw_tables;
unless (@raw_tables =
$self->{'dbh'}->tables(undef,'public',undef,'TABLE',{pg_noprefix => 1} )) {
&Log::do_log('err','Unable to retrieve the list of tables from
database %s',$self->{'db_name'});
return undef;
}
return \@raw_tables;
}

# Adds a table to the database
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table to add
#
# OUT: A character string report of the operation done or undef if something
went wrong.
sub add_table {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Adding table %s',$param->{'table'});
unless ($self->do_query("CREATE TABLE %s (temporary
INT)",$param->{'table'})) {
&Log::do_log('err', 'Could not create table %s in database %s',
$param->{'table'}, $self->{'db_name'});
return undef;
}
return sprintf "Table %s created in database %s", $param->{'table'},
$self->{'db_name'};
}

# Returns a ref to an hash containing the description of the fields in a
table from the database.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table whose fields are requested.
#
# OUT: A hash in which:
# * the keys are the field names
# * the values are the field type
# Returns undef if something went wrong.
#
sub get_fields {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Getting the list of fields in table %s, database
%s',$param->{'table'}, $self->{'db_name'});
my $sth;
my %result;
unless ($sth = $self->do_query("SELECT a.attname AS field, t.typname AS
type, a.atttypmod AS length FROM pg_class c, pg_attribute a, pg_type t WHERE
a.attnum > 0 and a.attrelid = c.oid and c.relname = '%s' and a.atttypid =
t.oid order by a.attnum",$param->{'table'})) {
&Log::do_log('err', 'Could not get the list of fields from table %s
in database %s', $param->{'table'}, $self->{'db_name'});
return undef;
}
while (my $ref = $sth->fetchrow_hashref('NAME_lc')) {
my $length = $ref->{'length'} - 4; # What a dirty method ! We give a
Sympa tee shirt to anyone that suggest a clean solution ;-)
if ( $ref->{'type'} eq 'varchar') {
$result{$ref->{'field'}} = $ref->{'type'}.'('.$length.')';
}else{
$result{$ref->{'field'}} = $ref->{'type'};
}
}
return \%result;
}

# Changes the type of a field in a table from the database.
# IN: A ref to hash containing the following keys:
# * 'field' : the name of the field to update
# * 'table' : the name of the table whose fields will be updated.
# * 'type' : the type of the field to add
# * 'notnull' : specifies that the field must not be null
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub update_field {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Updating field %s in table %s (%s,
%s)',$param->{'field'},$param->{'table'},$param->{'type'},$param->{'notnull'});
my $options;
if ($param->{'notnull'}) {
$options .= ' NOT NULL ';
}
my $report = sprintf("ALTER TABLE %s ALTER COLUMN %s TYPE %s
%s",$param->{'table'},$param->{'field'},$param->{'type'},$options);
&Log::do_log('notice', "ALTER TABLE %s ALTER COLUMN %s TYPE %s
%s",$param->{'table'},$param->{'field'},$param->{'type'},$options);
unless ($self->do_query("ALTER TABLE %s ALTER COLUMN %s TYPE %s
%s",$param->{'table'},$param->{'field'},$param->{'type'},$options)) {
&Log::do_log('err', 'Could not change field \'%s\' in
table\'%s\'.',$param->{'field'}, $param->{'table'});
return undef;
}
$report .= sprintf('\nField %s in table %s, structure updated',
$param->{'field'}, $param->{'table'});
&Log::do_log('info', 'Field %s in table %s, structure updated',
$param->{'field'}, $param->{'table'});
return $report;
}

# Adds a field in a table from the database.
# IN: A ref to hash containing the following keys:
# * 'field' : the name of the field to add
# * 'table' : the name of the table where the field will be added.
# * 'type' : the type of the field to add
# * 'notnull' : specifies that the field must not be null
# * 'autoinc' : specifies that the field must be autoincremental
# * 'primary' : specifies that the field is a key
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub add_field {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Adding field %s in table %s (%s, %s, %s,
%s)',$param->{'field'},$param->{'table'},$param->{'type'},$param->{'notnull'},$param->{'autoinc'},$param->{'primary'});
my $options;
# To prevent "Cannot add a NOT NULL column with default value NULL" errors
if ($param->{'notnull'}) {
$options .= 'NOT NULL ';
}
if ( $param->{'primary'}) {
$options .= ' PRIMARY KEY ';
}
unless ($self->do_query("ALTER TABLE %s ADD %s %s
%s",$param->{'table'},$param->{'field'},$param->{'type'},$options)) {
&Log::do_log('err', 'Could not add field %s to table %s in database
%s', $param->{'field'}, $param->{'table'}, $self->{'db_name'});
return undef;
}

my $report = sprintf('Field %s added to table %s (options : %s)',
$param->{'field'}, $param->{'table'}, $options);
&Log::do_log('info', 'Field %s added to table %s (options : %s)',
$param->{'field'}, $param->{'table'}, $options);

return $report;
}

# Deletes a field from a table in the database.
# IN: A ref to hash containing the following keys:
# * 'field' : the name of the field to delete
# * 'table' : the name of the table where the field will be deleted.
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub delete_field {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Deleting field %s from table
%s',$param->{'field'},$param->{'table'});

unless ($self->do_query("ALTER TABLE %s DROP COLUMN
%s",$param->{'table'},$param->{'field'})) {
&Log::do_log('err', 'Could not delete field %s from table %s in
database %s', $param->{'field'}, $param->{'table'}, $self->{'db_name'});
return undef;
}

my $report = sprintf('Field %s removed from table %s', $param->{'field'},
$param->{'table'});
&Log::do_log('info', 'Field %s removed from table %s', $param->{'field'},
$param->{'table'});

return $report;
}

# Returns the list fields being part of a table's primary key.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table for which the primary keys are
requested.
#
# OUT: A ref to a hash in which each key is the name of a primary key or
undef if something went wrong.
#
sub get_primary_key {
my $self = shift;
my $param = shift;

&Log::do_log('debug','Getting primary key for table
%s',$param->{'table'});
my %found_keys;
my $sth;
unless ($sth = $self->do_query("SELECT pg_attribute.attname AS field FROM
pg_index, pg_class, pg_attribute WHERE pg_class.oid ='%s'::regclass AND
indrelid = pg_class.oid AND pg_attribute.attrelid = pg_class.oid AND
pg_attribute.attnum = any(pg_index.indkey) AND
indisprimary",$param->{'table'})) {
&Log::do_log('err', 'Could not get the primary key from table %s in
database %s', $param->{'table'}, $self->{'db_name'});
return undef;
}

while (my $ref = $sth->fetchrow_hashref('NAME_lc')) {
$found_keys{$ref->{'field'}} = 1;
}
return \%found_keys;
}


# Drops the primary key of a table.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table for which the primary keys must be
dropped.
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub unset_primary_key {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Removing primary key from table
%s',$param->{'table'});

my $sth;
unless ($sth = $self->do_query("ALTER TABLE %s DROP PRIMARY
KEY",$param->{'table'})) {
&Log::do_log('err', 'Could not drop primary key from table %s in
database %s', $param->{'table'}, $self->{'db_name'});
return undef;
}
my $report = "Table $param->{'table'}, PRIMARY KEY dropped";
&Log::do_log('info', 'Table %s, PRIMARY KEY dropped', $param->{'table'});

return $report;
}

# Sets the primary key of a table.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table for which the primary keys must be
defined.
# * 'fields' : a ref to an array containing the names of the fields
used in the key.
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub set_primary_key {
my $self = shift;
my $param = shift;

my $sth;
my $fields = join ',',@{$param->{'fields'}};
&Log::do_log('debug','Setting primary key for table %s
(%s)',$param->{'table'},$fields);
unless ($sth = $self->do_query("ALTER TABLE %s ADD PRIMARY KEY
(%s)",$param->{'table'}, $fields)) {
&Log::do_log('err', 'Could not set fields %s as primary key for table
%s in database %s', $fields, $param->{'table'}, $self->{'db_name'});
return undef;
}
my $report = "Table $param->{'table'}, PRIMARY KEY set on $fields";
&Log::do_log('info', 'Table %s, PRIMARY KEY set on %s',
$param->{'table'},$fields);
return $report;
}

# Returns a ref to a hash in which each key is the name of an index.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table for which the indexes are requested.
#
# OUT: A ref to a hash in which each key is the name of an index. These key
point to
# a second level hash in which each key is the name of the field
indexed.
# Returns undef if something went wrong.
#
sub get_indexes {
my $self = shift;
my $param = shift;

&Log::do_log('debug','Getting the indexes defined on table
%s',$param->{'table'});
my %found_indexes;
my $sth;
unless ($sth = $self->do_query("SELECT c.oid FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname
~ \'^(%s)$\' AND pg_catalog.pg_table_is_visible(c.oid)",$param->{'table'})) {
&Log::do_log('err', 'Could not get the oid for table %s in database
%s', $param->{'table'}, $self->{'db_name'});
return undef;
}
my $ref = $sth->fetchrow_hashref('NAME_lc');

unless ($sth = $self->do_query("SELECT c2.relname,
pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS description FROM
pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i WHERE
c.oid = \'%s\' AND c.oid = i.indrelid AND i.indexrelid = c2.oid AND NOT
i.indisprimary ORDER BY i.indisprimary DESC, i.indisunique DESC,
c2.relname",$ref->{'oid'})) {
&Log::do_log('err', 'Could not get the list of indexes from table %s
in database %s', $param->{'table'}, $self->{'db_name'});
return undef;
}

while (my $ref = $sth->fetchrow_hashref('NAME_lc')) {
$ref->{'description'} =~ s/CREATE INDEX .* ON .* USING .*
\((.*)\)$/\1/i;
$ref->{'description'} =~ s/\s//i;
my @index_members = split ',',$ref->{'description'};
foreach my $member (@index_members) {
$found_indexes{$ref->{'relname'}}{$member} = 1;
}
}
open TMP, ">>/tmp/found_indexes"; print TMP &Dumper(\%found_indexes);
close TMP;
return \%found_indexes;
}

# Drops an index of a table.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table for which the index must be dropped.
# * 'index' : the name of the index to be dropped.
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub unset_index {
my $self = shift;
my $param = shift;
&Log::do_log('debug','Removing index %s from table
%s',$param->{'index'},$param->{'table'});

my $sth;
unless ($sth = $self->do_query("DROP INDEX %s",$param->{'index'})) {
&Log::do_log('err', 'Could not drop index %s from table %s in
database %s',$param->{'index'}, $param->{'table'}, $self->{'db_name'});
return undef;
}
my $report = "Table $param->{'table'}, index $param->{'index'} dropped";
&Log::do_log('info', 'Table %s, index %s dropped',
$param->{'table'},$param->{'index'});

return $report;
}

# Sets an index in a table.
# IN: A ref to hash containing the following keys:
# * 'table' : the name of the table for which the index must be defined.
# * 'fields' : a ref to an array containing the names of the fields
used in the index.
# * 'index_name' : the name of the index to be defined..
#
# OUT: A character string report of the operation done or undef if something
went wrong.
#
sub set_index {
my $self = shift;
my $param = shift;

my $sth;
my $fields = join ',',@{$param->{'fields'}};
&Log::do_log('debug', 'Setting index %s for table %s using fields %s',
$param->{'index_name'},$param->{'table'}, $fields);
unless ($sth = $self->do_query("CREATE INDEX %s ON %s (%s)",
$param->{'index_name'},$param->{'table'}, $fields)) {
&Log::do_log('err', 'Could not add index %s using field %s for table
%s in database %s', $fields, $param->{'table'}, $self->{'db_name'});
return undef;
}
my $report = "Table $param->{'table'}, index %s set using $fields";
&Log::do_log('info', 'Table %s, index %s set using fields
%s',$param->{'table'}, $param->{'index_name'}, $fields);
return $report;
}

return 1;



Archives gérées par MHonArc 2.6.19+.

Haut de le page