<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>active_table/SqlGenerators/mssql.class.php</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -148,19 +148,6 @@ interface ActiveTable_SQL
     public function addLimit($limit);
     
     /**
-     * Register function to build a one-off LIMIT statement.
-     *
-     * This will construct an appropriate LIMIT statement for your RDBMS and the
-     * number of args you are searching on (ie, AND/WHERE decision in OCI8).
-     *
-     * This is used for findOneBy() to stay DRY.
-     *
-     * @param integer The number of WHERE clauses.
-     * @param integer The number of rows to retrieve. 
-     **/
-    public function buildOneOffLimit($condition_number,$limit_number);
-
-    /**
      * Generate a SQL query to return a slice from a larger result set.
      *
      * @param integer $start The position to begin the slice at. Start at 0, not 1.
@@ -169,11 +156,18 @@ interface ActiveTable_SQL
     public function setSlice($start,$end);
 
     /**
-     * Get the escape character used around a reserved word. 
+     * Get the escape character used on the left side of a reserved word. 
+     * 
+     * @return string 
+     **/
+    public function getReservedWordEscapeCharacterLeft();
+
+    /**
+     * Get the escape character used on the right side of a reserved word. 
      * 
      * @return string 
      **/
-    public function getReservedWordEscapeCharacter();
+    public function getReservedWordEscapeCharacterRight();
 
 } // end ActiveTable_SQL
 ?&gt;</diff>
      <filename>active_table/SqlGenerators/interface.inc.php</filename>
    </modified>
    <modified>
      <diff>@@ -297,11 +297,6 @@ class ActiveTable_SQL_MySQL implements ActiveTable_SQL
         return &quot;SELECT last_insert_id() AS last_insert_id&quot;;
     } // end getLastInsertId
 
-    public function buildOneOffLimit($condition_number,$limit_number)
-    {
-        return &quot;LIMIT $limit_number\n&quot;;
-    } // end buildOneOffLimit
-    
     public function setSlice($start,$end)
     {
         if($this-&gt;limit != null)
@@ -313,11 +308,15 @@ class ActiveTable_SQL_MySQL implements ActiveTable_SQL
         $this-&gt;limit = &quot;$start,$total&quot;;
     } // end setSlice
 
-    public function getReservedWordEscapeCharacter()
+    public function getReservedWordEscapeCharacterLeft()
     {
         return '`';
-    } // end getReservedWordEscapeCharacter
+    } // end getReservedWordEscapeCharacterLeft
 
+    public function getReservedWordEscapeCharacterRight()
+    {
+        return $this-&gt;getReservedWordEscapeCharacterLeft();
+    }
 } // end ActiveTable_MySQL_SQL
 
 ?&gt;</diff>
      <filename>active_table/SqlGenerators/mysql.class.php</filename>
    </modified>
    <modified>
      <diff>@@ -309,16 +309,6 @@ class ActiveTable_SQL_Oracle implements ActiveTable_SQL
         return &quot;SELECT ROWIDTOCHAR(MAX(rowid)) FROM $table&quot;;
     } // end getLastInsertId
 
-    public function buildOneOffLimit($condition_number,$limit_number)
-    {
-        if($condition_number == 0)
-        {
-            return &quot;WHERE rownum &gt;= $limit_number\n&quot;;
-        }
-        
-        return &quot;AND rownum &gt;= $limit_number\n&quot;;
-    } // end buildOneOffLimit
-
     public function setSlice($start,$end)
     {
         $this-&gt;get_slice = true;
@@ -326,12 +316,15 @@ class ActiveTable_SQL_Oracle implements ActiveTable_SQL
         $this-&gt;slice_end = $end;
     } // end setSlice
 
-    public function getReservedWordEscapeCharacter()
+    public function getReservedWordEscapeCharacterLeft()
     {
-        // TODO. I think ' works, but I need to test that.
-        return '';
-    } // end getReservedWordEscapeCharacter
+        return &quot;&quot;;
+    } // end getReservedWordEscapeCharacterLeft
 
+    public function getReservedWordEscapeCharacterRight()
+    {
+        return $this-&gt;getReservedWordEscapeCharacterLeft();
+    }
 } // end ActiveTable_Oracle_SQL
 
 ?&gt;</diff>
      <filename>active_table/SqlGenerators/oci.class.php</filename>
    </modified>
    <modified>
      <diff>@@ -305,11 +305,6 @@ class ActiveTable_SQL_PgSQL implements ActiveTable_SQL
         return &quot;SELECT lastval() AS last_insert_id&quot;;
     } // end getLastInsertId
 
-    public function buildOneOffLimit($condition_number,$limit_number)
-    {
-        return &quot;LIMIT $limit_number\n&quot;;
-    } // end buildOneOffLimit
-    
     public function setSlice($start,$end)
     {
         if($this-&gt;limit != null)
@@ -322,11 +317,15 @@ class ActiveTable_SQL_PgSQL implements ActiveTable_SQL
         $this-&gt;offset = $start;
     } // end setSlice
 
-    public function getReservedWordEscapeCharacter()
+    public function getReservedWordEscapeCharacterLeft()
     {
         return '&quot;';
-    } // end getReservedWordEscapeCharacter
+    } // end getReservedWordEscapeCharacterLeft
 
+    public function getReservedWordEscapeCharacterRight()
+    {
+        return $this-&gt;getReservedWordEscapeCharacterLeft();
+    }
 } // end ActiveTable_PgSQL_SQL
 
 ?&gt;</diff>
      <filename>active_table/SqlGenerators/pgsql.class.php</filename>
    </modified>
    <modified>
      <diff>@@ -15,6 +15,7 @@ require_once('SqlGenerators/interface.inc.php');
 require_once('SqlGenerators/mysql.class.php');
 require_once('SqlGenerators/oci.class.php');
 require_once('SqlGenerators/pgsql.class.php');
+require_once('SqlGenerators/mssql.class.php');
 
 /**
  * Table definition cacher libraries. 
@@ -331,6 +332,13 @@ abstract class ActiveTable
                 break;
             } // end oci8
 
+            case 'mssql':
+            {
+                $this-&gt;sql_generator = 'ActiveTable_SQL_MSSQL';
+
+                break;
+            } // end mssql
+
             default:
             {
                 throw new ArgumentError('Unsupported RDBMS specified in phptype.',20);
@@ -466,7 +474,7 @@ abstract class ActiveTable
             {
                 throw new ArgumentError(&quot;Local key not defined in record set $record_set_name.&quot;,912);
             }
-            
+
             // Intialize the ID list.
             $this-&gt;RELATED_IDS[$record_set_name] = array();
         } // end related set validation
@@ -1179,8 +1187,6 @@ abstract class ActiveTable
      */
     public function findOneBy($ARGS,$order_by='')
     {
-        // $sql_generator = $this-&gt;newSqlGenerator();
-        // $limit = $sql_generator-&gt;buildOneOffLimit(sizeof($ARGS),1);
         $result = $this-&gt;findBy($ARGS,$order_by,false,0,1);
         $result = array_shift($result);
 
@@ -1388,13 +1394,16 @@ abstract class ActiveTable
         // PEAR::DB's autoExecute facility doesn't concern itself with escaping reserved words.
         // It would be a large architectural change to fix that, so I'll just work around it in
         // here instead of fixing it there and trying to get a patch pushed through.
-        $escape_char = $this-&gt;newSqlGenerator()-&gt;getReservedWordEscapeCharacter();
+        //
+        // Also, there is a left/right because SQL Server uses [ and ]. :-|
+        $escape_char_left = $this-&gt;newSqlGenerator()-&gt;getReservedWordEscapeCharacterLeft();
+        $escape_char_right = $this-&gt;newSqlGenerator()-&gt;getReservedWordEscapeCharacterRight();
 
         // Oracle users need db.table.
-        $table_name = &quot;{$escape_char}{$this-&gt;table_name}{$escape_char}&quot;;
+        $table_name = &quot;{$escape_char_left}{$this-&gt;table_name}{$escape_char_right}&quot;;
         if($this-&gt;database != '')
         {
-            $table_name = &quot;{$escape_char}{$this-&gt;database}{$escape_char}.{$escape_char}{$this-&gt;table_name}{$escape_char}&quot;;
+            $table_name = &quot;{$escape_char_left}{$this-&gt;database}{$escape_char_right}.{$escape_char_left}{$this-&gt;table_name}{$escape_char_right}&quot;;
         }
         
         if($this-&gt;allow_pk_write == false)
@@ -1412,9 +1421,9 @@ abstract class ActiveTable
                 $value = '';
             }
             
-            if($escape_char != '')
+            if($escape_char_left != '')
             {
-                $DATA[&quot;{$escape_char}$key{$escape_char}&quot;] = $value;
+                $DATA[&quot;{$escape_char_left}$key{$escape_char_right}&quot;] = $value;
                 unset($DATA[$key]);
             }
         } // end loop
@@ -1424,7 +1433,7 @@ abstract class ActiveTable
         {
             unset($DATA[strtolower($this-&gt;newSqlGenerator()-&gt;getMagicPkName())]);
             
-            $quoted_key = $escape_char.$DATA[strtolower($this-&gt;newSqlGenerator()-&gt;getMagicPkName())].$escape_char;
+            $quoted_key = $escape_char_left.$DATA[strtolower($this-&gt;newSqlGenerator()-&gt;getMagicPkName())].$escape_char_right;
             unset($quoted_key);
         } // end has magic PK
        
@@ -1436,7 +1445,8 @@ abstract class ActiveTable
             {
                 throw new SQLError($resource-&gt;getDebugInfo(),$resource-&gt;userinfo,907);
             }
-
+            
+            // TODO broken for oracle is PK isn't ROWID
             $id = $this-&gt;db-&gt;getOne($this-&gt;newSqlGenerator()-&gt;getLastInsertId($table_name));
             
             if(PEAR::isError($id))
@@ -1641,18 +1651,29 @@ abstract class ActiveTable
             $table = $this-&gt;table_name;
         }
 
-        $CACHE = $this-&gt;cacher-&gt;loadTable($table,$database_schema_name);
+        $RESULT = array(); // Structure
+
+        // If this is the primary table and the DB supports magic PKs, include it in the describe.
+        // Should be in position zero (cx_0).
+        // 
+        // This is done before figuring out if the table is cached. If this is cached by another describe from a different
+        // class that has the table as a JOIN, it will not include the magic PK (since we don't care about a lookup table's PK).
+        $sql_generator = $this-&gt;newSqlGenerator(); 
+        if($sql_generator-&gt;getMagicPkName() != null &amp;&amp; strtolower($table) == strtolower($this-&gt;table_name))
+        {
+            $RESULT[strtolower($sql_generator-&gt;getMagicPkName())] = null;
+        } // end add rowid
 
+        $CACHE = $this-&gt;cacher-&gt;loadTable($table,$database_schema_name);
         if(is_array($CACHE) == true)
         {
             $this-&gt;debug(&quot;Cached structure found for $table.&quot;,'cache');
-            $RESULT = $CACHE;
+            $RESULT = array_merge($RESULT,$CACHE);
         }
         else
         {
             $this-&gt;debug(&quot;Cached structure not found for $table; describing...&quot;,'cache');
 
-            $sql_generator = $this-&gt;newSqlGenerator(); 
             $sql = $sql_generator-&gt;getDescribeTable($table,$database);
 
             $resource = $this-&gt;db-&gt;query($sql);
@@ -1663,15 +1684,6 @@ abstract class ActiveTable
                 throw new SQLError($resource-&gt;getDebugInfo(),$resource-&gt;userinfo,905);
             }
             
-            $RESULT = array();
-            
-            // If this is the primary table and the DB supports magic PKs, include it in the describe.
-            // Should be in position zero (cx_0).
-            if($sql_generator-&gt;getMagicPkName() != null &amp;&amp; $table == $this-&gt;table_name)
-            {
-                $RESULT[strtolower($sql_generator-&gt;getMagicPkName())] = null;
-            } // end add rowid
-            
             while($resource-&gt;fetchInto($ROW))
             {
                 // Normalize into all lower case (I'm lookin at you, Oracle...)</diff>
      <filename>active_table/active_table.class.php</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>ad97365fdc2c9897eecae8f9da4ac8153a286b27</id>
    </parent>
  </parents>
  <author>
    <name>Nicholas 'OwlManAtt' Evans</name>
    <email>owlmanatt@gmail.com</email>
  </author>
  <url>http://github.com/OwlManAtt/activephp/commit/914d5a3978b30485208b5d264653b40f4284e203</url>
  <id>914d5a3978b30485208b5d264653b40f4284e203</id>
  <committed-date>2009-07-04T23:55:52-07:00</committed-date>
  <authored-date>2009-07-04T23:55:52-07:00</authored-date>
  <message>MS SQL support added.

MS SQL support is beta-quality. Only read-only operations have been tested,
and I don't plan on testing RW operations myself ever (I don't have an MS SQL
server to play with).

The generator interface was changed to support MS SQL's ... unique way of
quoting database objects...square brackets.</message>
  <tree>a59738a66d46d2aabc65775a71019680731cd8e0</tree>
  <committer>
    <name>Nicholas 'OwlManAtt' Evans</name>
    <email>owlmanatt@gmail.com</email>
  </committer>
</commit>
