<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -29,7 +29,8 @@
         $time_of_queries = 0,
         $nextID = null,
         $logging_transaction = false,
-        $logging_transaction_action = false;
+        $logging_transaction_action = false,
+        $fkeys = array();
 
     function &amp;connect($server = DB_SERVER, $username = DB_SERVER_USERNAME, $password = DB_SERVER_PASSWORD, $database = DB_DATABASE, $port = DB_SERVER_PORT, $type = DB_DATABASE_CLASS) {
       require('database/' . $type . '.php');
@@ -500,81 +501,76 @@
         if ($this-&gt;db_class-&gt;use_foreign_keys == false) {
           $query_action = substr($this-&gt;sql_query, 0, strpos($this-&gt;sql_query, ' '));
 
+          if ( ($query_action == 'delete') || ($query_action == 'update') ) {
+            if ( empty($this-&gt;db_class-&gt;fkeys) ) {
+              $Qfk = new self($this-&gt;db_class);
+              $Qfk-&gt;setQuery('select * from :table_fk_relationships');
+              $Qfk-&gt;bindTable(':table_fk_relationships', TABLE_FK_RELATIONSHIPS);
+//              $Qfk-&gt;setCache('fk_relationships');
+              $Qfk-&gt;execute();
+
+              while ( $Qfk-&gt;next() ) {
+                $this-&gt;db_class-&gt;fkeys[$Qfk-&gt;value('to_table')][] = array('from_table' =&gt; $Qfk-&gt;value('from_table'),
+                                                                          'from_field' =&gt; $Qfk-&gt;value('from_field'),
+                                                                          'to_field' =&gt; $Qfk-&gt;value('to_field'),
+                                                                          'on_update' =&gt; $Qfk-&gt;value('on_update'),
+                                                                          'on_delete' =&gt; $Qfk-&gt;value('on_delete'));
+              }
+
+              $Qfk-&gt;freeResult();
+            }
+          }
+
           if ($query_action == 'delete') {
             $query_data = split(' ', $this-&gt;sql_query, 4);
             $query_table = substr($query_data[2], strlen(DB_TABLE_PREFIX));
 
-            $fk_check_query = $this-&gt;db_class-&gt;simpleQuery('select * from ' . TABLE_FK_RELATIONSHIPS . ' where to_table = &quot;' . $query_table . '&quot;');
-            while ( $fk_check = $this-&gt;db_class-&gt;next($fk_check_query) ) {
-              $parent_query = $this-&gt;db_class-&gt;simpleQuery('select * from ' . $query_data[2] . ' ' . $query_data[3]);
-              while ( $parent_result = $this-&gt;db_class-&gt;next($parent_query) ) {
-                if ( $fk_check['on_delete'] == 'cascade' ) {
-                  $Qdel = new self($this-&gt;db_class);
-                  $Qdel-&gt;setQuery('delete from :from_table where :from_field = :' . $fk_check['from_field']);
-                  $Qdel-&gt;bindTable(':from_table', DB_TABLE_PREFIX . $fk_check['from_table']);
-                  $Qdel-&gt;bindRaw(':from_field', $fk_check['from_field'], false);
-                  $Qdel-&gt;bindValue(':' . $fk_check['from_field'], $parent_result[$fk_check['to_field']]);
-
-                  if ( $this-&gt;logging === true ) {
-                    if ( $this-&gt;db_class-&gt;logging_transaction === false ) {
-                      $this-&gt;db_class-&gt;logging_transaction = true;
-                    }
+            if ( isset($this-&gt;db_class-&gt;fkeys[$query_table]) ) {
+// check for RESTRICT constraints first
+              foreach ( $this-&gt;db_class-&gt;fkeys[$query_table] as $fk ) {
+                if ( $fk['on_delete'] == 'restrict' ) {
+                  $child_query = $this-&gt;db_class-&gt;simpleQuery('select ' . $fk['to_field'] . ' from ' . $query_data[2] . ' ' . $query_data[3]);
+                  while ( $child_result = $this-&gt;db_class-&gt;next($child_query) ) {
+                    $Qcheck = new self($this-&gt;db_class);
+                    $Qcheck-&gt;setQuery('select ' . $fk['from_field'] . ' from ' . DB_TABLE_PREFIX .  $fk['from_table'] . ' where ' . $fk['from_field'] . ' = &quot;' . $child_result[$fk['to_field']] . '&quot; limit 1');
+                    $Qcheck-&gt;execute();
 
-                    $Qdel-&gt;setLogging($this-&gt;logging_module, $this-&gt;logging_module_id);
-                  }
+                    if ( $Qcheck-&gt;numberOfRows() === 1 ) {
+                      $this-&gt;db_class-&gt;setError('RESTRICT constraint condition from table ' . DB_TABLE_PREFIX .  $fk['from_table'], null, $this-&gt;sql_query);
 
-                  $Qdel-&gt;execute();
-                } elseif ( $fk_check['on_delete'] == 'set_null' ) {
-                  $Qupdate = new self($this-&gt;db_class);
-                  $Qupdate-&gt;setQuery('update :from_table set :from_field = :' . $fk_check['from_field'] . ' where :from_field = :' . $fk_check['from_field']);
-                  $Qupdate-&gt;bindTable(':from_table', DB_TABLE_PREFIX . $fk_check['from_table']);
-                  $Qupdate-&gt;bindRaw(':from_field', $fk_check['from_field'], false);
-                  $Qupdate-&gt;bindRaw(':' . $fk_check['from_field'], 'null');
-                  $Qupdate-&gt;bindRaw(':from_field', $fk_check['from_field'], false);
-                  $Qupdate-&gt;bindValue(':' . $fk_check['from_field'], $parent_result[$fk_check['to_field']], false);
-
-                  if ( $this-&gt;logging === true ) {
-                    if ( $this-&gt;db_class-&gt;logging_transaction === false ) {
-                      $this-&gt;db_class-&gt;logging_transaction = true;
+                      return false;
                     }
-
-                    $Qupdate-&gt;setLogging($this-&gt;logging_module, $this-&gt;logging_module_id);
                   }
-
-                  $Qupdate-&gt;execute();
                 }
               }
-            }
-          } elseif ($query_action == 'update') {
-            $query_data = split(' ', $this-&gt;sql_query, 3);
-            $query_table = substr($query_data[1], strlen(DB_TABLE_PREFIX));
 
-            $fk_check_query = $this-&gt;db_class-&gt;simpleQuery('select * from ' . TABLE_FK_RELATIONSHIPS . ' where to_table = &quot;' . $query_table . '&quot;');
-            while ( $fk_check = $this-&gt;db_class-&gt;next($fk_check_query) ) {
-// check to see if foreign key column value is being changed
-              if ( strpos(substr($this-&gt;sql_query, strpos($this-&gt;sql_query, ' set ')+4, strpos($this-&gt;sql_query, ' where ') - strpos($this-&gt;sql_query, ' set ') - 4), ' ' . $fk_check['to_field'] . ' ') !== false ) {
-                $parent_query = $this-&gt;db_class-&gt;simpleQuery('select * from ' . $query_data[1] . substr($this-&gt;sql_query, strrpos($this-&gt;sql_query, ' where ')));
+              foreach ( $this-&gt;db_class-&gt;fkeys[$query_table] as $fk ) {
+                $parent_query = $this-&gt;db_class-&gt;simpleQuery('select * from ' . $query_data[2] . ' ' . $query_data[3]);
                 while ( $parent_result = $this-&gt;db_class-&gt;next($parent_query) ) {
-                  if ( ($fk_check['on_update'] == 'cascade') || ($fk_check['on_update'] == 'set_null') ) {
-                    $on_update_value = '';
+                  if ( $fk['on_delete'] == 'cascade' ) {
+                    $Qdel = new self($this-&gt;db_class);
+                    $Qdel-&gt;setQuery('delete from :from_table where :from_field = :' . $fk['from_field']);
+                    $Qdel-&gt;bindTable(':from_table', DB_TABLE_PREFIX . $fk['from_table']);
+                    $Qdel-&gt;bindRaw(':from_field', $fk['from_field'], false);
+                    $Qdel-&gt;bindValue(':' . $fk['from_field'], $parent_result[$fk['to_field']]);
 
-                    if ( $fk_check['on_update'] == 'cascade' ) {
-                      $on_update_value = $this-&gt;logging_fields[$fk_check['to_field']];
-                    }
+                    if ( $this-&gt;logging === true ) {
+                      if ( $this-&gt;db_class-&gt;logging_transaction === false ) {
+                        $this-&gt;db_class-&gt;logging_transaction = true;
+                      }
 
-                    $Qupdate = new self($this-&gt;db_class);
-                    $Qupdate-&gt;setQuery('update :from_table set :from_field = :' . $fk_check['from_field'] . ' where :from_field = :' . $fk_check['from_field']);
-                    $Qupdate-&gt;bindTable(':from_table', DB_TABLE_PREFIX . $fk_check['from_table']);
-                    $Qupdate-&gt;bindRaw(':from_field', $fk_check['from_field'], false);
-
-                    if ( empty($on_update_value) ) {
-                      $Qupdate-&gt;bindRaw(':' . $fk_check['from_field'], 'null');
-                    } else {
-                      $Qupdate-&gt;bindValue(':' . $fk_check['from_field'], $on_update_value);
+                      $Qdel-&gt;setLogging($this-&gt;logging_module, $this-&gt;logging_module_id);
                     }
 
-                    $Qupdate-&gt;bindRaw(':from_field', $fk_check['from_field'], false);
-                    $Qupdate-&gt;bindValue(':' . $fk_check['from_field'], $parent_result[$fk_check['to_field']], false);
+                    $Qdel-&gt;execute();
+                  } elseif ( $fk['on_delete'] == 'set_null' ) {
+                    $Qupdate = new self($this-&gt;db_class);
+                    $Qupdate-&gt;setQuery('update :from_table set :from_field = :' . $fk['from_field'] . ' where :from_field = :' . $fk['from_field']);
+                    $Qupdate-&gt;bindTable(':from_table', DB_TABLE_PREFIX . $fk['from_table']);
+                    $Qupdate-&gt;bindRaw(':from_field', $fk['from_field'], false);
+                    $Qupdate-&gt;bindRaw(':' . $fk['from_field'], 'null');
+                    $Qupdate-&gt;bindRaw(':from_field', $fk['from_field'], false);
+                    $Qupdate-&gt;bindValue(':' . $fk['from_field'], $parent_result[$fk['to_field']], false);
 
                     if ( $this-&gt;logging === true ) {
                       if ( $this-&gt;db_class-&gt;logging_transaction === false ) {
@@ -589,6 +585,69 @@
                 }
               }
             }
+          } elseif ($query_action == 'update') {
+            $query_data = split(' ', $this-&gt;sql_query, 3);
+            $query_table = substr($query_data[1], strlen(DB_TABLE_PREFIX));
+
+            if ( isset($this-&gt;db_class-&gt;fkeys[$query_table]) ) {
+// check for RESTRICT constraints first
+              foreach ( $this-&gt;db_class-&gt;fkeys[$query_table] as $fk ) {
+                if ( $fk['on_update'] == 'restrict' ) {
+                  $child_query = $this-&gt;db_class-&gt;simpleQuery('select ' . $fk['to_field'] . ' from ' . $query_data[2] . ' ' . $query_data[3]);
+                  while ( $child_result = $this-&gt;db_class-&gt;next($child_query) ) {
+                    $Qcheck = new self($this-&gt;db_class);
+                    $Qcheck-&gt;setQuery('select ' . $fk['from_field'] . ' from ' . DB_TABLE_PREFIX .  $fk['from_table'] . ' where ' . $fk['from_field'] . ' = &quot;' . $child_result[$fk['to_field']] . '&quot; limit 1');
+                    $Qcheck-&gt;execute();
+
+                    if ( $Qcheck-&gt;numberOfRows() === 1 ) {
+                      $this-&gt;db_class-&gt;setError('RESTRICT constraint condition from table ' . DB_TABLE_PREFIX .  $fk['from_table'], null, $this-&gt;sql_query);
+
+                      return false;
+                    }
+                  }
+                }
+              }
+
+              foreach ( $this-&gt;db_class-&gt;fkeys[$query_table] as $fk ) {
+// check to see if foreign key column value is being changed
+                if ( strpos(substr($this-&gt;sql_query, strpos($this-&gt;sql_query, ' set ')+4, strpos($this-&gt;sql_query, ' where ') - strpos($this-&gt;sql_query, ' set ') - 4), ' ' . $fk['to_field'] . ' ') !== false ) {
+                  $parent_query = $this-&gt;db_class-&gt;simpleQuery('select * from ' . $query_data[1] . substr($this-&gt;sql_query, strrpos($this-&gt;sql_query, ' where ')));
+                  while ( $parent_result = $this-&gt;db_class-&gt;next($parent_query) ) {
+                    if ( ($fk['on_update'] == 'cascade') || ($fk['on_update'] == 'set_null') ) {
+                      $on_update_value = '';
+
+                      if ( $fk['on_update'] == 'cascade' ) {
+                        $on_update_value = $this-&gt;logging_fields[$fk['to_field']];
+                      }
+
+                      $Qupdate = new self($this-&gt;db_class);
+                      $Qupdate-&gt;setQuery('update :from_table set :from_field = :' . $fk['from_field'] . ' where :from_field = :' . $fk['from_field']);
+                      $Qupdate-&gt;bindTable(':from_table', DB_TABLE_PREFIX . $fk['from_table']);
+                      $Qupdate-&gt;bindRaw(':from_field', $fk['from_field'], false);
+
+                      if ( empty($on_update_value) ) {
+                        $Qupdate-&gt;bindRaw(':' . $fk['from_field'], 'null');
+                      } else {
+                        $Qupdate-&gt;bindValue(':' . $fk['from_field'], $on_update_value);
+                      }
+
+                      $Qupdate-&gt;bindRaw(':from_field', $fk['from_field'], false);
+                      $Qupdate-&gt;bindValue(':' . $fk['from_field'], $parent_result[$fk['to_field']], false);
+
+                      if ( $this-&gt;logging === true ) {
+                        if ( $this-&gt;db_class-&gt;logging_transaction === false ) {
+                          $this-&gt;db_class-&gt;logging_transaction = true;
+                        }
+
+                        $Qupdate-&gt;setLogging($this-&gt;logging_module, $this-&gt;logging_module_id);
+                      }
+
+                      $Qupdate-&gt;execute();
+                    }
+                  }
+                }
+              }
+            }
           }
         }
 </diff>
      <filename>includes/classes/database.php</filename>
    </modified>
    <modified>
      <diff>@@ -5986,26 +5986,26 @@ INSERT INTO osc_fk_relationships VALUES (null, 'categories_description', 'catego
 INSERT INTO osc_fk_relationships VALUES (null, 'categories_description', 'languages', 'language_id', 'languages_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'configuration', 'configuration_group', 'configuration_group_id', 'configuration_group_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'customers', 'address_book', 'customers_default_address_id', 'address_book_id', 'cascade', 'set_null');
-#INSERT INTO osc_fk_relationships VALUES (null, 'languages', 'currencies', 'currencies_id', 'currencies_id', 'cascade', 'restrict');
+INSERT INTO osc_fk_relationships VALUES (null, 'languages', 'currencies', 'currencies_id', 'currencies_id', 'cascade', 'restrict');
 INSERT INTO osc_fk_relationships VALUES (null, 'languages_definitions', 'languages', 'languages_id', 'languages_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'manufacturers_info', 'manufacturers', 'manufacturers_id', 'manufacturers_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'manufacturers_info', 'languages', 'languages_id', 'languages_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'newsletters_log', 'newsletters', 'newsletters_id', 'newsletters_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders', 'customers', 'customers_id', 'customers_id', 'cascade', 'set_null');
-#INSERT INTO osc_fk_relationships VALUES (null, 'orders', 'orders_status', 'orders_status', 'orders_status_id', 'cascade', 'restrict');
+INSERT INTO osc_fk_relationships VALUES (null, 'orders', 'orders_status', 'orders_status', 'orders_status_id', 'cascade', 'restrict');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_products', 'orders', 'orders_id', 'orders_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_products_download', 'orders', 'orders_id', 'orders_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_products_variants', 'orders', 'orders_id', 'orders_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_status', 'languages', 'language_id', 'languages_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_status_history', 'orders', 'orders_id', 'orders_id', 'cascade', 'cascade');
-#INSERT INTO osc_fk_relationships VALUES (null, 'orders_status_history', 'orders_status', 'orders_status_id', 'orders_status_id', 'cascade', 'restrict');
+INSERT INTO osc_fk_relationships VALUES (null, 'orders_status_history', 'orders_status', 'orders_status_id', 'orders_status_id', 'cascade', 'restrict');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_total', 'orders', 'orders_id', 'orders_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_transactions_history', 'orders', 'orders_id', 'orders_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'orders_transactions_status', 'languages', 'language_id', 'languages_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'product_attributes', 'products', 'products_id', 'products_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'product_attributes', 'languages', 'languages_id', 'languages_id', 'cascade', 'cascade');
 INSERT INTO osc_fk_relationships VALUES (null, 'products', 'products', 'parent_id', 'products_id', 'cascade', 'cascade');
-#INSERT INTO osc_fk_relationships VALUES (null, 'products', 'weight_classes', 'products_weight_class', 'weight_class_id', 'cascade', 'restrict');
+INSERT INTO osc_fk_relationships VALUES (null, 'products', 'weight_classes', 'products_weight_class', 'weight_class_id', 'cascade', 'restrict');
 INSERT INTO osc_fk_relationships VALUES (null, 'products', 'tax_class', 'products_tax_class_id', 'tax_class_id', 'cascade', 'set_null');
 INSERT INTO osc_fk_relationships VALUES (null, 'products', 'manufacturers', 'manufacturers_id', 'manufacturers_id', 'cascade', 'set_null');
 INSERT INTO osc_fk_relationships VALUES (null, 'products_description', 'products', 'products_id', 'products_id', 'cascade', 'cascade');</diff>
      <filename>install/oscommerce.sql</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7c37dfd984dead1abc9b0673341ce7fe5ea4b7b6</id>
    </parent>
  </parents>
  <author>
    <name>Harald Ponce de Leon</name>
    <email>hpdl@oscommerce.com</email>
  </author>
  <url>http://github.com/haraldpdl/oscommerce/commit/57308c5e88eae1e278cdef471397e20129e5ae66</url>
  <id>57308c5e88eae1e278cdef471397e20129e5ae66</id>
  <committed-date>2009-06-18T02:10:08-07:00</committed-date>
  <authored-date>2009-06-18T02:10:08-07:00</authored-date>
  <message>Support RESTRICT foreign key constraints in the database class (for MyISAM databases)</message>
  <tree>65f58710726c222ae3657ddf18257fb4bfd0afe3</tree>
  <committer>
    <name>Harald Ponce de Leon</name>
    <email>hpdl@oscommerce.com</email>
  </committer>
</commit>
