diff --git a/src/lib/Sympa/Database.pm b/src/lib/Sympa/Database.pm index 07028ebf2..0ee2558db 100644 --- a/src/lib/Sympa/Database.pm +++ b/src/lib/Sympa/Database.pm @@ -473,22 +473,16 @@ sub quote { ## This sub takes a single argument: the name of the field to be used in ## the query. ## -sub get_canonical_write_date { - my $self = shift; - my $field = shift; - return $self->get_formatted_date({'mode' => 'write', 'target' => $field}); -} +# Moved to Sympa::Upgrade::_get_canonical_write_date(). +#sub get_canonical_write_date; ## Returns a character string corresponding to the expression to use in ## a write query (e.g. UPDATE or INSERT) for the value given as argument. ## This sub takes a single argument: the value of the date to be used in ## the query. ## -sub get_canonical_read_date { - my $self = shift; - my $value = shift; - return $self->get_formatted_date({'mode' => 'read', 'target' => $value}); -} +# Moved to Sympa::Upgrade::_get_canonical_read_date(). +#sub get_canonical_read_date; # We require that user also matches (except SQLite). sub get_id { diff --git a/src/lib/Sympa/DatabaseDescription.pm b/src/lib/Sympa/DatabaseDescription.pm index d1ffdf3aa..e1fe0f046 100644 --- a/src/lib/Sympa/DatabaseDescription.pm +++ b/src/lib/Sympa/DatabaseDescription.pm @@ -100,17 +100,30 @@ my %full_db_struct = ( 'doc' => 'FIXME', 'order' => 10, }, - 'date_subscriber' => { - 'struct' => 'datetime', + #'date_subscriber' => { + # 'struct' => 'datetime', + # 'doc' => 'date of subscription', + # 'not_null' => 1, + # 'order' => 11, + #}, + 'date_epoch_subscriber' => { + 'struct' => 'int(11)', 'doc' => 'date of subscription', 'not_null' => 1, - 'order' => 11, - }, - 'update_subscriber' => { - 'struct' => 'datetime', + 'order' => 11.5, + }, + # Obsoleted as of 6.2.25b.2. Use update_epoch_subscriber. + #'update_subscriber' => { + # 'struct' => 'datetime', + # 'doc' => + # 'the latest date where subscription is confirmed by subscriber', + # 'order' => 12, + #}, + 'update_epoch_subscriber' => { + 'struct' => 'int(11)', 'doc' => - 'the latest date where subscription is confirmed by subscriber', - 'order' => 12, + 'the last time when subscription is confirmed by subscriber', + 'order' => 12.5, }, 'comment_subscriber' => { 'struct' => 'varchar(150)', @@ -883,16 +896,28 @@ my %full_db_struct = ( 'privilege level for this owner, value //normal// or //privileged//. The related privilege are listed in edit_list.conf. ', 'order' => 5, }, - 'date_admin' => { - 'struct' => 'datetime', + #'date_admin' => { + # 'struct' => 'datetime', + # 'doc' => 'date this user become a list admin', + # 'not_null' => 1, + # 'order' => 6, + #}, + 'date_epoch_admin' => { + 'struct' => 'int(11)', 'doc' => 'date this user become a list admin', 'not_null' => 1, - 'order' => 6, + 'order' => 6.5, }, - 'update_admin' => { - 'struct' => 'datetime', - 'doc' => 'last update timestamp', - 'order' => 7, + # Obsoleted as of 6.2.25b.2. Use update_epoch_admin. + #'update_admin' => { + # 'struct' => 'datetime', + # 'doc' => 'last update timestamp', + # 'order' => 7, + #}, + 'update_epoch_admin' => { + 'struct' => 'int(11)', + 'doc' => 'last update time', + 'order' => 7.5, }, 'reception_admin' => { 'struct' => 'varchar(20)', @@ -1257,6 +1282,8 @@ Text with length up to 2^32 - 4 o. =item datetime Timestamp. +B as of Sympa 6.2.25b.3. +Use C (Unix time) instead. =item mediumblob diff --git a/src/lib/Sympa/DatabaseDriver.pm b/src/lib/Sympa/DatabaseDriver.pm index 9d4b93bc9..79c0028e1 100644 --- a/src/lib/Sympa/DatabaseDriver.pm +++ b/src/lib/Sympa/DatabaseDriver.pm @@ -144,6 +144,8 @@ This method was deprecated. =item get_formatted_date ( { mode => $mode, target => $target } ) +B as of Sympa 6.2.25b.3. + I. Returns a character string corresponding to the expression to use in a query involving a date. diff --git a/src/lib/Sympa/DatabaseDriver/MySQL.pm b/src/lib/Sympa/DatabaseDriver/MySQL.pm index 9afdfa162..e04f81caf 100644 --- a/src/lib/Sympa/DatabaseDriver/MySQL.pm +++ b/src/lib/Sympa/DatabaseDriver/MySQL.pm @@ -84,19 +84,8 @@ sub get_substring_clause { # DEPRECATED. #sub get_limit_clause ( { rows_count => $rows, offset => $offset } ); -sub get_formatted_date { - my $self = shift; - my $param = shift; - $log->syslog('debug', 'Building SQL date formatting'); - if (lc($param->{'mode'}) eq 'read') { - return sprintf 'UNIX_TIMESTAMP(%s)', $param->{'target'}; - } elsif (lc($param->{'mode'}) eq 'write') { - return sprintf 'FROM_UNIXTIME(%d)', $param->{'target'}; - } else { - $log->syslog('err', "Unknown date format mode %s", $param->{'mode'}); - return undef; - } -} +# DEPRECATED. +#sub get_formatted_date; sub is_autoinc { my $self = shift; diff --git a/src/lib/Sympa/DatabaseDriver/ODBC.pm b/src/lib/Sympa/DatabaseDriver/ODBC.pm index 8655ba0f7..dee1064d4 100644 --- a/src/lib/Sympa/DatabaseDriver/ODBC.pm +++ b/src/lib/Sympa/DatabaseDriver/ODBC.pm @@ -38,12 +38,8 @@ sub build_connect_string { return 'DBI:ODBC:' . $self->{'db_name'}; } -sub get_formatted_date { - my $self = shift; - my $param = shift; - - die 'Not yet implemented: This is required by Sympa'; -} +# DEPRECATED. Never implemented. +#sub get_formatted_date; sub translate_type { my $self = shift; diff --git a/src/lib/Sympa/DatabaseDriver/Oracle.pm b/src/lib/Sympa/DatabaseDriver/Oracle.pm index a4fac7fe9..34dbb1c2f 100644 --- a/src/lib/Sympa/DatabaseDriver/Oracle.pm +++ b/src/lib/Sympa/DatabaseDriver/Oracle.pm @@ -88,25 +88,8 @@ sub get_substring_clause { #DEPRECATED. #sub get_limit_clause ( { rows_count => $rows, offset => $offset } ); -sub get_formatted_date { - my $self = shift; - my $param = shift; - $log->syslog('debug', 'Building SQL date formatting'); - if (lc($param->{'mode'}) eq 'read') { - return - sprintf - q{((to_number(to_char(%s,'J')) - to_number(to_char(to_date('01/01/1970','dd/mm/yyyy'), 'J'))) * 86400) +to_number(to_char(%s,'SSSSS'))}, - $param->{'target'}, $param->{'target'}; - } elsif (lc($param->{'mode'}) eq 'write') { - return - sprintf - q{to_date(to_char(floor(%s/86400) + to_number(to_char(to_date('01/01/1970','dd/mm/yyyy'), 'J'))) || ':' ||to_char(mod(%s,86400)), 'J:SSSSS')}, - $param->{'target'}, $param->{'target'}; - } else { - $log->syslog('err', "Unknown date format mode %s", $param->{'mode'}); - return undef; - } -} +#DEPRECATED. +#sub get_formatted_date; sub is_autoinc { my $self = shift; diff --git a/src/lib/Sympa/DatabaseDriver/PostgreSQL.pm b/src/lib/Sympa/DatabaseDriver/PostgreSQL.pm index 1dbcd2a01..08da62cbc 100644 --- a/src/lib/Sympa/DatabaseDriver/PostgreSQL.pm +++ b/src/lib/Sympa/DatabaseDriver/PostgreSQL.pm @@ -115,20 +115,8 @@ sub get_substring_clause { # DEPRECATED. #sub get_limit_clause ( { rows_count => $rows, offset => $offset } ); -sub get_formatted_date { - my $self = shift; - my $param = shift; - $log->syslog('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->syslog('err', "Unknown date format mode %s", $param->{'mode'}); - return undef; - } -} +# DEPRECATED. +#sub get_formatted_date; sub is_autoinc { my $self = shift; diff --git a/src/lib/Sympa/DatabaseDriver/SQLite.pm b/src/lib/Sympa/DatabaseDriver/SQLite.pm index 8d10248b3..9afde3787 100644 --- a/src/lib/Sympa/DatabaseDriver/SQLite.pm +++ b/src/lib/Sympa/DatabaseDriver/SQLite.pm @@ -79,17 +79,8 @@ sub get_substring_clause { # DEPRECATED. #sub get_limit_clause ( { rows_count => $rows, offset => $offset } ); -sub get_formatted_date { - my $self = shift; - my $param = shift; - $log->syslog('debug', 'Building SQL date formatting'); - if (lc($param->{'mode'}) eq 'read' or lc($param->{'mode'}) eq 'write') { - return $param->{'target'}; - } else { - $log->syslog('err', "Unknown date format mode %s", $param->{'mode'}); - return undef; - } -} +# DEPRECATED. +#sub get_formatted_date; sub is_autoinc { my $self = shift; diff --git a/src/lib/Sympa/DatabaseDriver/Sybase.pm b/src/lib/Sympa/DatabaseDriver/Sybase.pm index 4eb4511e4..bc50cf53b 100644 --- a/src/lib/Sympa/DatabaseDriver/Sybase.pm +++ b/src/lib/Sympa/DatabaseDriver/Sybase.pm @@ -81,21 +81,8 @@ sub get_substring_clause { # DEPRECATED. #sub get_limit_clause ( { rows_count => $rows, offset => $offset } ); -sub get_formatted_date { - my $self = shift; - my $param = shift; - $log->syslog('debug', 'Building SQL date formatting'); - if (lc($param->{'mode'}) eq 'read') { - return sprintf 'datediff(second, \'01/01/1970\',%s)', - $param->{'target'}; - } elsif (lc($param->{'mode'}) eq 'write') { - return sprintf 'dateadd(second,%s,\'01/01/1970\')', - $param->{'target'}; - } else { - $log->syslog('err', "Unknown date format mode %s", $param->{'mode'}); - return undef; - } -} +# DEPRECATED. +#sub get_formatted_date; sub is_autoinc { my $self = shift; diff --git a/src/lib/Sympa/List.pm b/src/lib/Sympa/List.pm index a94b0eb81..4d3588375 100644 --- a/src/lib/Sympa/List.pm +++ b/src/lib/Sympa/List.pm @@ -2477,7 +2477,8 @@ sub get_exclusion { # Mapping between var and field names. sub _map_list_member_cols { my %map_field = ( - update_date => 'update_subscriber', + date => 'date_epoch_subscriber', + update_date => 'update_epoch_subscriber', gecos => 'comment_subscriber', email => 'user_subscriber', id => 'include_sources_subscriber', @@ -2516,12 +2517,7 @@ sub _list_member_cols { my %map_field = _map_list_member_cols(); return join ', ', map { - my $col; - if ($_ eq 'date' or $_ eq 'update_date') { - $col = $sdm->get_canonical_read_date($map_field{$_}); - } else { - $col = $map_field{$_}; - } + my $col = $map_field{$_}; ($col eq $_) ? $col : sprintf('%s AS "%s"', $col, $_); } sort keys %map_field; } @@ -2898,22 +2894,19 @@ sub _get_admins { unless ( $sdm and $sth = $sdm->do_prepared_query( - sprintf( - q{SELECT user_admin AS email, comment_admin AS gecos, - role_admin AS "role", - reception_admin AS reception, - visibility_admin AS visibility, - %s AS "date", %s AS update_date, - info_admin AS info, profile_admin AS profile, - subscribed_admin AS subscribed, - included_admin AS included, - include_sources_admin AS id - FROM admin_table - WHERE list_admin = ? AND robot_admin = ? - ORDER BY user_admin}, - $sdm->get_canonical_read_date('date_admin'), - $sdm->get_canonical_read_date('update_admin'), - ), + q{SELECT user_admin AS email, comment_admin AS gecos, + role_admin AS "role", + reception_admin AS reception, + visibility_admin AS visibility, + date_epoch_admin AS "date", + update_epoch_admin AS update_date, + info_admin AS info, profile_admin AS profile, + subscribed_admin AS subscribed, + included_admin AS included, + include_sources_admin AS id + FROM admin_table + WHERE list_admin = ? AND robot_admin = ? + ORDER BY user_admin}, $self->{'name'}, $self->{'domain'} ) @@ -3432,11 +3425,7 @@ sub update_list_member { die sprintf 'Unknown database field %s', $field unless $map_field{$field}; - if ($field eq 'date' or $field eq 'update_date') { - push @set_list, - sprintf('%s = %s', - $map_field{$field}, $sdm->get_canonical_write_date($value)); - } elsif ($field eq 'custom_attribute') { + if ($field eq 'custom_attribute') { push @set_list, sprintf('%s = ?', $map_field{$field}); push @val_list, Sympa::Tools::Data::encode_custom_attribute($value); @@ -3567,8 +3556,8 @@ sub update_list_admin { my %map_field = ( reception => 'reception_admin', visibility => 'visibility_admin', - date => 'date_admin', - update_date => 'update_admin', + date => 'date_epoch_admin', + update_date => 'update_epoch_admin', gecos => 'comment_admin', password => 'password_user', email => 'user_admin', @@ -3620,18 +3609,14 @@ sub update_list_admin { } if ($map_table{$field} eq $table) { - if ($field eq 'date' || $field eq 'update_date') { - $value = $sdm->get_canonical_write_date($value); - } elsif ($value and $value eq 'NULL') { # get_null_value? + if ($value and $value eq 'NULL') { #FIXME:get_null_value? if ($Conf::Conf{'db_type'} eq 'mysql') { $value = '\N'; } + } elsif ($numeric_field{$map_field{$field}}) { + $value ||= 0; #FIXME:Can't have a null value } else { - if ($numeric_field{$map_field{$field}}) { - $value ||= 0; ## Can't have a null value - } else { - $value = $sdm->quote($value); - } + $value = $sdm->quote($value); } my $set = sprintf "%s=%s", $map_field{$field}, $value; @@ -3836,30 +3821,25 @@ sub add_list_member { unless ( $sdm and $sdm->do_prepared_query( - sprintf( - q{INSERT INTO subscriber_table - (user_subscriber, comment_subscriber, - list_subscriber, robot_subscriber, - date_subscriber, update_subscriber, - reception_subscriber, topics_subscriber, - visibility_subscriber, subscribed_subscriber, - included_subscriber, include_sources_subscriber, - custom_attribute_subscriber, - suspend_subscriber, - suspend_start_date_subscriber, - suspend_end_date_subscriber, - number_messages_subscriber) - VALUES (?, ?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, - ?, ?, ?, 0)}, - $sdm->get_canonical_write_date($new_user->{'date'}), - $sdm->get_canonical_write_date( - $new_user->{'update_date'} - ) - ), + q{INSERT INTO subscriber_table + (user_subscriber, comment_subscriber, + list_subscriber, robot_subscriber, + date_epoch_subscriber, update_epoch_subscriber, + reception_subscriber, topics_subscriber, + visibility_subscriber, subscribed_subscriber, + included_subscriber, include_sources_subscriber, + custom_attribute_subscriber, + suspend_subscriber, + suspend_start_date_subscriber, + suspend_end_date_subscriber, + number_messages_subscriber) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)}, $who, $new_user->{'gecos'}, $name, $self->{'domain'}, + $new_user->{'date'}, + $new_user->{'update_date'}, $new_user->{'reception'}, $new_user->{'topics'}, $new_user->{'visibility'}, @@ -3978,24 +3958,20 @@ sub add_list_admin { unless ( $sdm and $sdm->do_prepared_query( - sprintf( - q{INSERT INTO admin_table - (user_admin, comment_admin, list_admin, robot_admin, - date_admin, update_admin, reception_admin, - visibility_admin, - subscribed_admin, - included_admin, include_sources_admin, - role_admin, info_admin, profile_admin) - VALUES (?, ?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?)}, - $sdm->get_canonical_write_date($new_admin_user->{'date'}), - $sdm->get_canonical_write_date( - $new_admin_user->{'update_date'} - ) - ), + q{INSERT INTO admin_table + (user_admin, comment_admin, list_admin, robot_admin, + date_epoch_admin, update_epoch_admin, reception_admin, + visibility_admin, + subscribed_admin, + included_admin, include_sources_admin, + role_admin, info_admin, profile_admin) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}, $who, $new_admin_user->{'gecos'}, $name, $self->{'domain'}, + $new_admin_user->{'date'}, + $new_admin_user->{'update_date'}, $new_admin_user->{'reception'}, $new_admin_user->{'visibility'}, $new_admin_user->{'subscribed'}, diff --git a/src/lib/Sympa/Upgrade.pm b/src/lib/Sympa/Upgrade.pm index efbf80dbc..90b5361c4 100644 --- a/src/lib/Sympa/Upgrade.pm +++ b/src/lib/Sympa/Upgrade.pm @@ -1727,6 +1727,54 @@ sub upgrade { ); } + # Database field type datetime was deprecated. Unix time will be used. + if (lower_version($previous_version, '6.2.25b.3')) { + my $sdm = Sympa::DatabaseManager->instance; + + $log->syslog('notice', 'Upgrading subscriber_table.'); + # date_subscriber & update_subscriber (datetime) was obsoleted. + # Use date_epoch_subscriber & update_epoch_subscriber (int). + $sdm->do_prepared_query( + sprintf( + q{UPDATE subscriber_table + SET date_epoch_subscriber = %s + WHERE date_subscriber IS NOT NULL AND + date_epoch_subscriber IS NULL}, + _get_canonical_read_date($sdm, 'date_subscriber') + ) + ); + $sdm->do_prepared_query( + sprintf( + q{UPDATE subscriber_table + SET update_epoch_subscriber = %s + WHERE update_subscriber IS NOT NULL AND + update_epoch_subscriber IS NULL}, + _get_canonical_read_date($sdm, 'update_subscriber') + ) + ); + $log->syslog('notice', 'Upgrading admin_table.'); + # date_admin & update_admin (datetime) was obsoleted. + # Use date_epoch_admin & update_epoch_admin (int). + $sdm->do_prepared_query( + sprintf( + q{UPDATE admin_table + SET date_epoch_admin = %s + WHERE date_admin IS NOT NULL AND + date_epoch_admin IS NULL}, + _get_canonical_read_date($sdm, 'date_admin') + ) + ); + $sdm->do_prepared_query( + sprintf( + q{UPDATE admin_table + SET update_epoch_admin = %s + WHERE update_admin IS NOT NULL AND + update_epoch_admin IS NULL}, + _get_canonical_read_date($sdm, 'update_admin') + ) + ); + } + # GH Issue #43: Preliminary notice on abolishment of "host" list parameter. if (lower_version($previous_version, '6.2.28')) { my $all_lists = Sympa::List::get_lists('*'); @@ -2001,4 +2049,52 @@ sub save_web_tt2 { return 1; } +sub _get_canonical_read_date { + my $sdm = shift; + my $target = shift; + + if ($sdm->isa('Sympa::DatabaseDriver::MySQL')) { + return sprintf 'UNIX_TIMESTAMP(%s)', $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::Oracle')) { + return + sprintf + q{((to_number(to_char(%s,'J')) - to_number(to_char(to_date('01/01/1970','dd/mm/yyyy'), 'J'))) * 86400) +to_number(to_char(%s,'SSSSS'))}, + $target, $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::PostgreSQL')) { + return sprintf 'date_part(\'epoch\',%s)', $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::SQLite')) { + return $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::Sybase')) { + return sprintf 'datediff(second, \'01/01/1970\',%s)', $target; + } else { + # Unknown driver + return $target; + } +} + +# No yet used. +sub _get_cacnonical_write_date { + my $sdm = shift; + my $target = shift; + + if ($sdm->isa('Sympa::DatabaseDriver::MySQL')) { + return sprintf 'FROM_UNIXTIME(%d)', $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::Oracle')) { + return + sprintf + q{to_date(to_char(floor(%s/86400) + to_number(to_char(to_date('01/01/1970','dd/mm/yyyy'), 'J'))) || ':' ||to_char(mod(%s,86400)), 'J:SSSSS')}, + $target, $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::PostgreSQL')) { + return sprintf '\'epoch\'::timestamp with time zone + \'%d sec\'', + $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::SQLite')) { + return $target; + } elsif ($sdm->isa('Sympa::DatabaseDriver::Sybase')) { + return sprintf 'dateadd(second,%s,\'01/01/1970\')', $target; + } else { + # Unknown driver + return $target; + } +} + 1;