~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/transaction_services.cc

  • Committer: Lee Bieber
  • Date: 2010-10-27 02:00:05 UTC
  • mfrom: (1882.1.2 build)
  • Revision ID: kalebral@gmail.com-20101027020005-jqiq89je9lhpidux
Merge Shrews - add options to the transaction_reader utility program
Merge Shrews - fix bug 660779: Transaction log retaining partial information from an aborted transaction

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
#include "drizzled/plugin/xa_resource_manager.h"
72
72
#include "drizzled/internal/my_sys.h"
73
73
 
74
 
using namespace std;
75
 
 
76
74
#include <vector>
77
75
#include <algorithm>
78
76
#include <functional>
 
77
#include <google/protobuf/repeated_field.h>
 
78
 
 
79
using namespace std;
 
80
using namespace google;
79
81
 
80
82
namespace drizzled
81
83
{
1826
1828
  }
1827
1829
}
1828
1830
 
 
1831
 
 
1832
/**
 
1833
 * Template for removing Statement records of different types.
 
1834
 *
 
1835
 * The code for removing records from different Statement message types
 
1836
 * is identical except for the class types that are embedded within the
 
1837
 * Statement.
 
1838
 *
 
1839
 * There are 3 scenarios we need to look for:
 
1840
 *   - We've been asked to remove more records than exist in the Statement
 
1841
 *   - We've been asked to remove less records than exist in the Statement
 
1842
 *   - We've been asked to remove ALL records that exist in the Statement
 
1843
 *
 
1844
 * If we are removing ALL records, then effectively we would be left with
 
1845
 * an empty Statement message, so we should just remove it and clean up
 
1846
 * message pointers in the Session object.
 
1847
 */
 
1848
template <class DataType, class RecordType>
 
1849
static bool removeStatementRecordsWithType(Session *session,
 
1850
                                           DataType *data,
 
1851
                                           uint32_t count)
 
1852
{
 
1853
  uint32_t num_avail_recs= static_cast<uint32_t>(data->record_size());
 
1854
 
 
1855
  /* If there aren't enough records to remove 'count' of them, error. */
 
1856
  if (num_avail_recs < count)
 
1857
    return false;
 
1858
 
 
1859
  /*
 
1860
   * If we are removing all of the data records, we'll just remove this
 
1861
   * entire Statement message.
 
1862
   */
 
1863
  if (num_avail_recs == count)
 
1864
  {
 
1865
    message::Transaction *transaction= session->getTransactionMessage();
 
1866
    protobuf::RepeatedPtrField<message::Statement> *statements= transaction->mutable_statement();
 
1867
    statements->RemoveLast();
 
1868
 
 
1869
    /*
 
1870
     * Now need to set the Session Statement pointer to either the previous
 
1871
     * Statement, or NULL if there isn't one.
 
1872
     */
 
1873
    if (statements->size() == 0)
 
1874
    {
 
1875
      session->setStatementMessage(NULL);
 
1876
    }
 
1877
    else
 
1878
    {
 
1879
      /*
 
1880
       * There isn't a great way to get a pointer to the previous Statement
 
1881
       * message using the RepeatedPtrField object, so we'll just get to it
 
1882
       * using the Transaction message.
 
1883
       */
 
1884
      int last_stmt_idx= transaction->statement_size() - 1;
 
1885
      session->setStatementMessage(transaction->mutable_statement(last_stmt_idx));
 
1886
    }
 
1887
  }
 
1888
  /* We only need to remove 'count' records */
 
1889
  else if (num_avail_recs > count)
 
1890
  {
 
1891
    protobuf::RepeatedPtrField<RecordType> *records= data->mutable_record();
 
1892
    while (count--)
 
1893
      records->RemoveLast();
 
1894
  }
 
1895
 
 
1896
  return true;
 
1897
}
 
1898
 
 
1899
 
 
1900
bool TransactionServices::removeStatementRecords(Session *session,
 
1901
                                                 uint32_t count)
 
1902
{
 
1903
  ReplicationServices &replication_services= ReplicationServices::singleton();
 
1904
  if (! replication_services.isActive())
 
1905
    return false;
 
1906
 
 
1907
  /* Get the most current Statement */
 
1908
  message::Statement *statement= session->getStatementMessage();
 
1909
 
 
1910
  /* Make sure we have work to do */
 
1911
  if (statement == NULL)
 
1912
    return false;
 
1913
 
 
1914
  bool retval= false;
 
1915
 
 
1916
  switch (statement->type())
 
1917
  {
 
1918
    case message::Statement::INSERT:
 
1919
    {
 
1920
      message::InsertData *data= statement->mutable_insert_data();
 
1921
      retval= removeStatementRecordsWithType<message::InsertData, message::InsertRecord>(session, data, count);
 
1922
      break;
 
1923
    }
 
1924
 
 
1925
    case message::Statement::UPDATE:
 
1926
    {
 
1927
      message::UpdateData *data= statement->mutable_update_data();
 
1928
      retval= removeStatementRecordsWithType<message::UpdateData, message::UpdateRecord>(session, data, count);
 
1929
      break;
 
1930
    }
 
1931
 
 
1932
    case message::Statement::DELETE:  /* not sure if this one is possible... */
 
1933
    {
 
1934
      message::DeleteData *data= statement->mutable_delete_data();
 
1935
      retval= removeStatementRecordsWithType<message::DeleteData, message::DeleteRecord>(session, data, count);
 
1936
      break;
 
1937
    }
 
1938
 
 
1939
    default:
 
1940
      retval= false;
 
1941
      break;
 
1942
  }
 
1943
 
 
1944
  return retval;
 
1945
}
 
1946
 
 
1947
 
1829
1948
void TransactionServices::createTable(Session *in_session,
1830
1949
                                      const message::Table &table)
1831
1950
{