Module: sql-implementation Author: eec Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND // $HopeName: D-databases-sql!transaction.dylan(trunk.6) $ define open generic default-transaction-mode(connection :: ) => (mode :: ); define open generic default-isolation-level(connection :: ) => (level :: ); define open generic default-diagnostics-size(connection :: ) => (diagnostics-size :: ); define open generic start-transaction(connection :: , transaction-mode :: , isolation-level :: , diagnostics-size :: ) => (transaction :: ); define open generic end-transaction(transaction :: ) => (); define open generic rollback-transaction(transaction :: ) => (); define open generic commit-transaction(transaction :: ) => (); define macro with-transaction { with-transaction(#key ?rollback:name = ignore-rollback, ?commit:name = ignore-commit, ?autocommit:expression = #t, // if #f, rollback ?transaction-mode:name = not-supplied, ?isolation-level:name = not-supplied, ?diagnostics-size:expression = $unfound, ?connection:expression = $unfound) ?transaction-body:body rollback ?rollback-body:body end } => { let connection = if (?connection == $unfound) default-connection() else ?connection end if; let diagnostics-size = if (?diagnostics-size == $unfound) default-diagnostics-size(connection) else ?diagnostics-size end if; let transaction-mode = if (?transaction-mode == $unfound) default-transaction-mode(connection) else ?transaction-mode end if; let isolation-level = if (?isolation-level == $unfound) default-isolation-level(connection) else ?isolation-level end if; let transaction = #f; with-connection(connection) block (exit) transaction := start-transaction(connection, transaction-mode, isolation-level, diagnostics-size); let ?rollback = compose(exit, curry(rollback-transaction, transaction)); let ?commit = compose(exit, curry(commit-transaction, transaction)); ?transaction-body afterwards if (?autocommit) commit-transaction(transaction); exit(); else rollback-transaction(transaction); exit(); end if; cleanup if (transaction ~= #f) end-transaction(transaction); end if; exception (condition :: ) ?rollback-body end block end; } { with-transaction(#key ?rollback:name = ignore-rollback, ?commit:name = ignore-commit, ?autocommit:expression = #t, // if #f, rollback ?transaction-mode:name = not-supplied, ?isolation-level:name = not-supplied, ?diagnostics-size:expression = $unfound, ?connection:expression = $unfound) ?transaction-body:body end } => { let connection = if (?connection == $unfound) default-connection() else ?connection end if; let diagnostics-size = if (?diagnostics-size == $unfound) default-diagnostics-size(connection) else ?diagnostics-size end if; let transaction-mode = if (?transaction-mode == $unfound) default-transaction-mode(connection) else ?transaction-mode end if; let isolation-level = if (?isolation-level == $unfound) default-isolation-level(connection) else ?isolation-level end if; let transaction = #f; with-connection(connection) block (exit) transaction := start-transaction(connection, transaction-mode, isolation-level, diagnostics-size); let ?rollback = compose(exit, curry(rollback-transaction, transaction)); let ?commit = compose(exit, curry(commit-transaction, transaction)); ?transaction-body afterwards if (?autocommit) commit-transaction(transaction); else rollback-transaction(transaction); end if; cleanup if (transaction ~= #f) end-transaction(transaction); end if; end block end; } transaction-mode: { read-only } => { $read-only } { read-write } => { $read-write } { not-supplied } => { $unfound } isolation-level: { read-uncommitted } => { $read-uncommitted } { read-committed } => { $read-committed } { repeatable-read } => { $repeatable-read } { serializable } => { $serializable } { not-supplied } => { $unfound } end macro;