Index: branches/RC/core/install/install_schema.sql
===================================================================
diff -u -r11870 -r11933
--- branches/RC/core/install/install_schema.sql (.../install_schema.sql) (revision 11870)
+++ branches/RC/core/install/install_schema.sql (.../install_schema.sql) (revision 11933)
@@ -1088,4 +1088,15 @@
Title VARCHAR(255) NOT NULL DEFAULT '',
Description text,
PRIMARY KEY (FormId)
+);
+
+CREATE TABLE Semaphores (
+ SemaphoreId int(11) NOT NULL auto_increment,
+ SessionKey int(10) unsigned NOT NULL,
+ Timestamp int(10) unsigned NOT NULL,
+ MainPrefix varchar(255) NOT NULL,
+ PRIMARY KEY (SemaphoreId),
+ KEY SessionKey (SessionKey),
+ KEY Timestamp (Timestamp),
+ KEY MainPrefix (MainPrefix)
);
\ No newline at end of file
Index: branches/RC/core/install/remove_schema.sql
===================================================================
diff -u -r11623 -r11933
--- branches/RC/core/install/remove_schema.sql (.../remove_schema.sql) (revision 11623)
+++ branches/RC/core/install/remove_schema.sql (.../remove_schema.sql) (revision 11933)
@@ -67,4 +67,5 @@
DROP TABLE PageContent;
DROP TABLE FormFields;
DROP TABLE FormSubmissions;
-DROP TABLE Forms;
\ No newline at end of file
+DROP TABLE Forms;
+DROP TABLE Semaphores;
Index: branches/RC/core/install/upgrades.sql
===================================================================
diff -u -r11931 -r11933
--- branches/RC/core/install/upgrades.sql (.../upgrades.sql) (revision 11931)
+++ branches/RC/core/install/upgrades.sql (.../upgrades.sql) (revision 11933)
@@ -1319,6 +1319,17 @@
INSERT INTO ConfigurationAdmin VALUES ('DebugOnlyFormConfigurator', 'la_section_SettingsAdmin', 'la_config_DebugOnlyFormConfigurator', 'checkbox', '', '', 40.09, 0, 0);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'DebugOnlyFormConfigurator', '0', 'In-Portal', 'in-portal:configure_advanced');
+CREATE TABLE Semaphores (
+ SemaphoreId int(11) NOT NULL auto_increment,
+ SessionKey int(10) unsigned NOT NULL,
+ Timestamp int(10) unsigned NOT NULL,
+ MainPrefix varchar(255) NOT NULL,
+ PRIMARY KEY (SemaphoreId),
+ KEY SessionKey (SessionKey),
+ KEY Timestamp (Timestamp),
+ KEY MainPrefix (MainPrefix)
+);
+
ALTER TABLE Language ADD IconDisabledURL VARCHAR(255) NULL DEFAULT NULL AFTER IconURL;
UPDATE Phrase
Index: branches/RC/core/kernel/db/db_event_handler.php
===================================================================
diff -u -r11930 -r11933
--- branches/RC/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 11930)
+++ branches/RC/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 11933)
@@ -1,6 +1,6 @@
Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$live_ids = $temp->SaveEdit($event->getEventParam('master_ids') ? $event->getEventParam('master_ids') : Array());
+ if ($live_ids === false) {
+ // coping from table failed, because we have another coping process to same table, that wasn't finished
+ $event->status = erFAIL;
+ return ;
+ }
// Deleteing files scheduled for delete
$var_name = $event->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
Index: branches/RC/core/kernel/utility/temp_handler.php
===================================================================
diff -u -r11923 -r11933
--- branches/RC/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 11923)
+++ branches/RC/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 11933)
@@ -1,6 +1,6 @@
savedIDs[ $master['Prefix'] ];
}
+ /**
+ * Create separate connection for locking purposes
+ *
+ * @return kDBConnection
+ */
+ function &_getSeparateConnection()
+ {
+ static $connection = null;
+
+ if (!isset($connection)) {
+ $connection = new kDBConnection(SQL_TYPE, Array(&$this->Application, 'handleSQLError') );
+ $connection->debugMode = $this->Application->isDebugMode();
+ $connection->Connect(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB, true);
+ }
+
+ return $connection;
+ }
+
function UpdateChangeLogForeignKeys($master, $live_id, $temp_id)
{
$main_prefix = $this->Application->GetTopmostPrefix($master['Prefix']);
@@ -766,7 +784,60 @@
function SaveEdit($master_ids = Array())
{
- return $this->DoCopyTempToOriginal($this->Tables, null, $master_ids);
+ // SessionKey field is required for deleting records from expired sessions
+ $conn =& $this->_getSeparateConnection();
+
+ $sleep_count = 0;
+ do {
+ // aquire lock
+ $conn->ChangeQuery('LOCK TABLES '.TABLE_PREFIX.'Semaphores WRITE');
+
+ $sql = 'SELECT SessionKey
+ FROM ' . TABLE_PREFIX . 'Semaphores
+ WHERE (MainPrefix = ' . $conn->qstr($this->Tables['Prefix']) . ')';
+ $another_coping_active = $conn->GetOne($sql);
+
+ if ($another_coping_active) {
+ // another user is coping data from temp table to live -> release lock and try again after 1 second
+ $conn->ChangeQuery('UNLOCK TABLES');
+ $sleep_count++;
+ sleep(1);
+ }
+ } while ($another_coping_active && ($sleep_count <= 30));
+
+ if ($sleep_count > 30) {
+ // another coping process failed to finished in 30 seconds
+ $error_message = $this->Application->Phrase('la_error_TemporaryTableCopingFailed');
+ $this->Application->SetVar('_temp_table_message', $error_message);
+
+ return false;
+ }
+
+ // mark, that we are coping from temp to live right now, so other similar attempt (from another script) will fail
+ $fields_hash = Array (
+ 'SessionKey' => $this->Application->GetSID(),
+ 'Timestamp' => adodb_mktime(),
+ 'MainPrefix' => $this->Tables['Prefix'],
+ );
+
+ $conn->doInsert($fields_hash, TABLE_PREFIX.'Semaphores');
+ $semaphore_id = $conn->getInsertID();
+
+ // unlock table now to prevent permanent lock in case, when coping will end with SQL error in the middle
+ $conn->ChangeQuery('UNLOCK TABLES');
+
+ $ids = $this->DoCopyTempToOriginal($this->Tables, null, $master_ids);
+
+ // remove mark, that we are coping from temp to live
+ $conn->Query('LOCK TABLES '.TABLE_PREFIX.'Semaphores WRITE');
+
+ $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Semaphores
+ WHERE SemaphoreId = ' . $semaphore_id;
+ $conn->ChangeQuery($sql);
+
+ $conn->ChangeQuery('UNLOCK TABLES');
+
+ return $ids;
}
function CancelEdit($master=null)
Index: branches/RC/core/admin_templates/incs/footer.tpl
===================================================================
diff -u -r11661 -r11933
--- branches/RC/core/admin_templates/incs/footer.tpl (.../footer.tpl) (revision 11661)
+++ branches/RC/core/admin_templates/incs/footer.tpl (.../footer.tpl) (revision 11933)
@@ -38,6 +38,14 @@
InitEditors();
+
+
+ addLoadEvent(
+ function() {
+ alert('');
+ }
+ );
+