Index: contrib/sessions/middleware.py
===================================================================
--- contrib/sessions/middleware.py	(revision 5596)
+++ contrib/sessions/middleware.py	(working copy)
@@ -59,8 +59,11 @@
                 self._session_cache = {}
             else:
                 try:
+                    datenow = datetime.datetime.now()
+                    if hasattr(datenow, 'microsecond'):
+                        datenow = datenow.replace(microsecond=0)
                     s = Session.objects.get(session_key=self.session_key,
-                        expire_date__gt=datetime.datetime.now())
+                        expire_date__gt=datenow)
                     self._session_cache = s.get_decoded()
                 except (Session.DoesNotExist, SuspiciousOperation):
                     self._session_cache = {}
Index: db/backends/mssql/base.py
===================================================================
--- db/backends/mssql/base.py	(revision 0)
+++ db/backends/mssql/base.py	(revision 0)
@@ -0,0 +1,232 @@
+"""
+Alpha Multi-plataform MSSQL database backend for Django.
+
+Requires pymssql >= v0.8.0: http://pymssql.sourceforge.net/
+"""
+if __name__ == '__main__':
+    import sys
+    import os
+    
+    SETTINGS_MODULE = 'settings'
+
+    project_dir = r'E:\Proyectos\Python\mysite'
+    sys.path.append(os.path.join(project_dir, '..'))
+    sys.path.append("..")
+    sys.path.pop()
+    os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
+    
+
+import datetime
+from django.db.backends import util
+from django.core.exceptions import ImproperlyConfigured
+
+try:
+    import pymssql as Database
+except ImportError, e:
+    raise ImproperlyConfigured, "Error loading pymssql module: %s" % e
+
+try:
+    import mx
+except ImportError:
+    mx = None
+
+try:
+    # Only exists in Python 2.4+
+    from threading import local
+except ImportError:
+    # Import copy of _thread_local.py from Python 2.4
+    from django.utils._threading_local import local
+
+DatabaseError = Database.DatabaseError
+IntegrityError = Database.IntegrityError
+
+#Configure support options:
+allows_group_by_ordinal = True
+allows_unique_and_pk = True
+autoindexes_primary_keys = True
+needs_datetime_string_cast = True
+needs_upper_for_iops = False
+supports_constraints = True
+supports_tablespaces = False
+uses_case_insensitive_names = False
+
+def complain(*args, **kwargs):
+    raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet."
+
+def ignore(*args, **kwargs):
+    pass
+
+class DatabaseError(Exception):
+    pass
+
+class IntegrityError(DatabaseError):
+    pass
+
+class DatabaseWrapper(local):
+    def __init__(self, **kwargs):
+        self.connection = None
+        self.queries = []
+
+    def cursor(self):
+        from django.conf import settings
+        if self.connection is None:
+            if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
+                raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file."
+            if not settings.DATABASE_HOST:
+                settings.DATABASE_HOST = "127.0.0.1"
+            # TODO: Handle DATABASE_PORT.
+            self.connection = Database.connect(host=settings.DATABASE_HOST,user=settings.DATABASE_USER,password=settings.DATABASE_PASSWORD,database=settings.DATABASE_NAME)
+        
+        self.connection.cursor().execute("SET DATEFORMAT ymd\nGO")
+        
+        cursor = self.connection.cursor()
+        if settings.DEBUG:
+            return util.CursorDebugWrapper(cursor, self)
+        return cursor
+
+    def _commit(self):
+        if self.connection is not None:
+            return self.connection.commit()
+
+    def _rollback(self):
+        if self.connection is not None:
+            return self.connection.rollback()
+
+    def close(self):
+        if self.connection is not None:
+            self.connection.close()
+            self.connection = None
+
+'''
+    Return the major version of the server. 7=Sql 7,8=Sql2000,9=Sql2005
+'''
+def version():
+    cur = DatabaseWrapper().cursor()
+    cur.execute("SELECT SERVERPROPERTY('ProductVersion')")
+    
+    return int(cur.fetchone()[0].split('.')[0])
+
+def quote_name(name):
+    if name.startswith('[') and name.endswith(']'):
+        return name # Quoting once is enough.
+    return '[%s]' % name
+
+dictfetchone = util.dictfetchone
+dictfetchmany = util.dictfetchmany
+dictfetchall  = util.dictfetchall
+
+def get_last_insert_id(cursor, table_name, pk_name):
+    cursor.execute("SELECT %s FROM %s WHERE %s = IDENT_CURRENT('%s')" % (pk_name, table_name, pk_name,table_name)) 
+    return cursor.fetchone()[0]
+
+def get_date_extract_sql(lookup_type, table_name):
+    # lookup_type is 'year', 'month', 'day'
+    return "DATEPART(%s, %s)" % (lookup_type, table_name)
+
+def get_date_trunc_sql(lookup_type, field_name):
+    # lookup_type is 'year', 'month', 'day'
+    if lookup_type=='year':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name
+    if lookup_type=='month':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name)
+    if lookup_type=='day':
+        return "Convert(datetime, Convert(varchar(12), %s))" % field_name
+
+def get_datetime_cast_sql():
+    return None
+
+def get_limit_offset_sql(limit, offset=None):
+    # Limits and offset are too complicated to be handled here.
+    # Look for a implementation similar to oracle backend
+    return ""
+
+def get_random_function_sql():
+    return "RAND()"
+
+def get_deferrable_sql():
+    # TODO: Workaround cicle paths...
+    # DEFERRABLE and INITALLY DEFFERRED are not apparently supported on constraints
+    # This cause SQL Server message 1750, severity 16, state 0, for example in the multiple joins path of comments.
+    # So, this left Sql Server as if have not relations :(
+    #return " ON DELETE CASCADE ON UPDATE CASCADE"
+    return "" 
+
+def get_fulltext_search_sql(field_name):
+    raise NotImplementedError
+
+def get_drop_foreignkey_sql():
+    return "DROP CONSTRAINT"
+
+def get_pk_default_value():
+    return "DEFAULT"
+
+def get_max_name_length():
+    return None
+
+def get_start_transaction_sql():
+    return "BEGIN;"
+
+def get_tablespace_sql(tablespace, inline=False):
+    return "ON %s" % quote_name(tablespace)
+
+def get_autoinc_sql(table):
+    return None
+
+def get_sql_flush(sql_styler, full_table_list, sequences): 
+    """Return a list of SQL statements required to remove all data from
+    all tables in the database (without actually removing the tables
+    themselves) and put the database in an empty 'initial' state
+    """
+    # Cannot use TRUNCATE on tables that are reference by a FOREIGN KEY
+    # So must use the much slower DELETE
+    sql_list = ['%s %s %s;' % \
+                (sql_styler.SQL_KEYWORD('DELETE'),
+                sql_styler.SQL_KEYWORD('FROM'),
+                sql_styler.SQL_FIELD(quote_name(table))
+                )  for table in full_table_list]
+    #The reset the counters on each table.
+    sql_list.extend(['%s %s %s %s %s %s %s;' % (
+        sql_styler.SQL_KEYWORD('DBCC'),
+        sql_styler.SQL_KEYWORD('CHECKIDENT'),
+        sql_styler.SQL_FIELD(quote_name(seq["table"])),
+        sql_styler.SQL_KEYWORD('RESEED'),
+        sql_styler.SQL_FIELD('1'),
+        sql_styler.SQL_KEYWORD('WITH'),
+        sql_styler.SQL_KEYWORD('NO_INFOMSGS'),
+        ) for seq in sequences])
+    
+    return sql_list 
+
+def get_sql_sequence_reset(style, model_list):
+    "Returns a list of the SQL statements to reset sequences for the given models."
+    # No sequence reset required
+    return []
+
+OPERATOR_MAPPING = {
+    'exact': '= %s',
+    'iexact': 'LIKE %s',
+    'contains': 'LIKE %s',
+    'icontains': 'LIKE %s',
+    'gt': '> %s',
+    'gte': '>= %s',
+    'lt': '< %s',
+    'lte': '<= %s',
+    'startswith': 'LIKE %s',
+    'endswith': 'LIKE %s',
+    'istartswith': 'LIKE %s',
+    'iendswith': 'LIKE %s',
+}
+
+if __name__ == '__main__':
+    from mysite.polls.models import Poll, Choice
+    from django.contrib.auth.models import User
+    from datetime import datetime
+    Poll.objects.all()
+    p = Poll(question="What's up?", pub_date=datetime.now())
+    p.save()
+    print p.id
+    
+    db=DatabaseWrapper()
+    print version()
+
+
Index: db/backends/mssql/client.py
===================================================================
--- db/backends/mssql/client.py	(revision 0)
+++ db/backends/mssql/client.py	(revision 0)
@@ -0,0 +1,2 @@
+def runshell():
+    raise NotImplementedError
Index: db/backends/mssql/__init__.py
===================================================================
Index: db/backends/mssql/introspection.py
===================================================================
--- db/backends/mssql/introspection.py	(revision 0)
+++ db/backends/mssql/introspection.py	(revision 0)
@@ -0,0 +1,137 @@
+def get_table_list(cursor):
+    "Returns a list of table names in the current database."
+    cursor.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'")
+    return [row[2] for row in cursor.fetchall()]
+
+def _is_auto_field(cursor, table_name, column_name):
+    cursor.execute("SELECT COLUMNPROPERTY( OBJECT_ID('%s'),'%s','IsIdentity')" % (table_name, column_name))
+    return cursor.fetchall()[0][0]
+
+def get_table_description(cursor, table_name, identity_check=True):
+    """Returns a description of the table, with the DB-API cursor.description interface.
+
+    The 'auto_check' parameter has been added to the function argspec.
+    If set to True, the function will check each of the table's fields for the
+    IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField).
+
+    When a field is found with an IDENTITY property, it is given a custom field number
+    of -777, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict.
+    """    
+    cursor.execute("SELECT TOP 1 * FROM %s" % table_name)
+    cursor.nextset()
+    items = []
+    if identity_check:
+        for data in cursor.description:
+            if _is_auto_field(cursor, table_name, data[0]):
+                data = list(data)
+                data[1] = -777
+            items.append(list(data))
+    else:
+        items = cursor.description
+    return items
+
+def _name_to_index(cursor, table_name):
+    """
+    Returns a dictionary of {field_name: field_index} for the given table.
+    Indexes are 0-based.
+    """
+    return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name, identity_check=False))])
+
+def get_relations(cursor, table_name):
+    """
+    Returns a dictionary of {field_index: (field_index_other_table, other_table)}
+    representing all relationships to the given table. Indexes are 0-based.    
+    """
+    table_index = _name_to_index(cursor, table_name)
+    sql = """SELECT e.COLUMN_NAME AS column_name,
+                    c.TABLE_NAME AS referenced_table_name,
+                    d.COLUMN_NAME AS referenced_column_name
+                    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a
+                        INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS b
+                              ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
+                        INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE AS c
+                              ON b.UNIQUE_CONSTRAINT_NAME = c.CONSTRAINT_NAME
+                        INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS d
+                              ON c.CONSTRAINT_NAME = d.CONSTRAINT_NAME
+                        INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS e
+                              ON a.CONSTRAINT_NAME = e.CONSTRAINT_NAME
+                    WHERE a.TABLE_NAME = ? AND
+                          a.CONSTRAINT_TYPE = 'FOREIGN KEY'"""
+    cursor = Cursor(cursor.db.connection)
+    cursor.execute(sql, (table_name,))
+    return dict([(table_index[item[0]], (_name_to_index(cursor, item[1])[item[2]], item[1]))
+                  for item in cursor.fetchall()])
+    
+def get_indexes(cursor, table_name):
+    """
+    Returns a dictionary of fieldname -> infodict for the given table,
+    where each infodict is in the format:
+        {'primary_key': boolean representing whether it's the primary key,
+         'unique': boolean representing whether it's a unique index}
+    """
+    sql = """SELECT b.COLUMN_NAME, a.CONSTRAINT_TYPE
+               FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a INNER JOIN
+                    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS b
+                    ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME AND
+                       a.TABLE_NAME = b.TABLE_NAME
+               WHERE a.TABLE_NAME = ? AND
+                     (CONSTRAINT_TYPE = 'PRIMARY KEY' OR
+                      CONSTRAINT_TYPE = 'UNIQUE')"""
+    field_names = [item[0] for item in get_table_description(cursor, table_name, identity_check=False)]
+    cursor = Cursor(cursor.db.connection)
+    cursor.execute(sql, (table_name,))
+    indexes = {}
+    results = {}
+    data = cursor.fetchall()
+    if data:
+        results.update(data)
+    for field in field_names:
+        val = results.get(field, None)
+        indexes[field] = dict(primary_key=(val=='PRIMARY KEY'), unique=(val=='UNIQUE'))
+    return indexes
+
+# A reference for the values below:
+# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdcstdatatypeenum.asp
+DATA_TYPES_REVERSE = {
+# 8192 : Array ,
+# 128 : Binary ,
+# 9 : IDispatch ,
+# 12 : Variant ,
+# 13 : IUnknown ,
+# 21  : UnsignedBigInt,
+# 132 : UserDefined ,
+# 0   : Empty ,
+# 136 : Chapter ,
+# 138 : PropVariant ,
+# 204 : VarBinary ,
+# 205 : LongVarBinary ,
+-777: 'AutoField',                  # Custom number used to identify AutoFields
+2   : 'SmallIntegerField',          # SmallInt
+3   : 'IntegerField',               # Integer
+4   : 'FloatField',                 # Single
+5   : 'FloatField',                 # Decimal
+6   : 'FloatField',                 # Currency
+7   : 'DateField',                  # Date
+8   : 'CharField',                  # BSTR
+10  : 'IntegerField',               # Error
+11  : 'BooleanField',               # Boolean
+14  : 'FloatField',                 # Decimal
+16  : 'SmallIntegerField',          # TinyInt
+17  : 'PositiveSmallIntegerField',  # UnsignedTinyInt
+18  : 'PositiveSmallIntegerField',  # UnsignedSmallInt
+19  : 'PositiveIntegerField',       # UnsignedInt
+20  : 'IntegerField',               # BigInt
+64  : 'DateTimeField',              # FileTime
+72  : 'CharField',                  # GUID
+129 : 'CharField',                  # Char
+130 : 'CharField',                  # WChar
+131 : 'FloatField',                 # Numeric
+133 : 'DateField',                  # DBDate
+134 : 'TimeField',                  # DBTime
+135 : 'DateTimeField',              # DBTimeStamp
+139 : 'FloatField',                 # VarNumeric
+200 : 'CharField',                  # VarChar
+201 : 'TextField',                  # LongVarChar
+202 : 'CharField',                  # VarWChar
+203 : 'TextField',                  # LongVarWChar
+}
\ No newline at end of file
Index: db/backends/mssql/creation.py
===================================================================
--- db/backends/mssql/creation.py	(revision 0)
+++ db/backends/mssql/creation.py	(revision 0)
@@ -0,0 +1,27 @@
+DATA_TYPES = {
+    'AutoField':         'int IDENTITY (1, 1)',
+    'BooleanField':      'bit',
+    'CharField':         'varchar(%(maxlength)s)',
+    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
+    'DateField':         'datetime',
+    'DateTimeField':     'datetime',
+    'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
+    'FileField':         'varchar(254)',
+    'FilePathField':     'varchar(254)',
+    'FloatField':        'double precision',
+    'ImageField':        'varchar(254)',
+    'IntegerField':      'int',
+    'IPAddressField':    'char(15)',
+    'ManyToManyField':   None,
+    'NullBooleanField':  'bit',
+    'OneToOneField':     'int',
+    'PhoneNumberField':  'varchar(20)',
+    #The check must be unique in for the database. Put random so the regresion test not complain about duplicate names
+    'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)',    
+    'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)',
+    'SlugField':         'varchar(%(maxlength)s)',
+    'SmallIntegerField': 'smallint',
+    'TextField':         'text',
+    'TimeField':         'datetime',
+    'USStateField':      'varchar(2)',
+}
Index: db/backends/mssql/__init__.py
===================================================================
Index: db/backends/mssql/base.py
===================================================================
--- db/backends/mssql/base.py	(revision 0)
+++ db/backends/mssql/base.py	(revision 0)
@@ -0,0 +1,232 @@
+"""
+Alpha Multi-plataform MSSQL database backend for Django.
+
+Requires pymssql >= v0.8.0: http://pymssql.sourceforge.net/
+"""
+if __name__ == '__main__':
+    import sys
+    import os
+    
+    SETTINGS_MODULE = 'settings'
+
+    project_dir = r'E:\Proyectos\Python\mysite'
+    sys.path.append(os.path.join(project_dir, '..'))
+    sys.path.append("..")
+    sys.path.pop()
+    os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
+    
+
+import datetime
+from django.db.backends import util
+from django.core.exceptions import ImproperlyConfigured
+
+try:
+    import pymssql as Database
+except ImportError, e:
+    raise ImproperlyConfigured, "Error loading pymssql module: %s" % e
+
+try:
+    import mx
+except ImportError:
+    mx = None
+
+try:
+    # Only exists in Python 2.4+
+    from threading import local
+except ImportError:
+    # Import copy of _thread_local.py from Python 2.4
+    from django.utils._threading_local import local
+
+DatabaseError = Database.DatabaseError
+IntegrityError = Database.IntegrityError
+
+#Configure support options:
+allows_group_by_ordinal = True
+allows_unique_and_pk = True
+autoindexes_primary_keys = True
+needs_datetime_string_cast = True
+needs_upper_for_iops = False
+supports_constraints = True
+supports_tablespaces = False
+uses_case_insensitive_names = False
+
+def complain(*args, **kwargs):
+    raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet."
+
+def ignore(*args, **kwargs):
+    pass
+
+class DatabaseError(Exception):
+    pass
+
+class IntegrityError(DatabaseError):
+    pass
+
+class DatabaseWrapper(local):
+    def __init__(self, **kwargs):
+        self.connection = None
+        self.queries = []
+
+    def cursor(self):
+        from django.conf import settings
+        if self.connection is None:
+            if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
+                raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file."
+            if not settings.DATABASE_HOST:
+                settings.DATABASE_HOST = "127.0.0.1"
+            # TODO: Handle DATABASE_PORT.
+            self.connection = Database.connect(host=settings.DATABASE_HOST,user=settings.DATABASE_USER,password=settings.DATABASE_PASSWORD,database=settings.DATABASE_NAME)
+        
+        self.connection.cursor().execute("SET DATEFORMAT ymd\nGO")
+        
+        cursor = self.connection.cursor()
+        if settings.DEBUG:
+            return util.CursorDebugWrapper(cursor, self)
+        return cursor
+
+    def _commit(self):
+        if self.connection is not None:
+            return self.connection.commit()
+
+    def _rollback(self):
+        if self.connection is not None:
+            return self.connection.rollback()
+
+    def close(self):
+        if self.connection is not None:
+            self.connection.close()
+            self.connection = None
+
+'''
+    Return the major version of the server. 7=Sql 7,8=Sql2000,9=Sql2005
+'''
+def version():
+    cur = DatabaseWrapper().cursor()
+    cur.execute("SELECT SERVERPROPERTY('ProductVersion')")
+    
+    return int(cur.fetchone()[0].split('.')[0])
+
+def quote_name(name):
+    if name.startswith('[') and name.endswith(']'):
+        return name # Quoting once is enough.
+    return '[%s]' % name
+
+dictfetchone = util.dictfetchone
+dictfetchmany = util.dictfetchmany
+dictfetchall  = util.dictfetchall
+
+def get_last_insert_id(cursor, table_name, pk_name):
+    cursor.execute("SELECT %s FROM %s WHERE %s = IDENT_CURRENT('%s')" % (pk_name, table_name, pk_name,table_name)) 
+    return cursor.fetchone()[0]
+
+def get_date_extract_sql(lookup_type, table_name):
+    # lookup_type is 'year', 'month', 'day'
+    return "DATEPART(%s, %s)" % (lookup_type, table_name)
+
+def get_date_trunc_sql(lookup_type, field_name):
+    # lookup_type is 'year', 'month', 'day'
+    if lookup_type=='year':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name
+    if lookup_type=='month':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name)
+    if lookup_type=='day':
+        return "Convert(datetime, Convert(varchar(12), %s))" % field_name
+
+def get_datetime_cast_sql():
+    return None
+
+def get_limit_offset_sql(limit, offset=None):
+    # Limits and offset are too complicated to be handled here.
+    # Look for a implementation similar to oracle backend
+    return ""
+
+def get_random_function_sql():
+    return "RAND()"
+
+def get_deferrable_sql():
+    # TODO: Workaround cicle paths...
+    # DEFERRABLE and INITALLY DEFFERRED are not apparently supported on constraints
+    # This cause SQL Server message 1750, severity 16, state 0, for example in the multiple joins path of comments.
+    # So, this left Sql Server as if have not relations :(
+    #return " ON DELETE CASCADE ON UPDATE CASCADE"
+    return "" 
+
+def get_fulltext_search_sql(field_name):
+    raise NotImplementedError
+
+def get_drop_foreignkey_sql():
+    return "DROP CONSTRAINT"
+
+def get_pk_default_value():
+    return "DEFAULT"
+
+def get_max_name_length():
+    return None
+
+def get_start_transaction_sql():
+    return "BEGIN;"
+
+def get_tablespace_sql(tablespace, inline=False):
+    return "ON %s" % quote_name(tablespace)
+
+def get_autoinc_sql(table):
+    return None
+
+def get_sql_flush(sql_styler, full_table_list, sequences): 
+    """Return a list of SQL statements required to remove all data from
+    all tables in the database (without actually removing the tables
+    themselves) and put the database in an empty 'initial' state
+    """
+    # Cannot use TRUNCATE on tables that are reference by a FOREIGN KEY
+    # So must use the much slower DELETE
+    sql_list = ['%s %s %s;' % \
+                (sql_styler.SQL_KEYWORD('DELETE'),
+                sql_styler.SQL_KEYWORD('FROM'),
+                sql_styler.SQL_FIELD(quote_name(table))
+                )  for table in full_table_list]
+    #The reset the counters on each table.
+    sql_list.extend(['%s %s %s %s %s %s %s;' % (
+        sql_styler.SQL_KEYWORD('DBCC'),
+        sql_styler.SQL_KEYWORD('CHECKIDENT'),
+        sql_styler.SQL_FIELD(quote_name(seq["table"])),
+        sql_styler.SQL_KEYWORD('RESEED'),
+        sql_styler.SQL_FIELD('1'),
+        sql_styler.SQL_KEYWORD('WITH'),
+        sql_styler.SQL_KEYWORD('NO_INFOMSGS'),
+        ) for seq in sequences])
+    
+    return sql_list 
+
+def get_sql_sequence_reset(style, model_list):
+    "Returns a list of the SQL statements to reset sequences for the given models."
+    # No sequence reset required
+    return []
+
+OPERATOR_MAPPING = {
+    'exact': '= %s',
+    'iexact': 'LIKE %s',
+    'contains': 'LIKE %s',
+    'icontains': 'LIKE %s',
+    'gt': '> %s',
+    'gte': '>= %s',
+    'lt': '< %s',
+    'lte': '<= %s',
+    'startswith': 'LIKE %s',
+    'endswith': 'LIKE %s',
+    'istartswith': 'LIKE %s',
+    'iendswith': 'LIKE %s',
+}
+
+if __name__ == '__main__':
+    from mysite.polls.models import Poll, Choice
+    from django.contrib.auth.models import User
+    from datetime import datetime
+    Poll.objects.all()
+    p = Poll(question="What's up?", pub_date=datetime.now())
+    p.save()
+    print p.id
+    
+    db=DatabaseWrapper()
+    print version()
+
+
Index: db/backends/mssql/client.py
===================================================================
--- db/backends/mssql/client.py	(revision 0)
+++ db/backends/mssql/client.py	(revision 0)
@@ -0,0 +1,2 @@
+def runshell():
+    raise NotImplementedError
Index: db/backends/mssql/creation.py
===================================================================
--- db/backends/mssql/creation.py	(revision 0)
+++ db/backends/mssql/creation.py	(revision 0)
@@ -0,0 +1,27 @@
+DATA_TYPES = {
+    'AutoField':         'int IDENTITY (1, 1)',
+    'BooleanField':      'bit',
+    'CharField':         'varchar(%(maxlength)s)',
+    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
+    'DateField':         'datetime',
+    'DateTimeField':     'datetime',
+    'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
+    'FileField':         'varchar(254)',
+    'FilePathField':     'varchar(254)',
+    'FloatField':        'double precision',
+    'ImageField':        'varchar(254)',
+    'IntegerField':      'int',
+    'IPAddressField':    'char(15)',
+    'ManyToManyField':   None,
+    'NullBooleanField':  'bit',
+    'OneToOneField':     'int',
+    'PhoneNumberField':  'varchar(20)',
+    #The check must be unique in for the database. Put random so the regresion test not complain about duplicate names
+    'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)',    
+    'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)',
+    'SlugField':         'varchar(%(maxlength)s)',
+    'SmallIntegerField': 'smallint',
+    'TextField':         'text',
+    'TimeField':         'datetime',
+    'USStateField':      'varchar(2)',
+}
Index: db/backends/mssql/introspection.py
===================================================================
--- db/backends/mssql/introspection.py	(revision 0)
+++ db/backends/mssql/introspection.py	(revision 0)
@@ -0,0 +1,137 @@
+def get_table_list(cursor):
+    "Returns a list of table names in the current database."
+    cursor.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'")
+    return [row[2] for row in cursor.fetchall()]
+
+def _is_auto_field(cursor, table_name, column_name):
+    cursor.execute("SELECT COLUMNPROPERTY( OBJECT_ID('%s'),'%s','IsIdentity')" % (table_name, column_name))
+    return cursor.fetchall()[0][0]
+
+def get_table_description(cursor, table_name, identity_check=True):
+    """Returns a description of the table, with the DB-API cursor.description interface.
+
+    The 'auto_check' parameter has been added to the function argspec.
+    If set to True, the function will check each of the table's fields for the
+    IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField).
+
+    When a field is found with an IDENTITY property, it is given a custom field number
+    of -777, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict.
+    """    
+    cursor.execute("SELECT TOP 1 * FROM %s" % table_name)
+    cursor.nextset()
+    items = []
+    if identity_check:
+        for data in cursor.description:
+            if _is_auto_field(cursor, table_name, data[0]):
+                data = list(data)
+                data[1] = -777
+            items.append(list(data))
+    else:
+        items = cursor.description
+    return items
+
+def _name_to_index(cursor, table_name):
+    """
+    Returns a dictionary of {field_name: field_index} for the given table.
+    Indexes are 0-based.
+    """
+    return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name, identity_check=False))])
+
+def get_relations(cursor, table_name):
+    """
+    Returns a dictionary of {field_index: (field_index_other_table, other_table)}
+    representing all relationships to the given table. Indexes are 0-based.    
+    """
+    table_index = _name_to_index(cursor, table_name)
+    sql = """SELECT e.COLUMN_NAME AS column_name,
+                    c.TABLE_NAME AS referenced_table_name,
+                    d.COLUMN_NAME AS referenced_column_name
+                    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a
+                        INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS b
+                              ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
+                        INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE AS c
+                              ON b.UNIQUE_CONSTRAINT_NAME = c.CONSTRAINT_NAME
+                        INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS d
+                              ON c.CONSTRAINT_NAME = d.CONSTRAINT_NAME
+                        INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS e
+                              ON a.CONSTRAINT_NAME = e.CONSTRAINT_NAME
+                    WHERE a.TABLE_NAME = ? AND
+                          a.CONSTRAINT_TYPE = 'FOREIGN KEY'"""
+    cursor = Cursor(cursor.db.connection)
+    cursor.execute(sql, (table_name,))
+    return dict([(table_index[item[0]], (_name_to_index(cursor, item[1])[item[2]], item[1]))
+                  for item in cursor.fetchall()])
+    
+def get_indexes(cursor, table_name):
+    """
+    Returns a dictionary of fieldname -> infodict for the given table,
+    where each infodict is in the format:
+        {'primary_key': boolean representing whether it's the primary key,
+         'unique': boolean representing whether it's a unique index}
+    """
+    sql = """SELECT b.COLUMN_NAME, a.CONSTRAINT_TYPE
+               FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a INNER JOIN
+                    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS b
+                    ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME AND
+                       a.TABLE_NAME = b.TABLE_NAME
+               WHERE a.TABLE_NAME = ? AND
+                     (CONSTRAINT_TYPE = 'PRIMARY KEY' OR
+                      CONSTRAINT_TYPE = 'UNIQUE')"""
+    field_names = [item[0] for item in get_table_description(cursor, table_name, identity_check=False)]
+    cursor = Cursor(cursor.db.connection)
+    cursor.execute(sql, (table_name,))
+    indexes = {}
+    results = {}
+    data = cursor.fetchall()
+    if data:
+        results.update(data)
+    for field in field_names:
+        val = results.get(field, None)
+        indexes[field] = dict(primary_key=(val=='PRIMARY KEY'), unique=(val=='UNIQUE'))
+    return indexes
+
+# A reference for the values below:
+# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdcstdatatypeenum.asp
+DATA_TYPES_REVERSE = {
+# 8192 : Array ,
+# 128 : Binary ,
+# 9 : IDispatch ,
+# 12 : Variant ,
+# 13 : IUnknown ,
+# 21  : UnsignedBigInt,
+# 132 : UserDefined ,
+# 0   : Empty ,
+# 136 : Chapter ,
+# 138 : PropVariant ,
+# 204 : VarBinary ,
+# 205 : LongVarBinary ,
+-777: 'AutoField',                  # Custom number used to identify AutoFields
+2   : 'SmallIntegerField',          # SmallInt
+3   : 'IntegerField',               # Integer
+4   : 'FloatField',                 # Single
+5   : 'FloatField',                 # Decimal
+6   : 'FloatField',                 # Currency
+7   : 'DateField',                  # Date
+8   : 'CharField',                  # BSTR
+10  : 'IntegerField',               # Error
+11  : 'BooleanField',               # Boolean
+14  : 'FloatField',                 # Decimal
+16  : 'SmallIntegerField',          # TinyInt
+17  : 'PositiveSmallIntegerField',  # UnsignedTinyInt
+18  : 'PositiveSmallIntegerField',  # UnsignedSmallInt
+19  : 'PositiveIntegerField',       # UnsignedInt
+20  : 'IntegerField',               # BigInt
+64  : 'DateTimeField',              # FileTime
+72  : 'CharField',                  # GUID
+129 : 'CharField',                  # Char
+130 : 'CharField',                  # WChar
+131 : 'FloatField',                 # Numeric
+133 : 'DateField',                  # DBDate
+134 : 'TimeField',                  # DBTime
+135 : 'DateTimeField',              # DBTimeStamp
+139 : 'FloatField',                 # VarNumeric
+200 : 'CharField',                  # VarChar
+201 : 'TextField',                  # LongVarChar
+202 : 'CharField',                  # VarWChar
+203 : 'TextField',                  # LongVarWChar
+}
\ No newline at end of file
Index: db/backends/util.py
===================================================================
--- db/backends/util.py	(revision 5596)
+++ db/backends/util.py	(working copy)
@@ -1,3 +1,4 @@
+from django.conf import settings
 import datetime
 import md5
 from time import time
@@ -22,8 +23,24 @@
             # formatting with '%' only works with tuples or dicts.
             if not isinstance(params, (tuple, dict)):
                 params = tuple(params)
+            # ado_mssql uses '?' for parameter escaping, so all '?'
+            # must be replaced with the standard '%s' if the parameter
+            # substitution is going to work.
+            if settings.DATABASE_ENGINE == 'ado_mssql':
+                sql = sql.replace('?', '%s')
+            # There are many situations that will cause the string
+            # substituion below to fail (e.g. wildcard characters '%'
+            # in LIKE queries).  Instead of attempting to figure out
+            # the many variations that can cause an error, the string substition
+            # will be attempted first; if it fails, then the sql
+            # and its parameters will be combined into a string similar to
+            # the one created in the executemany function below.
+            try:
+                sql = sql % tuple(params)
+            except:
+                sql = '%s SQL: %s' % (sql, str(tuple(params)))
             self.db.queries.append({
-                'sql': sql % params,
+                'sql': sql,
                 'time': "%.3f" % (stop - start),
             })
 
Index: db/models/base.py
===================================================================
--- db/models/base.py	(revision 5596)
+++ db/models/base.py	(working copy)
@@ -239,9 +239,22 @@
                     (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column)))
                 db_values.append(getattr(self, self._meta.order_with_respect_to.attname))
             if db_values:
+                if pk_set and (settings.DATABASE_ENGINE=="ado_mssql" or settings.DATABASE_ENGINE=="mssql"):
+                    # You can't insert an auto value into a column unless you do
+                    # this in MSSQL
+                    # TODO: Only works for auto-id's... how chek it properly?
+                    if self._meta.pk.column == 'id':
+                        cursor.execute("SET IDENTITY_INSERT %s ON" % \
+                            backend.quote_name(self._meta.db_table))
+                    
                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \
                     (backend.quote_name(self._meta.db_table), ','.join(field_names),
                     ','.join(placeholders)), db_values)
+                    
+                if pk_set and (settings.DATABASE_ENGINE=="ado_mssql" or settings.DATABASE_ENGINE=="mssql"):
+                    if self._meta.pk.column == 'id':
+                        cursor.execute("SET IDENTITY_INSERT %s OFF" %\
+                            backend.quote_name(self._meta.db_table))
             else:
                 # Create a new record with defaults for everything.
                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" %
Index: db/models/fields/__init__.py
===================================================================
--- db/models/fields/__init__.py	(revision 5596)
+++ db/models/fields/__init__.py	(working copy)
@@ -541,12 +541,15 @@
         if value is not None:
             # MySQL will throw a warning if microseconds are given, because it
             # doesn't support microseconds.
-            if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
+            if settings.DATABASE_ENGINE in ('mysql', 'ado_mssql','mssql') and hasattr(value, 'microsecond'):
                 value = value.replace(microsecond=0)
             value = str(value)
         return Field.get_db_prep_save(self, value)
 
     def get_db_prep_lookup(self, lookup_type, value):
+        # MSSQL doesn't like microseconds.
+        if settings.DATABASE_ENGINE in ('mysql', 'ado_mssql','mssql') and hasattr(value, 'microsecond'):
+            value = value.replace(microsecond=0)
         if lookup_type == 'range':
             value = [str(v) for v in value]
         else:
@@ -908,8 +911,9 @@
         # Casts dates into string format for entry into database.
         if value is not None:
             # MySQL will throw a warning if microseconds are given, because it
-            # doesn't support microseconds.
-            if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
+            # doesn't support microseconds. Ditto MSSQL
+            if settings.DATABASE_ENGINE in ('mysql', 'ado_mssql','mssql') \
+                            and hasattr(value, 'microsecond'):
                 value = value.replace(microsecond=0)
             if settings.DATABASE_ENGINE == 'oracle':
                 # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.
