Commits

Kirill Simonov committed 3ca89a0

tweak.django: respect django transaction management.

Comments (0)

Files changed (5)

demo/django/tutorial/polls/views.py

     latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
     return render_to_response('polls/index.html', {'latest_poll_list': latest_poll_list})
 
-
 def detail(request, poll_id):
     p = get_object_or_404(Poll, pk=poll_id)
     return render_to_response('polls/detail.html', {'poll': p},

demo/django/tutorial/tutorial/settings.py

 MIDDLEWARE_CLASSES = (
     'django.middleware.common.CommonMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.transaction.TransactionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',

src/htsql/core/connect.py

         return None
 
 
+class Transact(Utility):
+
+    def __call__(self):
+        return TransactionGuard()
+
+
 class TransactionGuard(object):
 
     def __init__(self):
             connection.release()
 
 
-def transaction():
-    return TransactionGuard()
-
-
 connect = Connect.__invoke__
 scramble = Scramble.__invoke__
 unscramble = Unscramble.__invoke__
 unscramble_error = UnscrambleError.__invoke__
+transaction = Transact.__invoke__
 
 

src/htsql/tweak/django/connect.py

 # Copyright (c) 2006-2012, Prometheus Research, LLC
 #
 
-from ...core.connect import Connect
+from ...core.connect import Connect, Transact, connect
 from ...core.adapter import rank
+from ...core.context import context
 
 
 class DjangoConnect(Connect):
         return connections[DEFAULT_DB_ALIAS]
 
 
+class DjangoTransact(Transact):
+
+    def __call__(self):
+        return DjangoTransactionGuard()
+
+
+class DjangoTransactionGuard(object):
+
+    def __init__(self):
+        self.is_nested = None
+        self.is_managed = None
+
+    def __enter__(self):
+        self.is_nested = True
+        self.is_managed = True
+        if context.env.connection is None:
+            connection = connect()
+            context.env.push(connection=connection)
+            self.is_nested = False
+            if not connection.connection.is_managed():
+                connection.connection.enter_transaction_management()
+                self.is_managed = False
+        return context.env.connection
+
+    def __exit__(self, exc_type, exc_value, exc_traceback):
+        if not self.is_nested:
+            connection = context.env.connection
+            context.env.pop()
+            if exc_type is None:
+                if not self.is_managed:
+                    connection.commit()
+                    connection.connection.leave_transaction_management()
+                else:
+                    connection.connection.commit_unless_managed()
+            else:
+                if not self.is_managed:
+                    connection.connection.leave_transaction_management()
+                connection.invalidate()
+            connection.release()
+        self.is_nested = None
+        self.is_forced = None
+
+

src/htsql_django/views.py

     return environ
 
 @login_required
-@transaction.commit_manually
 def gateway(request):
     class output:
         status = None