Fisheye: Tag 1.4.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/apm/version-i18n-export.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.7.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/apm/version-i18n-export.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.3.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/apm/version-i18n-import.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.4.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/apm/version-i18n-import.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/acs-admin/www/apm/version-i18n-index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/apm/version-i18n-index.adp,v diff -u -r1.7 -r1.7.2.1 --- openacs-4/packages/acs-admin/www/apm/version-i18n-index.adp 3 Oct 2003 10:36:09 -0000 1.7 +++ openacs-4/packages/acs-admin/www/apm/version-i18n-index.adp 9 Dec 2003 13:41:51 -0000 1.7.2.1 @@ -5,16 +5,14 @@

Import/Export Messages

- » Export - messages from the database to catalog files (NB! Overwrites - catalog files in the file system) + » Export + messages from the database to catalog files

» Import - messages from catalog files to the database (NB! Overwrites - messages in the database) + href="@import_url@">Import + messages from catalog files to the database

Index: openacs-4/packages/acs-admin/www/apm/version-i18n-index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/apm/version-i18n-index.tcl,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/packages/acs-admin/www/apm/version-i18n-index.tcl 3 Oct 2003 08:56:40 -0000 1.4 +++ openacs-4/packages/acs-admin/www/apm/version-i18n-index.tcl 9 Dec 2003 13:41:51 -0000 1.4.2.1 @@ -26,3 +26,5 @@ set localize_url [export_vars -base "[apm_package_url_from_key "acs-lang"]admin/message-list" { package_key {locale {[ad_conn locale]}}}] +set import_url [export_vars -base "/acs-lang/admin/import-messages" { package_key {return_url {[ad_return_url]}} }] +set export_url [export_vars -base "/acs-lang/admin/export-messages" { package_key {return_url {[ad_return_url]}} }] Index: openacs-4/packages/acs-lang/acs-lang.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/acs-lang.info,v diff -u -r1.31.2.3 -r1.31.2.4 --- openacs-4/packages/acs-lang/acs-lang.info 8 Dec 2003 15:11:43 -0000 1.31.2.3 +++ openacs-4/packages/acs-lang/acs-lang.info 9 Dec 2003 13:41:51 -0000 1.31.2.4 @@ -7,7 +7,7 @@ t t - + Peter Marklund OpenACS Internationalization Support. 2003-11-07 @@ -16,7 +16,7 @@ request processor hooks, templating, accessing and managing the message catalog, and locale-specific formatting functions for localizing dates, times, monetary amounts etc. - + Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/lib/conflict-link.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/lib/conflict-link.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/acs-lang/sql/oracle/message-catalog.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/sql/oracle/message-catalog.sql,v diff -u -r1.10 -r1.10.2.1 --- openacs-4/packages/acs-lang/sql/oracle/message-catalog.sql 22 Sep 2003 11:49:01 -0000 1.10 +++ openacs-4/packages/acs-lang/sql/oracle/message-catalog.sql 9 Dec 2003 13:41:51 -0000 1.10.2.1 @@ -26,9 +26,6 @@ on delete cascade constraint lang_message_keys_p_key_nn not null, - upgrade_status varchar2(30) - constraint lang_message_keys_us_ck - check (upgrade_status in ('no_upgrade', 'added','deleted')), description clob, constraint lang_message_keys_pk primary key (message_key, package_key) @@ -47,6 +44,11 @@ constraint lang_messages_locale_nn not null, message clob, + deleted_p char(1) default 'f' + constraint lang_messages_dp_ck check (deleted_p in ('t','f')), + sync_time date, + conflict_p char(1) default 'f' + constraint lang_messages_cp_ck check (conflict_p in ('t','f')), upgrade_status varchar2(30) constraint lang_messages_us_ck check (upgrade_status in ('no_upgrade', 'added', 'deleted', 'updated')), @@ -81,6 +83,14 @@ constraint lang_messages_audit_l_nn not null, old_message clob, + deleted_p char(1) default 'f' + constraint lang_messages_audit_dp_ck check (deleted_p in ('t','f')), + sync_time date, + conflict_p char(1) default 'f' + constraint lang_messages_audit_cp_ck check (conflict_p in ('t','f')), + upgrade_status varchar2(30) + constraint lang_messages_audit_us_ck + check (upgrade_status in ('no_upgrade', 'added', 'deleted', 'updated')), comment_text clob, overwrite_date date default sysdate not null, overwrite_user integer Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/sql/oracle/upgrade-5.0.0b4-5.0.0b5.sql'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/acs-lang/sql/postgresql/message-catalog.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/sql/postgresql/message-catalog.sql,v diff -u -r1.13 -r1.13.2.1 --- openacs-4/packages/acs-lang/sql/postgresql/message-catalog.sql 22 Sep 2003 11:49:01 -0000 1.13 +++ openacs-4/packages/acs-lang/sql/postgresql/message-catalog.sql 9 Dec 2003 13:41:52 -0000 1.13.2.1 @@ -27,9 +27,6 @@ on delete cascade constraint lang_message_keys_package_key_nn not null, - upgrade_status varchar(30) - constraint lang_message_keys_us_ck - check (upgrade_status in ('no_upgrade', 'added','deleted')), description text, constraint lang_message_keys_pk primary key (message_key, package_key) @@ -48,6 +45,9 @@ constraint lang_messages_locale_nn not null, message text, + deleted_p boolean default 'f', + sync_time timestamptz, + conflict_p boolean default 'f', upgrade_status varchar(30) constraint lang_messages_us_ck check (upgrade_status in ('no_upgrade', 'added', 'deleted', 'updated')), @@ -77,10 +77,15 @@ references ad_locales(locale) constraint lang_messages_audit_l_nn not null, - -- The old, overwritten message, not the new message being -- entered on this date by this user. old_message text, + deleted_p boolean default 'f', + sync_time timestamptz, + conflict_p boolean default 'f', + upgrade_status varchar(30) + constraint lang_messages_us_ck + check (upgrade_status in ('no_upgrade', 'added', 'deleted', 'updated')), comment_text text, overwrite_date timestamptz default now() @@ -141,5 +146,3 @@ ); end; - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/sql/postgresql/upgrade/upgrade-5.0.0b4-5.0.0b5.sql'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/acs-lang/tcl/lang-audit-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-audit-procs-oracle.xql,v diff -u -r1.2 -r1.2.2.1 --- openacs-4/packages/acs-lang/tcl/lang-audit-procs-oracle.xql 11 Aug 2003 16:16:21 -0000 1.2 +++ openacs-4/packages/acs-lang/tcl/lang-audit-procs-oracle.xql 9 Dec 2003 13:41:52 -0000 1.2.2.1 @@ -4,8 +4,10 @@ - insert into lang_messages_audit (package_key, message_key, locale, old_message, comment_text, overwrite_user) - values (:package_key, :message_key, :locale, empty_clob(), empty_clob(), :overwrite_user) + insert into lang_messages_audit (package_key, message_key, locale, old_message, comment_text, overwrite_user, + deleted_p, sync_time, conflict_p, upgrade_status) + values (:package_key, :message_key, :locale, empty_clob(), empty_clob(), :overwrite_user, + :deleted_p, :sync_time, :conflict_p, :upgrade_status) returning old_message, comment_text into :1, :2 Index: openacs-4/packages/acs-lang/tcl/lang-audit-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-audit-procs-postgresql.xql,v diff -u -r1.3 -r1.3.2.1 --- openacs-4/packages/acs-lang/tcl/lang-audit-procs-postgresql.xql 11 Aug 2003 16:16:21 -0000 1.3 +++ openacs-4/packages/acs-lang/tcl/lang-audit-procs-postgresql.xql 9 Dec 2003 13:41:52 -0000 1.3.2.1 @@ -4,8 +4,10 @@ - insert into lang_messages_audit (package_key, message_key, locale, old_message, comment_text, overwrite_user) - values (:package_key, :message_key, :locale, :old_message, :comment, :overwrite_user) + insert into lang_messages_audit (package_key, message_key, locale, old_message, comment_text, overwrite_user, + deleted_p, sync_time, conflict_p, upgrade_status) + values (:package_key, :message_key, :locale, :old_message, :comment, :overwrite_user, + :deleted_p, :sync_time, :conflict_p, :upgrade_status) Index: openacs-4/packages/acs-lang/tcl/lang-audit-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-audit-procs.tcl,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/packages/acs-lang/tcl/lang-audit-procs.tcl 22 Sep 2003 11:49:01 -0000 1.4 +++ openacs-4/packages/acs-lang/tcl/lang-audit-procs.tcl 9 Dec 2003 13:41:52 -0000 1.4.2.1 @@ -3,7 +3,7 @@ Auditing of lang_messages - @creation-date 15 October 2000 + @creation-date 3 December 2002 @author Peter Marklund (peter@collaboraid.biz) @cvs-id $Id$ } @@ -16,6 +16,10 @@ message_key locale comment + deleted_p + sync_time + conflict_p + upgrade_status } { Save a message that is overwritten. @author Peter Marklund Index: openacs-4/packages/acs-lang/tcl/lang-catalog-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-catalog-procs-oracle.xql,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/acs-lang/tcl/lang-catalog-procs-oracle.xql 19 Dec 2002 16:00:53 -0000 1.1 +++ openacs-4/packages/acs-lang/tcl/lang-catalog-procs-oracle.xql 9 Dec 2003 13:41:52 -0000 1.1.2.1 @@ -10,4 +10,47 @@ + + + update lang_messages + set sync_time = sysdate + where package_key = :package_key + and locale = :locale + + + + + + select message_key, + dbms_lob.substr(message) as message, + deleted_p + from lang_messages + where package_key = :package_key + and locale = :locale + and sync_time is not null + union + select lma1.message_key, + dbms_lob.substr(lma1.old_message) as message, + lma1.deleted_p + from lang_messages_audit lma1 + where lma1.package_key = :package_key + and lma1.locale = :locale + and lma1.sync_time is not null + and lma1.overwrite_date = (select max(lma2.overwrite_date) + from lang_messages_audit lma2 + where lma2.package_key = lma1.package_key + and lma2.message_key = lma1.message_key + and lma2.locale = :locale + and lma2.sync_time is not null + ) + and not exists (select 1 + from lang_messages + where package_key = lma1.package_key + and message_key = lma1.message_key + and locale = :locale + and sync_time is not null + ) + + + Index: openacs-4/packages/acs-lang/tcl/lang-catalog-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-catalog-procs-postgresql.xql,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/acs-lang/tcl/lang-catalog-procs-postgresql.xql 19 Dec 2002 16:00:53 -0000 1.1 +++ openacs-4/packages/acs-lang/tcl/lang-catalog-procs-postgresql.xql 9 Dec 2003 13:41:52 -0000 1.1.2.1 @@ -10,4 +10,49 @@ + + + update lang_messages + set sync_time = current_timestamp + where package_key = :package_key + and locale = :locale + + + + + + + select message_key, + message, + deleted_p + from lang_messages + where package_key = :package_key + and locale = :locale + and sync_time is not null + union + select lma1.message_key, + lma1.old_message, + lma1.deleted_p + from lang_messages_audit lma1 + where lma1.package_key = :package_key + and lma1.locale = :locale + and lma1.sync_time is not null + and lma1.overwrite_date = (select max(lma2.overwrite_date) + from lang_messages_audit lma2 + where lma2.package_key = lma1.package_key + and lma2.message_key = lma1.message_key + and lma2.locale = :locale + and lma2.sync_time is not null + ) + and not exists (select 1 + from lang_messages + where package_key = lma1.package_key + and message_key = lma1.message_key + and locale = :locale + and sync_time is not null + ) + + + + Index: openacs-4/packages/acs-lang/tcl/lang-catalog-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-catalog-procs.tcl,v diff -u -r1.36.2.1 -r1.36.2.2 --- openacs-4/packages/acs-lang/tcl/lang-catalog-procs.tcl 25 Nov 2003 12:45:17 -0000 1.36.2.1 +++ openacs-4/packages/acs-lang/tcl/lang-catalog-procs.tcl 9 Dec 2003 13:41:52 -0000 1.36.2.2 @@ -49,7 +49,7 @@ #set default_charset [encoding system] # LARS: Default to utf-8 set default_charset utf-8 - ns_log Warning "lang::catalog::default_charset_if_unsupported: charset $charset not supported by tcl, assuming $default_charset" + ns_log Warning "charset $charset not supported by tcl, assuming $default_charset" set charset_to_use $default_charset } else { set charset_to_use $charset @@ -92,7 +92,7 @@ return "[acs_package_root_dir $package_key]/catalog" } -ad_proc -public lang::catalog::is_upgrade_backup_file { file_path } { +ad_proc -private lang::catalog::is_upgrade_backup_file { file_path } { Given a file path return 1 if the path represents a file with messages backed up from message catalog upgrade. @@ -111,7 +111,7 @@ set return_value 1 } else { # Catalog file with unknown prefix - ns_log Warning "lang::catalog::is_upgrade_backup_file: The file $file_path has unknown prefix $prefix" + ns_log Warning "The file $file_path has unknown prefix $prefix" set return_value 0 } } @@ -217,22 +217,71 @@ return $catalog_paths } -ad_proc -public lang::catalog::reset_upgrade_status_message_keys { package_key } { - Before a package upgrade the upgrade status of message keys is cleared - so that upgrade status always reflects the last upgrade. +ad_proc -private lang::catalog::system_package_version_name { package_key } { + Returns the version name of the highest version of the given + package_key in the system. +} { + return [db_string get_version_name {}] +} +ad_proc -private lang::catalog::messages_in_db { + {-package_key:required} + {-locale:required} +} { + Return a list of all messages for a certain package and locale. + + @return An array list with message keys as keys and messages as + values. + + @see lang::catalog::all_messages_for_package_and_locale + @author Peter Marklund } { - db_dml reset_status {} + set message_list [list] + + all_messages_for_package_and_locale $package_key $locale + template::util::multirow_foreach all_messages { + lappend message_list @all_messages.message_key@ @all_messages.message@ + } + + return $message_list } -ad_proc -private lang::catalog::system_package_version_name { package_key } { - Returns the version name of the highest version of the given - package_key in the system. +ad_proc -private lang::catalog::last_sync_messages { + {-package_key:required} + {-locale:required} } { - return [db_string get_version_name {}] + For a certain package, and locale, return the messages in + the database the last time catalog files and db were in sync. + This is the message that we use as merge base during message catalog + upgrades. + + @return An array list with message keys as keys and messages as + values. + + @author Peter Marklund +} { + set message_list [list] + db_foreach last_sync_messages {} { + if { ![template::util::is_true $deleted_p] } { + lappend message_list $message_key $message + } + } + + return $message_list } +ad_proc -private lang::catalog::uninitialized_packages {} { + Return a list of keys for installed and enabled packages + that do not have any message keys associated with them. + This would suggest that either the package is not internationalized, + or we have not yet imported the message keys for the package. + + @author Peter Marklund +} { + return [db_list select_uninitialized {}] +} + ################## # # Exporting procs @@ -278,7 +327,7 @@ # Create the catalog directory if it doesn't exist set catalog_dir [package_catalog_dir $filename_info(package_key)] if { ![file isdirectory $catalog_dir] } { - ns_log Notice "lang::catalog::export_to_file: Creating new catalog directory $catalog_dir" + ns_log Notice "Creating new catalog directory $catalog_dir" file mkdir $catalog_dir } @@ -288,7 +337,7 @@ ns_log Notice "Backing up catalog file $file_path" file copy -- $file_path $backup_path } else { - ns_log Notice "lang::catalog::export_to_file: Not backing up $file_path as backup file already exists" + ns_log Notice "Not backing up $file_path as backup file already exists" } # Since the output charset, and thus the filename, may have changed since @@ -328,7 +377,7 @@ puts $catalog_file_id "" close $catalog_file_id - ns_log Notice "lang::catalog::export_to_file: Wrote $message_count messages to file $file_path with encoding $file_encoding" + ns_log Notice "Wrote $message_count messages to file $file_path with encoding $file_encoding" } ad_proc -public lang::catalog::export { @@ -373,8 +422,11 @@ -locale $locale] export_to_file -descriptions_list $descriptions_list $catalog_file_path $messages_list - } - } + + # Messages exported to file are in sync with file + db_dml update_sync_time {} + } + } } ################## @@ -398,13 +450,13 @@ @author Peter Marklund (peter@collaboraid.biz) } { if {![regexp {/([^/]*)\.([^/]*)\.(?:xml|cat)$} $catalog_filename match base msg_encoding]} { - ns_log Warning "lang::catalog::read_file: Charset info missing in filename assuming $catalog_filename is iso-8859-1" + ns_log Warning "Charset info missing in filename assuming $catalog_filename is iso-8859-1" set msg_encoding iso-8859-1 } set msg_encoding [default_charset_if_unsupported $msg_encoding] - ns_log Notice "lang::catalog::read_file: reading $catalog_filename in $msg_encoding" + ns_log Notice "reading $catalog_filename in $msg_encoding" set in [open $catalog_filename] fconfigure $in -encoding [ns_encodingforcharset $msg_encoding] set catalog_file_contents [read $in] @@ -422,8 +474,8 @@ package_version locale charset - messages - An array with message keys as keys and the message texts as values. - descriptions - An array with message keys as keys and the descriptions as values. + messages - An array-list with message keys as keys and the message texts as values. + descriptions - An array-list with message keys as keys and the descriptions as values. @author Peter Marklund (peter@collaboraid.biz) @@ -502,34 +554,30 @@

- To determine if the import is a message catalog upgrade the package - version of the catalog file will be compared with the highest package version - currently in the system (in the database). If the package version in the - catalog file deviates from what is in the system then the import is considered an upgrade. + The import should be considered an upgrade if the package has had messages + imported before. In this case the proc lang::catalog::import_messages will be used + to register the new messages with the system and handle the upgrade logic (a merge + with what's in the database).

-

- For upgrades, changed messages will have their old values (the ones in the - database that are overwritten) backed up to a file with a name on a format along the lines of - overwritten_messages_upgrade.-....xml - The upgrade status of message keys and messages will be updated during an upgrade. - Also during package upgrades, before invoking this procedure for the catalog files of a package the upgrade - status of message keys should be cleared with the proc - lang::catalog::reset_upgrade_status_message_keys -

- @param file_path The absolute path of the XML file to import messages from. The path must be on valid format, see apm_is_catalog_file + @return An array list containing the number of messages processed, number of messages added, + number of messages updated, and the number of messages deleted by the import. The keys of the + array list are processed, added, updated, and deleted. + @see lang::catalog::parse @see lang::message::register + @see lang::catalog::import_messages @author Peter Marklund } { # Check arguments assert_catalog_file $file_path # Parse the catalog file and put the information in an array + # LARS NOTE: Change parse to take three array-names, catalog, messages, descriptions, and use upvar array set catalog_array [parse [read_file $file_path]] # Extract package_key, locale, and charset from the file path @@ -544,109 +592,370 @@ error "the package_key $catalog_array(package_key) in the file $file_path does not match the package_key $package_key in the filesystem" } - # Figure out if we are upgrading - if { ![apm_package_installed_p $package_key] } { - # The package is not installed so we are not upgrading - set upgrade_p 0 - } else { - # The package is installed so this is probably an upgrade - set higher_version_p [apm_higher_version_installed_p $package_key $catalog_array(package_version)] - # higher_version_p value < 0 means downgrade, value 0 means versions are same, 1 is an upgrade - # A package downgrade could be considered a form of upgrade. However, in practice versions - # of the catalog files are sometimes not keeping up with the version in the info file and we don't - # want that to trigger an upgrade. - set upgrade_p [ad_decode $higher_version_p 1 1 0] - } - ns_log Notice "lang::catalog::import_from_file: Loading messages in file $file_path [ad_decode $upgrade_p 0 "" ", upgrading"]" - # Get the messages array, and the list of message keys to iterate over array set messages_array [lindex [array get catalog_array messages] 1] set messages_array_names [array names messages_array] # Get the descriptions array array set descriptions_array [lindex [array get catalog_array descriptions] 1] - if { $upgrade_p } { - # clear out any old upgrade status of messages - db_dml reset_upgrade_status_messages {} + ns_log Notice "Loading messages in file $file_path" - # Mark any messages that are in the system but not in the - # catalog file as deleted - all_messages_for_package_and_locale $package_key $locale - template::util::multirow_foreach all_messages { - set message_key @all_messages.message_key@ - if { [lsearch -exact $messages_array_names $message_key] < 0 } { - ns_log Notice "lang::catalog::import_from_file: Marking message $message_key in locale $locale as deleted" - db_dml mark_message_as_deleted {} + # Register messages + array set message_count [lang::catalog::import_messages \ + -file_messages_list [array get messages_array] \ + -package_key $package_key \ + -locale $locale] - # One approach to deleted message keys after upgrade is to consider those - # keys deleted whose messages in all locales have an upgrade status - # of deleted in the lang_messages table. - # However in the somewhat unusual case where the package we are upgrading - # to doesn't have all locales that the old package version does, upgrade - # status won't be set to deleted for all locales. - # The workable solution seems to be to consider a key as deleted if its - # en_US message has the deleted upgrade status. - if { [string equal $locale "en_US"] } { - db_dml mark_message_key_as_deleted {} + # Register descriptions + foreach message_key $messages_array_names { + if { [info exists descriptions_array($message_key)] } { + with_catch errmsg { + lang::message::update_description \ + -package_key $catalog_array(package_key) \ + -message_key $message_key \ + -description $descriptions_array($message_key) + } { + global errorInfo + ns_log Error "Registering description for key ${package_key}.${message_key} in locale $locale failed with error message \"$errmsg\"\n\n$errorInfo" + } + } + } + + return [array get message_count] +} + +ad_proc -private lang::catalog::import_messages { + {-file_messages_list:required} + {-package_key:required} + {-locale:required} +} { +

+ Import a given set of messages from a catalog file to the database + for a certain package and locale. If we already have messages in the db + for the given package and locale then a merge + between the database messages and the file messages will be performed. +

+ +

+ Foreach message to import, the base + messages for the merge is the messages in the db from the last time + db and catalog file were in sync for the corresponding message key. The first such sync point + is the initial import of a message. After that, any export of messages to + the file system will be a sync point. Also, after an upgrade, a large number + of the resulting messages in the db will be identical to those in the file (the + file messages take precedence on conflict) and those messages will also be sync points. + A message being in sync between db and file is indicated by the lang_message.sync_time + column being set to a not null value. +

+ +

+ This proc is idempotent which means that it can be executed multiple times and after the first + time it's been executed it won't have any effect on the db. See the corresponding + acs-automated-testing test case called upgrade. +

+ +

+ What follows below is a description of the logic of the proc in terms of its input, the cases considered, + and the logical actions taken for each case. +

+ +

+ There are three sets of keys, file, db, and base keys. For each key in + the union of these keys there are three messages that can exist: the file message, the db message, and the base message. The + base message serves as the base for the merge. We will distinguish all the different permutations + of each of the three messages existing or not, and all permutations of the messages being different from eachother. + We don't distinguish how two messages are different, only whether they are different or not. + In total that gives us 14 cases (permutations) to consider. +

+ +
+    *** Exactly one of messages exists (3 cases):
+
+    1. base message (deleted in file and db). upgrade_action=none, conflict_p=f
+
+    2. db message (added in db). upgrade_action=none, conflict_p=f
+
+    3. file message (added in file). upgrade_action=add, conflict_p=f
+
+    *** Exactly two of the messages exist (6 cases):
+
+    - Base and file message (db message deleted):
+      4. Differ (conflicting change). upgrade_action=resurrect, conflict_p=t
+      5. No difference (no conflicting change). upgrade_action=none, conflict_p=f
+
+    - Base and db message (file message deleted):
+      6. Differ (conflicting change): upgrade_action=delete, conflict_p=t
+      7. No difference (no conflicting change): upgrade_action=delete, conflict_p=f
+
+    - File and db message (message added in both db and file):
+      8. Differ (conflicting change). upgrade_action=update, conflict_p=t
+      9. No difference (identical changes). upgrade_action=none, conflict_p=f
+
+    *** All three messages exist (5 cases):
+
+    10. All the same. upgrade_action=none, conflict_p=f
+
+    11. File and base the same. upgrade_action=none, conflict_p=f
+
+    12. DB and base the same. upgrade_action=update, conflict_p=f
+
+    13. File and DB the same. upgrade_action=none, conflict_p=f
+
+    14. All different. upgrade_action=update, conflict_p=t
+    
+ + @param file_messages_list An array list with message keys as keys and + the message of those keys as values, + i.e. (key, value, key, value, ...) + + @param package_key The package_key for the messages. + + @param locale The locale of the messages. + + @return An array list containing the number of messages processed, number of messages added, + number of messages updated, and the number of messages deleted by the import. The keys of the + array list are processed, added, updated, and deleted. + + @author Peter Marklund + @author Lars Pind +} { + set message_count(processed) 0 + set message_count(added) 0 + set message_count(updated) 0 + set message_count(deleted) 0 + + # Form arrays for all three sets of messages + array set file_messages $file_messages_list + array set db_messages [messages_in_db \ + -package_key $package_key \ + -locale $locale] + array set base_messages [last_sync_messages \ + -package_key $package_key \ + -locale $locale] + + foreach arrname { base_messages file_messages db_messages } { + set dummy [list] + foreach elm [lsort [array names $arrname]] { + lappend dummy "$elm=[set ${arrname}($elm)]" + } + ns_log Debug "lang::catalog::import_messages - $arrname: $dummy" + } + + # Remember each time we've processed a key, so we don't process it twice + array set message_key_processed_p [list] + + # Loop over the union of import and db keys. + foreach message_key [lsort [concat [array names db_messages] [array names file_messages] [array names base_messages]]] { + if { [info exists message_key_processed_p($message_key)] } { + continue + } + set message_key_processed_p($message_key) 1 + + ########################################### + # + # Figure out how db and file messages have changed with regards to the base message + # + ########################################### + + # The variables indicate how the db and file messages have changed + # from the base message. Valid values are: none, add, update, delete + set db_change "none" + set file_change "none" + + if { [info exists base_messages($message_key)] } { + # The base message exists + + if { [info exists db_messages($message_key)] } { + # db message exists + if { ![string equal $db_messages($message_key) $base_messages($message_key)] } { + # db message and base message differ + set db_change "update" } + } else { + # db message does not exist + set db_change "delete" } + + if { [info exists file_messages($message_key)] } { + # file message exists + if { ![string equal $file_messages($message_key) $base_messages($message_key)] } { + # file message and base message differ + set file_change "update" + } + } else { + # file message does not exist + set file_change "delete" + } + } else { + # The base message does not exist + + if { [info exists db_messages($message_key)] } { + # db message exists + set db_change "add" + } + if { [info exists file_messages($message_key)] } { + # file message exists + set file_change "add" + } } - } - # Loop over and register the messages - array set overwritten_db_messages {} - foreach message_key $messages_array_names { - set qualified_key "$package_key.$message_key" - set new_message $messages_array($message_key) + ########################################### + # + # Based on the change in file and db messages, + # and based on whether file and db messages differ, decide + # which upgrade actions to take + # + ########################################### - # Failing to register one message should not cause the whole file import to fail - with_catch errmsg { - # If this is an upgrade - save old message if it will be overwritten - if { $upgrade_p } { - # Check if the message existed previously - if { [lang::message::message_exists_p $locale $qualified_key] } { - # Check if message is updated, avoid variable substitution during lookup by setting upvar_level to 0 - set old_message [lang::message::lookup $locale $qualified_key {} {} 0] - if { ![string equal $old_message $new_message] } { - set overwritten_db_messages($message_key) $old_message + # Default values cover the cases 2, 5, 9, 10, 11, 13 + set import_case "in 2, 5, 9, 10, 11, 13" + set upgrade_status "no_upgrade" + set conflict_p "f" + + switch $db_change { + none { + switch $file_change { + none {} + add { + # case 3 + set import_case 3 + # add message from file to db + set upgrade_status "added" } + update { + # case 12 + set import_case 12 + # update db with file message + set upgrade_status "updated" + } + delete { + # case 7 + set import_case 7 + # mark message in db deleted + set upgrade_status "deleted" + } } - } + } + add { + switch $file_change { + none {} + add { + if { ![string equal $db_messages($message_key) $file_messages($message_key)] } { + # case 8 + set import_case 8 + # differing additions in db and file + set upgrade_status "updated" + set conflict_p "t" + } + } + } + } + update { + switch $file_change { + none {} + update { + if { ![string equal $db_messages($message_key) $file_messages($message_key)] } { + # case 14 + set import_case 14 + # differing updates in file and db + set upgrade_status "updated" + set conflict_p "t" + } + } + delete { + # case 6 + set import_case 6 + # deletion in file but update in db + set upgrade_status "deleted" + set conflict_p "t" + } + } + } + delete { + switch $file_change { + none {} + update { + # case 4 + set import_case 4 + # deletion in db but update in file + set upgrade_status "added" ;# resurrect + set conflict_p "t" + } + delete { + # case 1 + set import_case 1 + # deletion in both db and file + # no status change, no conflict + # sync time should be updated below + } + } + } + } - # Register the new message with the system + ########################################### + # + # Execute upgrade actions + # + ########################################### + + # For certain messages we need to move the sync point so that we have a current base for the next upgrade. + if { [string equal $db_change "none"] || ![string equal $file_change "none"] } { + # If there is no db change then any change in the file will be reflected in + # db (file takes precedence) and file and db are identical. + # Also, regardless of what's happened in db, if + # there has been a change in the file then that change will take effect in + # the db and file and db are again identical (in sync). + set update_sync_p 1 + } else { + set update_sync_p 0 + } + + # Store a new message in the database if we are adding or updating + if { [string equal $upgrade_status "added"] || [string equal $upgrade_status "updated"] } { + + ns_log Debug "lang::catalog::import_messages - invoking lang::message::register with import_case=\"$import_case\" -update_sync=$update_sync_p $message_key $upgrade_status $conflict_p" lang::message::register \ - -upgrade=$upgrade_p \ - $catalog_array(locale) \ - $catalog_array(package_key) \ - $message_key \ - $new_message + -update_sync \ + -upgrade_status $upgrade_status \ + -conflict=$conflict_p \ + $locale \ + $package_key \ + $message_key \ + $file_messages($message_key) - if { [info exists descriptions_array($message_key)] } { - lang::message::update_description \ - -package_key $catalog_array(package_key) \ - -message_key $message_key \ - -description $descriptions_array($message_key) - } - } { - global errorInfo - ns_log Error "Registering message for key $qualified_key in locale $locale failed with error message \"$errmsg\"\n\n$errorInfo" + } elseif { $update_sync_p || [string equal $upgrade_status "deleted"] } { + # Set the upgrade_status, deleted_p, conflict_p, and sync_time properties of the message + + # If we are doing nothing, the only property of the message we might want to update in the db + # is the sync_time as we might have discovered that db and file are in sync + array unset edit_array + if { ![string equal $upgrade_status "no_upgrade"] } { + set edit_array(upgrade_status) $upgrade_status + set edit_array(deleted_p) [string equal $upgrade_status "deleted"] + set edit_array(conflict_p) $conflict_p + } + + ns_log Debug "lang::catalog::import_messages - invoking lang::message::edit with import_case=\"$import_case\" -update_sync=$update_sync_p $message_key [array get edit_array]" + lang::message::edit \ + -update_sync=$update_sync_p \ + $package_key \ + $message_key \ + $locale \ + [array get edit_array] + } else { + ns_log Debug "lang::catalog::import_messages - not doing anything: import_case=\"$import_case\" $message_key $upgrade_status $conflict_p" } - } - # Save any messages overwritten in database - if { $upgrade_p && [array size overwritten_db_messages] > 0 } { - set system_package_version [system_package_version_name $package_key] - # Note that export_messages_to_file demands a certain filename format + if { [lsearch -exact {added updated deleted} $upgrade_status] != -1 } { + incr message_count($upgrade_status) + } else { + incr message_count(processed) + } - ns_log Notice "lang::catalog::import_from_file: Saving overwritten messages during upgrade for package $package_key and locale $locale in file $filename" - set file_path [get_catalog_file_path \ - -backup_from_version ${system_package_version} \ - -backup_to_version $catalog_array(package_version) \ - -package_key $package_key \ - -locale $locale] - export_messages_to_file $file_path [array get overwritten_db_messages] - } + } ;# End of message key loop + + return [array get message_count] } ad_proc -public lang::catalog::import { @@ -657,23 +966,35 @@ } { Import messages from catalog files to the database. By default all messages for enabled packages and enabled locales will be imported. Optionally, the import - can be restricted to a certain package and/or a list of locales. + can be restricted to a certain package and/or a list of locales. Invokes the proc + lang::catalog::import_messages that deals with multiple imports (upgrades). @param package_key Restrict the import to the package with this key @param locales A list of locales to restrict the import to @param initialize Only load messages from packages that have never before had any message imported @param cache Provide this switch if you want the proc to cache all the imported messages + @return An array list containing the number of messages processed, number of messages added, + number of messages updated, and the number of messages deleted by the import. The keys of the + array list are processed, added, updated, and deleted. + + @see lang::catalog::import_messages + @author Peter Marklund } { + set message_count(processed) 0 + set message_count(added) 0 + set message_count(updated) 0 + set message_count(deleted) 0 + if { ![empty_string_p $package_key] } { set package_key_list $package_key } else { set package_key_list [apm_enabled_packages] } if { $initialize_p } { - set uninitialized_packages [db_list select_uninitialized {}] + set uninitialized_packages [uninitialized_packages] } foreach package_key $package_key_list { @@ -693,23 +1014,30 @@ # Issue a warning and exit if there are no catalog files if { [empty_string_p $catalog_files] } { - ns_log Warning "lang::catalog::import: No catalog files found for package $package_key" + ns_log Warning "No catalog files found for package $package_key" continue } + array unset loop_message_count foreach file_path $catalog_files { # Use a catch so that parse failure of one file doesn't cause the import of all files to fail - if { [catch {import_from_file $file_path} errMsg] } { + if { [catch { array set loop_message_count [lang::catalog::import_from_file $file_path] } errMsg] } { global errorInfo - ns_log Error "lang::catalog::import: The import of file $file_path failed, error message is:\n\n${errMsg}\n\nstack trace:\n\n$errorInfo\n\n" - } - } + ns_log Error "The import of file $file_path failed, error message is:\n\n${errMsg}\n\nstack trace:\n\n$errorInfo\n\n" + } + } + + foreach action [array names loop_message_count] { + set message_count($action) [expr $message_count($action) + $loop_message_count($action)] + } } if { $cache_p } { lang::message::cache } + + return [array get message_count] } ad_proc -private lang::catalog::get_catalog_paths_for_import { @@ -756,7 +1084,7 @@ if { [file exists $file_path] } { lappend catalog_files $file_path } else { - ns_log Error "lang::catalog::get_catalog_paths_for_import: Catalog file $file_path not found. Failed to import messages for package $package_key and locale $locale" + ns_log Error "Catalog file $file_path not found. Failed to import messages for package $package_key and locale $locale" } } @@ -817,7 +1145,7 @@ if [catch { set translated_message [lang_babel_translate $message en_$lang] } errmsg] { - ns_log Notice "lang::catalog::translate: Error translating $message into $lang: $errmsg" + ns_log Notice "Error translating $message into $lang: $errmsg" } else { lang::message::register $lang $package_key $message_key $translated_message } Index: openacs-4/packages/acs-lang/tcl/lang-catalog-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-catalog-procs.xql,v diff -u -r1.11 -r1.11.2.1 --- openacs-4/packages/acs-lang/tcl/lang-catalog-procs.xql 16 Oct 2003 16:25:49 -0000 1.11 +++ openacs-4/packages/acs-lang/tcl/lang-catalog-procs.xql 9 Dec 2003 13:41:52 -0000 1.11.2.1 @@ -1,7 +1,7 @@ - + select package_key from apm_package_types @@ -35,7 +35,7 @@ and lm.package_key = lmk.package_key and lm.package_key = :package_key and lm.locale = :locale - and lmk.upgrade_status != 'deleted' + and lm.deleted_p = 'f' Index: openacs-4/packages/acs-lang/tcl/lang-message-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-message-procs-oracle.xql,v diff -u -r1.7 -r1.7.2.1 --- openacs-4/packages/acs-lang/tcl/lang-message-procs-oracle.xql 22 Sep 2003 11:49:01 -0000 1.7 +++ openacs-4/packages/acs-lang/tcl/lang-message-procs-oracle.xql 9 Dec 2003 13:41:52 -0000 1.7.2.1 @@ -5,23 +5,34 @@ update lang_messages - set message = empty_clob(), - upgrade_status = :message_upgrade_status + set [join $set_clauses ", "] where locale = :locale and message_key = :message_key and package_key = :package_key returning message into :1 - + - insert into lang_messages (package_key, message_key, locale, message, upgrade_status, creation_user) - values (:package_key, :message_key, :locale, empty_clob(), :message_upgrade_status, :creation_user) + insert into lang_messages ([join $col_clauses ", "]) + values ([join $val_clauses ", "]) returning message into :1 + + + sysdate + + + + + + empty_clob() + + + update lang_message_keys @@ -32,4 +43,10 @@ + + + sync_time = sysdate + + + Index: openacs-4/packages/acs-lang/tcl/lang-message-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-message-procs-postgresql.xql,v diff -u -r1.8 -r1.8.2.1 --- openacs-4/packages/acs-lang/tcl/lang-message-procs-postgresql.xql 22 Sep 2003 11:49:01 -0000 1.8 +++ openacs-4/packages/acs-lang/tcl/lang-message-procs-postgresql.xql 9 Dec 2003 13:41:52 -0000 1.8.2.1 @@ -1,26 +1,36 @@ - postgresql7.2 + + + update lang_messages + set [join $set_clauses ", "] + where locale = :locale + and message_key = :message_key + and package_key = :package_key + + + - insert into lang_messages (package_key, message_key, locale, message, upgrade_status, creation_user) - values (:package_key, :message_key, :locale, :message, :message_upgrade_status, :creation_user) + insert into lang_messages ([join $col_clauses ", "]) + values ([join $val_clauses ", "]) - - - update lang_messages - set message = :message, - upgrade_status = :message_upgrade_status - where locale = :locale - and message_key = :message_key - and package_key = :package_key - - + + + current_timestamp + + + + + :message + + + update lang_message_keys @@ -30,4 +40,10 @@ + + + sync_time = current_timestamp + + + Index: openacs-4/packages/acs-lang/tcl/lang-message-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-message-procs.tcl,v diff -u -r1.39.2.2 -r1.39.2.3 --- openacs-4/packages/acs-lang/tcl/lang-message-procs.tcl 25 Nov 2003 12:45:17 -0000 1.39.2.2 +++ openacs-4/packages/acs-lang/tcl/lang-message-procs.tcl 9 Dec 2003 13:41:52 -0000 1.39.2.3 @@ -18,7 +18,9 @@ namespace eval lang::message {} ad_proc -public lang::message::register { - -upgrade:boolean + {-update_sync:boolean} + {-upgrade_status "no_upgrade"} + {-conflict:boolean} {-comment ""} locale package_key @@ -34,29 +36,35 @@ cache with the message.

-

- If we are registering a message as part of an upgrade, appropriate - upgrade status for the message key (added) and the message (updated or - added) will be set. -

- @author Jeff Davis @author Peter Marklund @author Bruno Mattarollo (bruno.mattarollo@ams.greenpeace.org) @author Christian Hvid @see _mr - @param locale Locale or language of the message. If a language is supplied, - the default locale for the language is looked up. + @param locale Locale or language of the message. If a language is supplied, + the default locale for the language is looked up. - @param package_key The package key of the package that the message belongs to. - @param message_key The key that identifies the message within the package. - @param message The message text - @param upgrade A boolean switch indicating if this message is registered - as part of a message catalog upgrade or not. The default - (switch not provided) is that we are not upgrading. + @param package_key The package key of the package that the message belongs to. + @param message_key The key that identifies the message within the package. + + @param message The message text + + @param update_sync If this switch is provided the sync_time + of the message will be set to current time. The sync time for + a message should only be not null when we know that message in + catalog file and db are identical (in sync). This message is then + used as a merge base for message catalog upgrades. For more info, + see the lang::catalog::upgrade proc. + + @param upgrade_status Set the upgrade status of the new message to "added", "updated", "deleted". + Defaults to "no_upgrade". + + @param conflict Set this switch if the upgrade represents a conflict between + changes made in the database and in catalog files. + @see lang::message::lookup @see _ } { @@ -67,10 +75,10 @@ # We don't do a more throughout check since this is not # invoked by users. # let's get the default locale for that language - set locale [util_memoize [list ad_locale_locale_from_lang $locale]] + set locale [lang::util::default_locale_from_lang $locale] } - # Create a globally unique key for the cache + # Create a globally (across packages) unique key for the cache set key "${package_key}.${message_key}" # Insert the message key into the database if it doesn't @@ -79,10 +87,6 @@ if { ! $key_exists_p } { if { [string equal $locale "en_US"] } { - set key_upgrade_status [ad_decode $upgrade_p 1 "added" "no_upgrade"] - if { $upgrade_p } { - ns_log Notice "lang::message::register - Giving message key $message_key an upgrade status of $key_upgrade_status" - } db_dml insert_message_key {} } else { # Non-default locale @@ -107,62 +111,208 @@ error "Message key '$key' in locale '$locale' has these embedded variables not present in the en_US locale: [join $missing_vars ","]. Message has not been imported." } } + + # Build up an array of columns to set + array set cols [list] + if { $update_sync_p } { + set cols(sync_time) [db_map sync_time] + } else { + set cols(sync_time) "null" + } + if { [empty_string_p [string trim $message]] } { + set cols(message) "null" + } else { + set cols(message) [db_map message] + } + set cols(upgrade_status) :upgrade_status + set conflict_db_p [db_boolean $conflict_p] + set cols(conflict_p) :conflict_db_p + # Different logic for update and insert if { [nsv_exists lang_message_$locale $key] } { # Update existing message if the message has changed + # For use in audit log call set old_message [nsv_get lang_message_$locale $key] + # Peter TODO: should these attributes be cached? + lang::message::get \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale \ + -array old_message_array - lang::audit::changed_message $old_message $package_key $message_key $locale $comment + # An updated message is no longer deleted + set deleted_p f + set cols(deleted_p) :deleted_p - set message_upgrade_status [ad_decode $upgrade_p 1 "updated" "no_upgrade"] - if { $upgrade_p } { - ns_log Notice "lang::message::register - Giving message for key $message_key in locale $locale an upgrade status of $message_upgrade_status" + # For use in update query + set set_clauses [list] + foreach col [array names cols] { + lappend set_clauses "$col = $cols($col)" } - # Trying to avoid hitting Oracle bug#2011927 - if { [empty_string_p [string trim $message]] } { - db_dml lang_message_null_update {} - } else { - db_dml lang_message_update {} -clobs [list $message] + db_transaction { + + # Update audit log + lang::audit::changed_message \ + $old_message \ + $package_key \ + $message_key \ + $locale \ + $comment \ + $old_message_array(deleted_p) \ + $old_message_array(sync_time) \ + $old_message_array(conflict_p) \ + $old_message_array(upgrade_status) + + # Trying to avoid hitting Oracle bug#2011927 + if { [empty_string_p [string trim $message]] } { + db_dml lang_message_null_update {} + } else { + set cols(message) [db_map message] + db_dml lang_message_update {} -clobs [list $message] + } } - nsv_set lang_message_$locale $key $message - } else { # Insert new message - db_transaction { - set message_upgrade_status [ad_decode $upgrade_p 1 "added" "no_upgrade"] - if { $upgrade_p } { - ns_log Notice "lang::message::register - Giving message for key $message_key in locale $locale an upgrade status of $message_upgrade_status" - } + set cols(package_key) :package_key + set cols(message_key) :message_key + set cols(locale) :locale - if { [catch {set creation_user [ad_conn user_id]}] } { - set creation_user [db_null] - } - - # avoiding bug#2011927 from Oracle. - if { [empty_string_p [string trim $message]] } { - db_dml lang_message_insert_null_msg {} - } else { - # LARS: - # We may need to have two different lines here, one for - # Oracle w/clobs, one for PG w/o clobs. - db_dml lang_message_insert {} -clobs [list $message] - } - nsv_set lang_message_$locale $key $message + # We wrap this in a catch, so that it still works in the bootstrap-installer where ad_conn user_id will fail. + # LARS NOTE: Why not make ad_conn user_id return 0 in the bootstrap-installer? + catch { + set creation_user [ad_conn user_id] + set cols(creation_user) :creation_user } + + set col_clauses [list] + set val_clauses [list] + foreach col [array names cols] { + lappend col_clauses $col + lappend val_clauses $cols($col) + } + + # avoiding bug#2011927 from Oracle. + if { [empty_string_p [string trim $message]] } { + db_dml lang_message_insert_null_msg {} + } else { + db_dml lang_message_insert {} -clobs [list $message] + } } + + # Update the message catalog cache + nsv_set lang_message_$locale $key $message } +ad_proc -public lang::message::delete { + -package_key:required + -message_key:required + -locale:required +} { + Deletes a message in a particular locale. + + @author Lars Pind (lars@collaboraid.biz) +} { + lang::message::edit \ + $package_key \ + $message_key \ + $locale \ + [list deleted_p t \ + upgrade_status no_upgrade \ + conflict_p f \ + sync_time [db_null] \ + ] +} + +ad_proc -public lang::message::get_element { + -package_key:required + -message_key:required + -locale:required + -element:required +} { + Get value of a single attribute of a message. + + @param element The name of the attribute that you want. + + @see lang::message::get + + @author Peter Marklund +} { + lang::message::get \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale \ + -array message_array + + return $message_array($element) +} + +ad_proc -public lang::message::get { + -package_key:required + -message_key:required + -locale:required + -array:required +} { + Get all properties of a message in a particular locale. + + @param array Name of an array in the caller's namespace into + which you want the message properties delivered. + + @return The array will contain the following entries: + message_key, + package_key, + locale, + message, + deleted_p, + sync_time, + conflict_p, + upgrade_status, + creation_date_ansi, + creation_user, + key_description. + + @author Lars Pind (lars@collaboraid.biz) +} { + upvar 1 $array row + + db_1row select_message_props { + select m.message_key, + m.package_key, + m.locale, + m.message, + m.deleted_p, + m.sync_time, + m.conflict_p, + m.upgrade_status, + to_char(m.creation_date, 'YYYY-MM-DD HH24:MI:SS') as creation_date_ansi, + m.creation_user, + k.description as key_description + from lang_messages m, + lang_message_keys k + where m.package_key = :package_key + and m.message_key = :message_key + and m.locale = :locale + and k.package_key = m.package_key + and k.message_key = m.message_key + } -column_array row +} + ad_proc -public lang::message::unregister { package_key message_key } { Unregisters a message key, i.e. deletes it along with all its messages - from the database and deleted entries in the cache. + from the database and deleted entries in the cache. This proc is + useful when installing a package. + To delete an individual message, as opposed to the entire key, + use lang::message::delete. + + @see lang::message::delete + @author Peter Marklund } { # Deletes messages as well @@ -175,6 +325,144 @@ remove_from_cache $package_key $message_key } +ad_proc -private lang::message::edit { + {-update_sync:boolean} + package_key + message_key + locale + edit_array_list +} { + Edit properties (meta data) of a language catalog message, but not + the message text itself. To update or add message catalog text, use + the lang::message::register proc. + +

+ Implementation note: some of the dynamic sql edit + code of this proc was copied from the auth::authority::edit proc + and should probably be broken out into a general API. +

+ + @param package_key The package_key of the message to update + + @param message_key The message_key of the message to update + + @param locale The locale of the message to update + + @param edit_array_list An array list holding names of columns and + and the values to set them to. Valid keys + in this array list are any column names in the + lang_messages table. + + @param update_sync If this switch is provided the sync_time + of the message will be updated to current time. If not + provided no update to sync_time will be made. If sync_time + is contained in the edit_array_list then that value will + override the update_sync flag. + + @author Peter Marklund +} { + array set edit_array $edit_array_list + + if { [info exists edit_array(message)] } { + error "The proc lang::message::edit was invoked with the message attribute in the edit array. To edit the message text of a message use the lang::message::register proc instead" + } + + if { [info exists edit_array(deleted_p)] } { + set edit_array(deleted_p) [db_boolean [template::util::is_true $edit_array(deleted_p)]] + + # If we are deleting we need to preserve the old message in the audit log + if { [template::util::is_true $edit_array(deleted_p)] } { + + # Peter TODO: should these attributes be cached? + lang::message::get \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale \ + -array old_message_array + + lang::audit::changed_message \ + $old_message_array(message) \ + $package_key \ + $message_key \ + $locale \ + "deleted" \ + $old_message_array(deleted_p) \ + $old_message_array(sync_time) \ + $old_message_array(conflict_p) \ + $old_message_array(upgrade_status) + + # If we are deleting an en_US message we need to mark the message deleted in all locales + if { [string equal $locale "en_US"] } { + set message_locales [db_list all_message_locales { + select locale + from lang_messages + where package_key = :package_key + and message_key = :message_key + and locale <> 'en_US' + }] + foreach message_locale $message_locales { + lang::message::delete \ + -package_key $package_key \ + -message_key $message_key \ + -locale $message_locale + } + } + } + } + + set set_clauses [list] + foreach name [array names edit_array] { + lappend set_clauses "$name = :$name" + set $name $edit_array($name) + } + if { $update_sync_p } { + if { ![info exists edit_array(sync_time)] } { + lappend set_clauses [db_map set_sync_time_now] + } + } + + if { [llength $set_clauses] > 0 } { + + set sql " + update lang_messages + set [join $set_clauses ", "] + where package_key = :package_key + and message_key = :message_key + and locale = :locale + " + db_dml edit_message_key $sql + } +} + +ad_proc -public lang::message::conflict_count { + {-package_key ""} + {-locale ""} +} { + Return the number of messages with conflicts (conflict_p=t) resulting + from catalog imports. + + @param package_key Restrict count to package with this key + @param locale Restrict count to messages of this locale + + @author Peter Marklund +} { + # Build any package and locale where clauses + set where_clauses [list] + foreach col {package_key locale} { + if { ![empty_string_p [set $col]] } { + lappend where_clauses "$col = :${col}" + } + } + set where_clause [ad_decode $where_clauses "" "" "and [join $where_clauses " and "]"] + + return [db_string conflict_count " + select count(*) + from lang_messages + where conflict_p = 't' + $where_clause + "] +} + ad_proc -private lang::message::remove_from_cache { package_key message_key @@ -521,7 +809,6 @@ set i 0 db_foreach select_locale_keys {} { - ns_log Notice "pm debug ${package_key}.${message_key} $message" nsv_set lang_message_$locale "${package_key}.${message_key}" $message incr i } Index: openacs-4/packages/acs-lang/tcl/lang-message-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/lang-message-procs.xql,v diff -u -r1.7 -r1.7.2.1 --- openacs-4/packages/acs-lang/tcl/lang-message-procs.xql 18 Aug 2003 08:10:21 -0000 1.7 +++ openacs-4/packages/acs-lang/tcl/lang-message-procs.xql 9 Dec 2003 13:41:52 -0000 1.7.2.1 @@ -22,23 +22,29 @@ insert into lang_message_keys - (message_key, package_key, upgrade_status) + (message_key, package_key) values - (:message_key, :package_key, :key_upgrade_status) + (:message_key, :package_key) update lang_messages - set message = null, - upgrade_status = :message_upgrade_status + set [join $set_clauses ", "] where locale = :locale and package_key = :package_key and message_key = :message_key + + + insert into lang_messages ([join $col_clauses ", "]) + values ([join $val_clauses ", "]) + + + select locale, package_key, message_key, message @@ -47,13 +53,6 @@ - - - insert into lang_messages (package_key, message_key, locale, message, upgrade_status) - values (:package_key, :message_key, :locale, null, :message_upgrade_status) - - - update lang_message_keys Index: openacs-4/packages/acs-lang/tcl/test/acs-lang-test-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/tcl/test/acs-lang-test-procs.tcl,v diff -u -r1.11 -r1.11.2.1 --- openacs-4/packages/acs-lang/tcl/test/acs-lang-test-procs.tcl 4 Nov 2003 10:32:43 -0000 1.11 +++ openacs-4/packages/acs-lang/tcl/test/acs-lang-test-procs.tcl 9 Dec 2003 13:41:52 -0000 1.11.2.1 @@ -7,7 +7,7 @@ namespace eval lang::test {} -ad_proc lang::test::get_dir {} { +ad_proc -private lang::test::get_dir {} { The test directory of the acs-lang package (where this file resides). @author Peter Marklund (peter@collaboraid.biz) @@ -16,7 +16,7 @@ return "[acs_package_root_dir acs-lang]/tcl/test" } -ad_proc lang::test::assert_browser_locale {accept_language expect_locale} { +ad_proc -private lang::test::assert_browser_locale {accept_language expect_locale} { Assert that with given accept language header lang::conn::browser_locale returns the expected locale. @@ -27,10 +27,443 @@ aa_equals "accept-language header \"$accept_language\"" $browser_locale $expect_locale } +ad_proc -private lang::test::test_package_key {} { + return "acs-lang-test-tmp" +} +ad_proc -private lang::test::setup_test_package {} { + set package_key [test_package_key] + set package_name "acs-lang temporary test package" + set package_dir [file join [acs_root_dir] packages $package_key] + file mkdir $package_dir + set info_file_path "${package_dir}/${package_key}.info" + set info_file_contents " + + $package_name + $package_name + f + f + + + Peter Marklund + Temporary acs-lang test package + 2003-11-07 + Collaboraid + Temporary test package created by acs-lang test case. + + +" + template::util::write_file $info_file_path $info_file_contents + # Install the test package without catalog files + apm_package_install \ + -enable \ + [apm_package_info_file_path $package_key] + aa_true "Package install: package enabled" \ + [expr [lsearch -exact [apm_enabled_packages] $package_key] != -1] +} +ad_proc -private lang::test::teardown_test_package {} { + apm_package_delete -remove_files=1 [test_package_key] +} + +ad_proc -private lang::test::check_import_result { + {-package_key:required} + {-locale:required} + {-upgrade_array:required} + {-base_array:required} + {-db_array:required} + {-file_array:required} +} { + This proc checks that the properties of messages in the database + are what we expect after a message catalog import or upgrade. + + @author Peter Marklund +} { + upvar $upgrade_array upgrade_expect + upvar $base_array base_messages + upvar $db_array db_messages + upvar $file_array file_messages + + # Check that we have the expected message properties in the database after upgrade + foreach message_key [lsort [array names upgrade_expect]] { + array set expect_property $upgrade_expect($message_key) + switch $expect_property(message) { + db { + set expect_message $db_messages($message_key) + } + file { + set expect_message $file_messages($message_key) + } + base { + set expect_message $base_messages($message_key) + } + } + + array unset message_actual + lang::message::get \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale \ + -array message_actual + + # Check message properties + aa_equals "Import check: $message_key - lang_messages.message" $message_actual(message) $expect_message + aa_equals "Import check: $message_key - lang_messages.deleted_p" $message_actual(deleted_p) $expect_property(deleted_p) + aa_equals "Import check: $message_key - lang_messages.conflict_p" $message_actual(conflict_p) $expect_property(conflict_p) + aa_equals "Import check: $message_key - lang_messages.upgrade_status" \ + $message_actual(upgrade_status) $expect_property(upgrade_status) + if { [string equal $expect_property(sync_time) "not_null"] } { + aa_true "Import check: $message_key - lang_messages.sync_time not null" \ + [expr ![empty_string_p $message_actual(sync_time)]] + } else { + aa_true "Import check: $message_key - lang_messages.sync_time null" \ + [expr [empty_string_p $message_actual(sync_time)]] + } + } +} + +ad_proc -private lang::test::execute_upgrade { + {-locale:required} +} { + Executes the logic of the upgrade test case for a certain locale. + + @author Peter Marklund +} { + set package_key [lang::test::test_package_key] + + # The key numbers correspond to the 14 cases described in the api-doc for lang::catalog::upgrade + array set base_messages { + key01 "Key 1" + key04 "Key 4" + key05 "Key 5" + key06 "Key 6" + key07 "Key 7" + key10 "Key 10" + key11 "Key 11" + key12 "Key 12" + key13 "Key 13 differ" + key14 "Key 14 base" + } + + array set db_messages { + key02 "Key 2" + key06 "Key 6 differ" + key07 "Key 7" + key08 "Key 8" + key09 "Key 9" + key10 "Key 10" + key11 "Key 11 differ" + key12 "Key 12" + key13 "Key 13" + key14 "Key 14 db" + } + + array set file_messages { + key03 "Key 3" + key04 "Key 4 differ" + key05 "Key 5" + key08 "Key 8 differ" + key09 "Key 9" + key10 "Key 10" + key11 "Key 11" + key12 "Key 12 differ" + key13 "Key 13" + key14 "Key 14 file" + } + + # Add the locale to each message so we can tell messages in + # different locales apart + foreach array_name {base_messages db_messages file_messages} { + foreach message_key [array names $array_name] { + append ${array_name}($message_key) " $locale" + } + } + + array set upgrade_expect { + key01 { + message base + deleted_p t + conflict_p f + sync_time not_null + upgrade_status no_upgrade + } + key02 { + message db + deleted_p f + conflict_p f + sync_time null + upgrade_status no_upgrade + } + key03 { + message file + deleted_p f + conflict_p f + sync_time not_null + upgrade_status added + } + key04 { + message file + deleted_p f + conflict_p t + sync_time not_null + upgrade_status added + } + key05 { + message base + deleted_p t + conflict_p f + sync_time null + upgrade_status no_upgrade + } + key06 { + message db + deleted_p t + conflict_p t + sync_time not_null + upgrade_status deleted + } + key07 { + message db + deleted_p t + conflict_p f + sync_time not_null + upgrade_status deleted + } + key08 { + message file + deleted_p f + conflict_p t + sync_time not_null + upgrade_status updated + } + key09 { + message db + deleted_p f + conflict_p f + sync_time not_null + upgrade_status no_upgrade + } + key10 { + message db + deleted_p f + conflict_p f + sync_time not_null + upgrade_status added + } + key11 { + message db + deleted_p f + conflict_p f + sync_time null + upgrade_status no_upgrade + } + key12 { + message file + deleted_p f + conflict_p f + sync_time not_null + upgrade_status updated + } + key13 { + message db + deleted_p f + conflict_p f + sync_time not_null + upgrade_status no_upgrade + } + key14 { + message file + deleted_p f + conflict_p t + sync_time not_null + upgrade_status updated + } + } + + # + # Execution plan: + # + # 1. Import some messages (base_messages below) + # 2. Make changes to DB (db_messages below) + # 3. Make changes to catalog files and import again (file_messages below) + # 4. Check that merged result is what we expect (upgrade_expect below) + # 5. Import again + # 6. Check that we still have the same result (verify idempotent) + # 7. Resolve some conflicts, but not all + # 8. Import again + # 9. Check that we have what's expected then + # + + aa_log "-------------------------------------------------------------------" + aa_log "*** Executing upgrade test with locale $locale" + aa_log "-------------------------------------------------------------------" + + #---------------------------------------------------------------------- + # 1. Import some messages (base_messages) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------1. import some messages----------" + + # Write original catalog file + set catalog_file_path [lang::catalog::get_catalog_file_path \ + -package_key $package_key \ + -locale $locale] + lang::catalog::export_to_file $catalog_file_path [array get base_messages] + aa_true "Initial export: messages exported to file $catalog_file_path" [file exists $catalog_file_path] + + aa_log [template::util::read_file $catalog_file_path] + + # Import the catalog file + array unset message_count + array set message_count [lang::catalog::import -package_key $package_key -locales [list $locale]] + aa_log "Imported messages: [array get message_count]" + + # Check that we have the expected messages in the database + array unset actual_db_messages + array set actual_db_messages [lang::catalog::messages_in_db -package_key $package_key -locale $locale] + foreach message_key [lsort [array names base_messages]] { + aa_equals "Initial import: message for key $message_key in db same as in file" \ + $actual_db_messages($message_key) $base_messages($message_key) + } + + #---------------------------------------------------------------------- + # 2. Make changes to DB (db_messages) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------2. Make changes to DB----------" + + # Carry out changes to the message catalog in the db + foreach message_key [lsort [array names upgrade_expect]] { + + set register_p 0 + if { ![info exists db_messages($message_key)] } { + # Message is not supposed to exist in DB + if { [info exists base_messages($message_key)] } { + # Message currently does exist in DB: Delete + aa_log "Deleting message $message_key" + lang::message::delete \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale + } + } else { + # Message is supposed to exist in DB + # Is it new or changed? + if { ![info exists base_messages($message_key)] || \ + ![string equal $base_messages($message_key) $db_messages($message_key)] } { + # Added || updated + aa_log "Adding/updating message $message_key" + lang::message::register \ + $locale \ + $package_key \ + $message_key \ + $db_messages($message_key) + } + } + } + + #---------------------------------------------------------------------- + # 3. Make changes to catalog files and import again (file_messages) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------3. Make changes to catalog files and do first upgrade----------" + + # Update the catalog file + file delete -force $catalog_file_path + lang::catalog::export_to_file $catalog_file_path [array get file_messages] + aa_true "First upgrade: catalog file $catalog_file_path updated" [file exists $catalog_file_path] + + # Execute a first upgrade + lang::catalog::import -package_key $package_key -locales [list $locale] + + #---------------------------------------------------------------------- + # 4. Check that merged result is what we expect (upgrade_expect) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------4. Check merge result of first upgrade----------" + lang::test::check_import_result \ + -package_key $package_key \ + -locale $locale \ + -upgrade_array upgrade_expect \ + -base_array base_messages \ + -db_array db_messages \ + -file_array file_messages + + #---------------------------------------------------------------------- + # 5. First upgrade (second import) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------5. Second upgrade ----------" + lang::catalog::import -package_key $package_key -locales [list $locale] + + #---------------------------------------------------------------------- + # 6. Check that we still have the same result (verify idempotent) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------6. Check merge results of second upgrade (verify idempotent)----------" + lang::test::check_import_result \ + -package_key $package_key \ + -locale $locale \ + -upgrade_array upgrade_expect \ + -base_array base_messages \ + -db_array db_messages \ + -file_array file_messages + + #---------------------------------------------------------------------- + # 7. Resolve some conflicts, but not all + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------7. Resolve some conflicts, but not all----------" + array set conflict_resolutions { + key06 "key06 resolution message" + key08 "accept" + } + foreach message_key [array names conflict_resolutions] { + if { [string equal $conflict_resolutions($message_key) "accept"] } { + # Resolution is an accept - just toggle conflict_p flag + lang::message::edit $package_key $message_key $locale [list conflict_p f] + + # Set the message to be what's in the database (the accepted message) + set conflict_resolutions($message_key) [lang::message::get_element \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale \ + -element message] + } else { + # Resolution is an edit + lang::message::register \ + $locale \ + $package_key \ + $message_key \ + $conflict_resolutions($message_key) + } + } + + # TODO: test resolution being to retain the message (just toggle conflict_p) + # TODO: test resolution being to delete a resurrected message + # TODO: test other resolution possibilities + + #---------------------------------------------------------------------- + # 8. Third upgrade + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------8. Do third upgrade----------" + lang::catalog::import -package_key $package_key -locales [list $locale] + + #---------------------------------------------------------------------- + # 9. Check that we have what's expected then (resolutions are sticky) + #---------------------------------------------------------------------- + aa_log "locale=$locale ----------9. Check results of third upgrade (that resolutions are sticky)----------" + foreach message_key [array names conflict_resolutions] { + + array unset message_array + lang::message::get \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale \ + -array message_array + + aa_equals "$message_key - conflict message that has been resolved in UI has conflict_p=f" \ + $message_array(conflict_p) "f" + aa_equals "$message_key - the resolved conflict is not clobbered by an additional import" \ + $message_array(message) $conflict_resolutions($message_key) + } +} + aa_register_case util__replace_temporary_tags_with_lookups { Primarily tests lang::util::replace_temporary_tags_with_lookups, Also tests the procs lang::catalog::export_messages_to_file, lang::catalog::parse, @@ -499,3 +932,38 @@ error $saved_error $saved_errorInfo } } + +aa_register_case upgrade { + Test that a package can be upgraded with new + catalog files and that the resulting keys and messages + in the database can then be exported properly. + + What we are testing is a scenario similar to what we have on the OpenACS + Translation server (http://translate.openacs.org). + + @author Peter Marklund +} { + # Create the test package in the file system + lang::test::setup_test_package + + # Can't run this test case with the usual rollback switch since if everthing + # is wrapped in one transaction then the creation_date of the messages will be the + # same and the query in lang::catalog::last_sync_messages will return duplicates. + aa_run_with_teardown \ + -test_code { + + lang::test::execute_upgrade -locale en_US + + lang::system::locale_set_enabled \ + -locale de_DE \ + -enabled_p t + + lang::test::execute_upgrade -locale de_DE + + } -teardown_code { + foreach message_key [array names upgrade_expect] { + lang::message::unregister $package_key $message_key + } + lang::test::teardown_test_package + } +} Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/export-locale-to-files.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/export-locale-to-files.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/export-messages.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/export-messages.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/import-locale-from-files.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.3.2.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/import-locale-from-files.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/import-messages.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/import-messages.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/acs-lang/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/index.adp,v diff -u -r1.14.2.1 -r1.14.2.2 --- openacs-4/packages/acs-lang/www/admin/index.adp 24 Nov 2003 17:15:41 -0000 1.14.2.1 +++ openacs-4/packages/acs-lang/www/admin/index.adp 9 Dec 2003 13:41:52 -0000 1.14.2.2 @@ -2,6 +2,8 @@ @page_title@ @context@ + +

» Toggle translator mode: Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/message-conflict-resolve.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/message-conflicts.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-lang/www/admin/message-conflicts.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/acs-lang/www/admin/message-delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/message-delete.adp,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/acs-lang/www/admin/message-delete.adp 15 Aug 2003 07:50:44 -0000 1.1 +++ openacs-4/packages/acs-lang/www/admin/message-delete.adp 9 Dec 2003 13:41:52 -0000 1.1.2.1 @@ -5,13 +5,10 @@

- Deleting message @package_key@.@message_key@ + Deleting message for key @package_key@.@message_key@ in locale @locale@.

@form_export_vars;noquote@
- - - Index: openacs-4/packages/acs-lang/www/admin/message-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/message-delete.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/acs-lang/www/admin/message-delete.tcl 15 Aug 2003 07:50:44 -0000 1.1 +++ openacs-4/packages/acs-lang/www/admin/message-delete.tcl 9 Dec 2003 13:41:52 -0000 1.1.2.1 @@ -28,32 +28,15 @@ [list "message-list?[export_vars { locale package_key show }]" $package_key] \ $page_title] - -# We check that this request is coming for the system wide default -# locale. If not, we can't allow the creation of a new localized -# message. - -if { ![string equal $current_locale $default_locale] } { - ad_return_error "Can only create messages in the default locale" "Can only create messages in the default locale" - ad_script_abort -} - - set form_export_vars [export_vars -form { locale package_key message_key show {confirm_p 1} }] if { [exists_and_not_null confirm_p] && [template::util::is_true $confirm_p] } { + lang::message::delete \ + -package_key $package_key \ + -message_key $message_key \ + -locale $locale - db_transaction { - - db_dml delete_messages { delete from lang_messages where package_key = :package_key and message_key = :message_key } - - db_dml delete_audit { delete from lang_messages_audit where package_key = :package_key and message_key = :message_key } - - db_dml delete_message_key { delete from lang_message_keys where package_key = :package_key and message_key = :message_key } - - } - ad_returnredirect "message-list?[export_vars { locale package_key show }]" ad_script_abort } Index: openacs-4/packages/acs-lang/www/admin/message-list-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/Attic/message-list-oracle.xql,v diff -u -r1.2 -r1.2.2.1 --- openacs-4/packages/acs-lang/www/admin/message-list-oracle.xql 22 Sep 2003 14:33:40 -0000 1.2 +++ openacs-4/packages/acs-lang/www/admin/message-list-oracle.xql 9 Dec 2003 13:41:52 -0000 1.2.2.1 @@ -21,6 +21,8 @@ and lm2.locale (+) = :locale and lm2.message_key (+) = lmk.message_key and lm2.package_key (+) = lmk.package_key + and (lm2.deleted_p = 'f' or lm2.deleted_p is null) + and lm1.deleted_p = 'f' $where_clause order by upper(lm1.message_key), lm1.message_key Index: openacs-4/packages/acs-lang/www/admin/message-list-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/Attic/message-list-postgresql.xql,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/acs-lang/www/admin/message-list-postgresql.xql 14 Aug 2003 16:06:20 -0000 1.1 +++ openacs-4/packages/acs-lang/www/admin/message-list-postgresql.xql 9 Dec 2003 13:41:52 -0000 1.1.2.1 @@ -17,6 +17,8 @@ and lm1.package_key = :package_key and lm1.message_key = lmk.message_key and lm1.package_key = lmk.package_key + and (lm2.deleted_p = 'f' or lm2.deleted_p is null) + and lm1.deleted_p = 'f' $where_clause order by upper(lm1.message_key), lm1.message_key Index: openacs-4/packages/acs-lang/www/admin/message-list.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/message-list.adp,v diff -u -r1.5 -r1.5.2.1 --- openacs-4/packages/acs-lang/www/admin/message-list.adp 22 Oct 2003 11:34:20 -0000 1.5 +++ openacs-4/packages/acs-lang/www/admin/message-list.adp 9 Dec 2003 13:41:52 -0000 1.5.2.1 @@ -11,6 +11,8 @@

+ +

» Create new message @@ -64,11 +66,11 @@ Not translated - + - + Index: openacs-4/packages/acs-lang/www/admin/message-list.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/message-list.tcl,v diff -u -r1.5 -r1.5.2.1 --- openacs-4/packages/acs-lang/www/admin/message-list.tcl 22 Oct 2003 11:34:20 -0000 1.5 +++ openacs-4/packages/acs-lang/www/admin/message-list.tcl 9 Dec 2003 13:41:52 -0000 1.5.2.1 @@ -35,9 +35,8 @@ -object_id [acs_lookup_magic_object security_context_root] \ -privilege "admin"] -set version_id [apm_version_id_from_package_key $package_key] -set export_messages_url [export_vars -base "/acs-admin/apm/version-i18n-export" { version_id { return_url {[ad_return_url]} } }] -set import_messages_url [export_vars -base "/acs-admin/apm/version-i18n-import" { version_id { return_url {[ad_return_url]} } }] +set export_messages_url [export_vars -base "export-messages" { package_key locale { return_url {[ad_return_url]} } }] +set import_messages_url [export_vars -base "import-messages" { package_key locale { return_url {[ad_return_url]} } }] # We let you create new messages keys if you're in the default locale set create_p [string equal $current_locale $default_locale] Index: openacs-4/packages/acs-lang/www/admin/package-list.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/package-list.adp,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/packages/acs-lang/www/admin/package-list.adp 22 Oct 2003 11:17:50 -0000 1.4 +++ openacs-4/packages/acs-lang/www/admin/package-list.adp 9 Dec 2003 13:41:52 -0000 1.4.2.1 @@ -6,9 +6,11 @@ Search for + +

- » Import all messages for this locale + » Import all messages for this locale

» Export all messages for this locale Index: openacs-4/packages/acs-lang/www/admin/package-list.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-lang/www/admin/package-list.tcl,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/packages/acs-lang/www/admin/package-list.tcl 22 Oct 2003 13:30:31 -0000 1.4 +++ openacs-4/packages/acs-lang/www/admin/package-list.tcl 9 Dec 2003 13:41:52 -0000 1.4.2.1 @@ -114,6 +114,6 @@ } -set import_all_url [export_vars -base import-locale-from-files { { locale $current_locale } }] +set import_all_url [export_vars -base import-messages { { locale $current_locale } }] set export_all_url [export_vars -base export-locale-to-files { { locale $current_locale } }]