NdbBlob.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #ifndef NdbBlob_H
  14. #define NdbBlob_H
  15. #include <ndb_types.h>
  16. #include <NdbDictionary.hpp>
  17. #include <NdbConnection.hpp>
  18. #include <NdbError.hpp>
  19. class Ndb;
  20. class NdbConnection;
  21. class NdbOperation;
  22. class NdbRecAttr;
  23. class NdbTableImpl;
  24. class NdbColumnImpl;
  25. /**
  26.  * @class NdbBlob
  27.  * @brief Blob handle
  28.  *
  29.  * Blob data is stored in 2 places:
  30.  *
  31.  * - "header" and "inline bytes" stored in the blob attribute
  32.  * - "blob parts" stored in a separate table NDB$BLOB_<tid>_<cid>
  33.  *
  34.  * Inline and part sizes can be set via NdbDictionary::Column methods
  35.  * when the table is created.
  36.  *
  37.  * NdbBlob is a blob handle.  To access blob data, the handle must be
  38.  * created using NdbOperation::getBlobHandle in operation prepare phase.
  39.  * The handle has following states:
  40.  *
  41.  * - prepared: before the operation is executed
  42.  * - active: after execute or next result but before transaction commit
  43.  * - closed: after transaction commit
  44.  * - invalid: after rollback or transaction close
  45.  *
  46.  * NdbBlob supports 3 styles of data access:
  47.  *
  48.  * - in prepare phase, NdbBlob methods getValue and setValue are used to
  49.  *   prepare a read or write of a blob value of known size
  50.  *
  51.  * - in prepare phase, setActiveHook is used to define a routine which
  52.  *   is invoked as soon as the handle becomes active
  53.  *
  54.  * - in active phase, readData and writeData are used to read or write
  55.  *   blob data of arbitrary size
  56.  *
  57.  * The styles can be applied in combination (in above order).
  58.  *
  59.  * Blob operations take effect at next transaction execute.  In some
  60.  * cases NdbBlob is forced to do implicit executes.  To avoid this,
  61.  * operate on complete blob parts.
  62.  *
  63.  * Use NdbConnection::executePendingBlobOps to flush your reads and
  64.  * writes.  It avoids execute penalty if nothing is pending.  It is not
  65.  * needed after execute (obviously) or after next scan result.
  66.  *
  67.  * NdbBlob methods return -1 on error and 0 on success, and use output
  68.  * parameters when necessary.
  69.  *
  70.  * Operation types:
  71.  * - insertTuple must use setValue if blob column is non-nullable
  72.  * - readTuple with exclusive lock can also update existing value
  73.  * - updateTuple can overwrite with setValue or update existing value
  74.  * - writeTuple always overwrites and must use setValue if non-nullable
  75.  * - deleteTuple creates implicit non-accessible blob handles
  76.  * - scan with exclusive lock can also update existing value
  77.  * - scan "lock takeover" update op must do its own getBlobHandle
  78.  *
  79.  * Bugs / limitations:
  80.  * - lock mode upgrade should be handled automatically
  81.  * - lock mode vs allowed operation is not checked
  82.  * - too many pending blob ops can blow up i/o buffers
  83.  * - table and its blob part tables are not created atomically
  84.  * - there is no support for an asynchronous interface
  85.  */
  86. class NdbBlob {
  87. public:
  88.   /**
  89.    * State.
  90.    */
  91.   enum State {
  92.     Idle = 0,
  93.     Prepared = 1,
  94.     Active = 2,
  95.     Closed = 3,
  96.     Invalid = 9
  97.   };
  98.   State getState();
  99.   /**
  100.    * Inline blob header.
  101.    */
  102.   struct Head {
  103.     Uint64 length;
  104.   };
  105.   /**
  106.    * Prepare to read blob value.  The value is available after execute.
  107.    * Use getNull to check for NULL and getLength to get the real length
  108.    * and to check for truncation.  Sets current read/write position to
  109.    * after the data read.
  110.    */
  111.   int getValue(void* data, Uint32 bytes);
  112.   /**
  113.    * Prepare to insert or update blob value.  An existing longer blob
  114.    * value will be truncated.  The data buffer must remain valid until
  115.    * execute.  Sets current read/write position to after the data.  Set
  116.    * data to null pointer (0) to create a NULL value.
  117.    */
  118.   int setValue(const void* data, Uint32 bytes);
  119.   /**
  120.    * Callback for setActiveHook.  Invoked immediately when the prepared
  121.    * operation has been executed (but not committed).  Any getValue or
  122.    * setValue is done first.  The blob handle is active so readData or
  123.    * writeData etc can be used to manipulate blob value.  A user-defined
  124.    * argument is passed along.  Returns non-zero on error.
  125.    */
  126.   typedef int ActiveHook(NdbBlob* me, void* arg);
  127.   /**
  128.    * Define callback for blob handle activation.  The queue of prepared
  129.    * operations will be executed in no commit mode up to this point and
  130.    * then the callback is invoked.
  131.    */
  132.   int setActiveHook(ActiveHook* activeHook, void* arg);
  133.   /**
  134.    * Check if blob is null.
  135.    */
  136.   int getNull(bool& isNull);
  137.   /**
  138.    * Set blob to NULL.
  139.    */
  140.   int setNull();
  141.   /**
  142.    * Get current length in bytes.  Use getNull to distinguish between
  143.    * length 0 blob and NULL blob.
  144.    */
  145.   int getLength(Uint64& length);
  146.   /**
  147.    * Truncate blob to given length.  Has no effect if the length is
  148.    * larger than current length.
  149.    */
  150.   int truncate(Uint64 length = 0);
  151.   /**
  152.    * Get current read/write position.
  153.    */
  154.   int getPos(Uint64& pos);
  155.   /**
  156.    * Set read/write position.  Must be between 0 and current length.
  157.    * "Sparse blobs" are not supported.
  158.    */
  159.   int setPos(Uint64 pos);
  160.   /**
  161.    * Read at current position and set new position to first byte after
  162.    * the data read.  A read past blob end returns actual number of bytes
  163.    * read in the in/out bytes parameter.
  164.    */
  165.   int readData(void* data, Uint32& bytes);
  166.   /**
  167.    * Write at current position and set new position to first byte after
  168.    * the data written.  A write past blob end extends the blob value.
  169.    */
  170.   int writeData(const void* data, Uint32 bytes);
  171.   /**
  172.    * Return the blob column.
  173.    */
  174.   const NdbDictionary::Column* getColumn();
  175.   /**
  176.    * Get blob parts table name.  Useful only to test programs.
  177.    */
  178.   static int getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName);
  179.   /**
  180.    * Return error object.  The error may be blob specific (below) or may
  181.    * be copied from a failed implicit operation.
  182.    */
  183.   const NdbError& getNdbError() const;
  184.   /**
  185.    * Return info about all blobs in this operation.
  186.    */
  187.   // Get first blob in list
  188.   NdbBlob* blobsFirstBlob();
  189.   // Get next blob in list after this one
  190.   NdbBlob* blobsNextBlob();
  191. private:
  192.   friend class Ndb;
  193.   friend class NdbConnection;
  194.   friend class NdbOperation;
  195.   friend class NdbScanOperation;
  196.   friend class NdbDictionaryImpl;
  197.   friend class NdbResultSet; // atNextResult
  198.   // state
  199.   State theState;
  200.   void setState(State newState);
  201.   // define blob table
  202.   static void getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c);
  203.   static void getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c);
  204.   // ndb api stuff
  205.   Ndb* theNdb;
  206.   NdbConnection* theNdbCon;
  207.   NdbOperation* theNdbOp;
  208.   const NdbTableImpl* theTable;
  209.   const NdbTableImpl* theAccessTable;
  210.   const NdbTableImpl* theBlobTable;
  211.   const NdbColumnImpl* theColumn;
  212.   char theFillChar;
  213.   // sizes
  214.   Uint32 theInlineSize;
  215.   Uint32 thePartSize;
  216.   Uint32 theStripeSize;
  217.   // getValue/setValue
  218.   bool theGetFlag;
  219.   char* theGetBuf;
  220.   bool theSetFlag;
  221.   const char* theSetBuf;
  222.   Uint32 theGetSetBytes;
  223.   // pending ops
  224.   Uint8 thePendingBlobOps;
  225.   // activation callback
  226.   ActiveHook* theActiveHook;
  227.   void* theActiveHookArg;
  228.   // buffers
  229.   struct Buf {
  230.     char* data;
  231.     unsigned size;
  232.     unsigned maxsize;
  233.     Buf();
  234.     ~Buf();
  235.     void alloc(unsigned n);
  236.     void copyfrom(const Buf& src);
  237.   };
  238.   Buf theKeyBuf;
  239.   Buf theAccessKeyBuf;
  240.   Buf theHeadInlineBuf;
  241.   Buf theHeadInlineCopyBuf;     // for writeTuple
  242.   Buf thePartBuf;
  243.   Head* theHead;
  244.   char* theInlineData;
  245.   NdbRecAttr* theHeadInlineRecAttr;
  246.   NdbOperation* theHeadInlineReadOp;
  247.   bool theHeadInlineUpdateFlag;
  248.   // length and read/write position
  249.   int theNullFlag;
  250.   Uint64 theLength;
  251.   Uint64 thePos;
  252.   // errors
  253.   NdbError theError;
  254.   // for keeping in lists
  255.   NdbBlob* theNext;
  256.   // initialization
  257.   NdbBlob(Ndb*);
  258.   void init();
  259.   void release();
  260.   // classify operations
  261.   bool isTableOp();
  262.   bool isIndexOp();
  263.   bool isKeyOp();
  264.   bool isReadOp();
  265.   bool isInsertOp();
  266.   bool isUpdateOp();
  267.   bool isWriteOp();
  268.   bool isDeleteOp();
  269.   bool isScanOp();
  270.   // computations
  271.   Uint32 getPartNumber(Uint64 pos);
  272.   Uint32 getPartCount();
  273.   Uint32 getDistKey(Uint32 part);
  274.   // getters and setters
  275.   int getTableKeyValue(NdbOperation* anOp);
  276.   int setTableKeyValue(NdbOperation* anOp);
  277.   int setAccessKeyValue(NdbOperation* anOp);
  278.   int setPartKeyValue(NdbOperation* anOp, Uint32 part);
  279.   int getHeadInlineValue(NdbOperation* anOp);
  280.   void getHeadFromRecAttr();
  281.   int setHeadInlineValue(NdbOperation* anOp);
  282.   // data operations
  283.   int readDataPrivate(char* buf, Uint32& bytes);
  284.   int writeDataPrivate(const char* buf, Uint32 bytes);
  285.   int readParts(char* buf, Uint32 part, Uint32 count);
  286.   int insertParts(const char* buf, Uint32 part, Uint32 count);
  287.   int updateParts(const char* buf, Uint32 part, Uint32 count);
  288.   int deleteParts(Uint32 part, Uint32 count);
  289.   int deletePartsUnknown(Uint32 part);
  290.   // pending ops
  291.   int executePendingBlobReads();
  292.   int executePendingBlobWrites();
  293.   // callbacks
  294.   int invokeActiveHook();
  295.   // blob handle maintenance
  296.   int atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn);
  297.   int preExecute(ExecType anExecType, bool& batch);
  298.   int postExecute(ExecType anExecType);
  299.   int preCommit();
  300.   int atNextResult();
  301.   // errors
  302.   void setErrorCode(int anErrorCode, bool invalidFlag = true);
  303.   void setErrorCode(NdbOperation* anOp, bool invalidFlag = true);
  304.   void setErrorCode(NdbConnection* aCon, bool invalidFlag = true);
  305. #ifdef VM_TRACE
  306.   int getOperationType() const;
  307.   friend class NdbOut& operator<<(NdbOut&, const NdbBlob&);
  308. #endif
  309.   void next(NdbBlob* obj) { theNext= obj;}
  310.   NdbBlob* next() { return theNext;}
  311.   friend struct Ndb_free_list_t<NdbBlob>;
  312. };
  313. #endif