~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/rollback_to_savepoint.cc

  • Committer: Brian Aker
  • Date: 2010-02-04 15:58:21 UTC
  • mfrom: (1280.1.9 build)
  • Revision ID: brian@gaz-20100204155821-bi4txluiivy043sb
Rollup of Brian, Jay

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <drizzled/show.h>
23
23
#include <drizzled/session.h>
24
24
#include <drizzled/statement/rollback_to_savepoint.h>
 
25
#include "drizzled/transaction_services.h"
 
26
#include "drizzled/named_savepoint.h"
 
27
#include "drizzled/util/functors.h"
 
28
 
 
29
#include <string>
 
30
 
 
31
using namespace std;
25
32
 
26
33
namespace drizzled
27
34
{
28
35
 
29
36
bool statement::RollbackToSavepoint::execute()
30
37
{
31
 
  SAVEPOINT *sv;
32
 
  for (sv= session->transaction.savepoints; sv; sv= sv->prev)
33
 
  {
 
38
  /*
 
39
   * Handle these situations:
 
40
   *
 
41
   * If the first savepoint on the deck matches the
 
42
   * name to find, simply call rollback_to_savepoint
 
43
   * for the resource managers.
 
44
   *
 
45
   * If the first savepoint on the deck does NOT match
 
46
   * the name to find, then we need to search through
 
47
   * the deque to find the savepoint we need.  If we
 
48
   * don't find it, we return an error.  If we do
 
49
   * find it, we must restructure the deque by removing
 
50
   * all savepoints "above" the one we find.
 
51
   */
 
52
  deque<NamedSavepoint> &savepoints= session->transaction.savepoints;
 
53
  TransactionServices &transaction_services= TransactionServices::singleton();
 
54
 
 
55
  /* Short-circuit for no savepoints */
 
56
  if (savepoints.empty())
 
57
  {
 
58
    my_error(ER_SP_DOES_NOT_EXIST, 
 
59
             MYF(0), 
 
60
             "SAVEPOINT", 
 
61
             session->lex->ident.str);
 
62
    return false;
 
63
  }
 
64
 
 
65
  {
 
66
    /* Short-circuit for first savepoint */
 
67
    NamedSavepoint &first_savepoint= savepoints.front();
 
68
    const string &first_savepoint_name= first_savepoint.getName();
34
69
    if (my_strnncoll(system_charset_info,
35
70
                     (unsigned char *) session->lex->ident.str, 
36
71
                     session->lex->ident.length,
37
 
                     (unsigned char *)sv->name, 
38
 
                     sv->length) == 0)
39
 
    {
40
 
      break;
41
 
    }
42
 
  }
43
 
  if (sv)
44
 
  {
45
 
    if (ha_rollback_to_savepoint(session, sv))
46
 
    {
47
 
      return true; /* cannot happen */
48
 
    }
49
 
    else
50
 
    {
 
72
                     (unsigned char *) first_savepoint_name.c_str(), 
 
73
                     first_savepoint_name.size()) == 0)
 
74
    {
 
75
      /* Found the named savepoint we want to rollback to */
 
76
      (void) transaction_services.ha_rollback_to_savepoint(session, first_savepoint);
 
77
 
51
78
      if (session->transaction.all.modified_non_trans_table)
52
79
      {
53
80
        push_warning(session, 
56
83
                     ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
57
84
      }
58
85
      session->my_ok();
59
 
    }
60
 
    session->transaction.savepoints= sv;
 
86
      return false;
 
87
    }
 
88
  }
 
89
 
 
90
  /* 
 
91
   * OK, from here on out it means that we have savepoints
 
92
   * but that the first savepoint isn't the one we're looking
 
93
   * for.  We need to search through the savepoints and find
 
94
   * the one we're looking for, removing all savepoints "above"
 
95
   * the one we need.
 
96
   */
 
97
  bool found= false;
 
98
  deque<NamedSavepoint> copy_savepoints(savepoints); /* used to restore if not found */
 
99
  deque<NamedSavepoint> new_savepoints;
 
100
  while (savepoints.empty() == false)
 
101
  {
 
102
    NamedSavepoint &sv= savepoints.front();
 
103
    const string &sv_name= sv.getName();
 
104
    if (! found && 
 
105
        my_strnncoll(system_charset_info,
 
106
                     (unsigned char *) session->lex->ident.str, 
 
107
                     session->lex->ident.length,
 
108
                     (unsigned char *) sv_name.c_str(), 
 
109
                     sv_name.size()) == 0)
 
110
    {
 
111
      /* Found the named savepoint we want to rollback to */
 
112
      found= true;
 
113
 
 
114
      (void) transaction_services.ha_rollback_to_savepoint(session, sv);
 
115
    }
 
116
    if (found)
 
117
    {
 
118
      /* 
 
119
       * We push all savepoints "below" the found savepoint
 
120
       * to our new savepoint list, in reverse order to keep
 
121
       * the stack order correct. 
 
122
       */
 
123
      new_savepoints.push_back(sv);
 
124
    }
 
125
    savepoints.pop_front();
 
126
  }
 
127
  if (found)
 
128
  {
 
129
    if (session->transaction.all.modified_non_trans_table)
 
130
    {
 
131
      push_warning(session, 
 
132
                   DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
133
                   ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
134
                   ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
135
    }
 
136
    /* Store new savepoints list */
 
137
    session->transaction.savepoints= new_savepoints;
 
138
    session->my_ok();
61
139
  }
62
140
  else
63
141
  {
 
142
    /* restore the original savepoint list */
 
143
    session->transaction.savepoints= copy_savepoints;
64
144
    my_error(ER_SP_DOES_NOT_EXIST, 
65
145
             MYF(0), 
66
146
             "SAVEPOINT", 
70
150
}
71
151
 
72
152
} /* namespace drizzled */
73