MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbBlob.hpp
1 /*
2  Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef NdbBlob_H
19 #define NdbBlob_H
20 
21 #include <ndb_types.h>
22 #include "NdbDictionary.hpp"
23 #include "NdbTransaction.hpp"
24 #include "NdbError.hpp"
25 
26 class Ndb;
27 class NdbTransaction;
28 class NdbOperation;
29 class NdbRecAttr;
30 class NdbTableImpl;
31 class NdbColumnImpl;
33 
123 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
124 
127 #endif
128 
129 class NdbBlob {
130 public:
134  enum State {
135  Idle = 0,
136  Prepared = 1,
137  Active = 2,
138  Closed = 3,
139  Invalid = 9
140  };
144  State getState();
149  void getVersion(int& version);
150 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
151 
164  struct Head {
165  Uint16 varsize; // length of head+inline minus the 2 length bytes
166  Uint16 reserved; // must be 0 wl3717_todo checksum?
167  Uint32 pkid; // connects part and row with same PK within tx
168  Uint64 length; // blob length
169  //
170  Uint32 headsize; // for convenience, number of bytes in head
171  Head() :
172  varsize(0), reserved(0), pkid(0), length(0), headsize(0) {}
173  };
174  static void packBlobHead(const Head& head, char* buf, int blobVersion);
175  static void unpackBlobHead(Head& head, const char* buf, int blobVersion);
176 #endif
177 
183  int getValue(void* data, Uint32 bytes);
190  int setValue(const void* data, Uint32 bytes);
198  typedef int ActiveHook(NdbBlob* me, void* arg);
204  int setActiveHook(ActiveHook* activeHook, void* arg);
205 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
206  int getDefined(int& isNull);
207  int getNull(bool& isNull);
208 #endif
209 
213  int getNull(int& isNull);
217  int setNull();
222  int getLength(Uint64& length);
227  int truncate(Uint64 length = 0);
231  int getPos(Uint64& pos);
236  int setPos(Uint64 pos);
242  int readData(void* data, Uint32& bytes);
247  int writeData(const void* data, Uint32 bytes);
255  static int getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName);
260  static int getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const char* columnName);
268  const NdbError& getNdbError() const;
275  const NdbOperation* getNdbOperation() const;
318  int close(bool execPendingBlobOps = true);
319 
320 private:
321 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
322  friend class Ndb;
323  friend class NdbTransaction;
324  friend class NdbOperation;
325  friend class NdbScanOperation;
326  friend class NdbDictionaryImpl;
327  friend class NdbResultSet; // atNextResult
328  friend class NdbEventBuffer;
329  friend class NdbEventOperationImpl;
330  friend class NdbReceiver;
331 #endif
332  int theBlobVersion;
333  /*
334  * Disk data does not yet support Var* attrs. In both V1 and V2,
335  * if the primary table blob attr is specified as disk attr then:
336  * - the primary table blob attr remains a memory attr
337  * - the blob parts "DATA" attr becomes a disk attr
338  * - the blob parts "DATA" attr is fixed size
339  * Use following flag. It is always set for V1.
340  */
341  bool theFixedDataFlag;
342  Uint32 theHeadSize;
343  Uint32 theVarsizeBytes;
344  // state
345  State theState;
346  // True if theNdbOp is using NdbRecord, false if NdbRecAttr.
347  bool theNdbRecordFlag;
348  void setState(State newState);
349  // quick and dirty support for events (consider subclassing)
350  int theEventBlobVersion; // -1=data op 0=post event 1=pre event
351  // define blob table
352  static void getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c);
353  static int getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c, struct NdbError& error);
354  static void getBlobEventName(char* bename, const NdbEventImpl* e, const NdbColumnImpl* c);
355  static void getBlobEvent(NdbEventImpl& be, const NdbEventImpl* e, const NdbColumnImpl* c);
356  // compute blob table column number for faster access
357  enum {
358  BtColumnPk = 0, /* V1 only */
359  BtColumnDist = 1, /* if stripe size != 0 */
360  BtColumnPart = 2,
361  BtColumnPkid = 3, /* V2 only */
362  BtColumnData = 4
363  };
364  int theBtColumnNo[5];
365  // ndb api stuff
366  Ndb* theNdb;
367  NdbTransaction* theNdbCon;
368  NdbOperation* theNdbOp;
369  NdbEventOperationImpl* theEventOp;
370  NdbEventOperationImpl* theBlobEventOp;
371  NdbRecAttr* theBlobEventPkRecAttr;
372  NdbRecAttr* theBlobEventDistRecAttr;
373  NdbRecAttr* theBlobEventPartRecAttr;
374  NdbRecAttr* theBlobEventPkidRecAttr;
375  NdbRecAttr* theBlobEventDataRecAttr;
376  const NdbTableImpl* theTable;
377  const NdbTableImpl* theAccessTable;
378  const NdbTableImpl* theBlobTable;
379  const NdbColumnImpl* theColumn;
380  unsigned char theFillChar;
381  // sizes
382  Uint32 theInlineSize;
383  Uint32 thePartSize;
384  Uint32 theStripeSize;
385  // getValue/setValue
386  bool theGetFlag;
387  char* theGetBuf;
388  bool theSetFlag;
389  bool theSetValueInPreExecFlag;
390  const char* theSetBuf;
391  Uint32 theGetSetBytes;
392  // pending ops
393  Uint8 thePendingBlobOps;
394  // activation callback
395  ActiveHook* theActiveHook;
396  void* theActiveHookArg;
397  // buffers
398  struct Buf {
399  char* data;
400  unsigned size;
401  unsigned maxsize;
402  Buf();
403  ~Buf();
404  void alloc(unsigned n);
405  void release();
406  void zerorest();
407  void copyfrom(const Buf& src);
408  };
409  Buf theKeyBuf;
410  Buf theAccessKeyBuf;
411  Buf thePackKeyBuf;
412  Buf theHeadInlineBuf;
413  Buf theHeadInlineCopyBuf; // for writeTuple
414  Buf thePartBuf;
415  Uint16 thePartLen;
416  Buf theBlobEventDataBuf;
417  Uint32 theBlobEventDistValue;
418  Uint32 theBlobEventPartValue;
419  Uint32 theBlobEventPkidValue;
420  Head theHead;
421  char* theInlineData;
422  NdbRecAttr* theHeadInlineRecAttr;
423  NdbOperation* theHeadInlineReadOp;
424  bool theHeadInlineUpdateFlag;
425  // partition id for data events
426  bool userDefinedPartitioning;
427  Uint32 noPartitionId() { return ~(Uint32)0; }
428  Uint32 thePartitionId;
429  NdbRecAttr* thePartitionIdRecAttr;
430  // length and read/write position
431  int theNullFlag;
432  Uint64 theLength;
433  Uint64 thePos;
434  // errors
435  NdbError theError;
436  // for keeping in lists
437  NdbBlob* theNext;
438  // initialization
439  NdbBlob(Ndb*);
440  void init();
441  void release();
442  // classify operations
443  bool isTableOp();
444  bool isIndexOp();
445  bool isKeyOp();
446  bool isReadOp();
447  bool isInsertOp();
448  bool isUpdateOp();
449  bool isWriteOp();
450  bool isDeleteOp();
451  bool isScanOp();
452  bool isReadOnlyOp();
453  bool isTakeOverOp();
454  // computations
455  Uint32 getPartNumber(Uint64 pos);
456  Uint32 getPartOffset(Uint64 pos);
457  Uint32 getPartCount();
458  Uint32 getDistKey(Uint32 part);
459  // pack / unpack
460  int packKeyValue(const NdbTableImpl* aTable, const Buf& srcBuf);
461  int unpackKeyValue(const NdbTableImpl* aTable, Buf& dstBuf);
462  int copyKeyFromRow(const NdbRecord *record, const char *row,
463  Buf& packedBuf, Buf& unpackedBuf);
464  Uint32 getHeadInlineSize() { return theHeadSize + theInlineSize; }
465  void prepareSetHeadInlineValue();
466  void getNullOrEmptyBlobHeadDataPtr(const char * & data, Uint32 & byteSize);
467  // getters and setters
468  void packBlobHead();
469  void unpackBlobHead();
470  int getTableKeyValue(NdbOperation* anOp);
471  int setTableKeyValue(NdbOperation* anOp);
472  int setAccessKeyValue(NdbOperation* anOp);
473  int setDistKeyValue(NdbOperation* anOp, Uint32 part);
474  int setPartKeyValue(NdbOperation* anOp, Uint32 part);
475  int setPartPkidValue(NdbOperation* anOp, Uint32 pkid);
476  int getPartDataValue(NdbOperation* anOp, char* buf, Uint16* aLenLoc);
477  int setPartDataValue(NdbOperation* anOp, const char* buf, const Uint16& aLen);
478  int getHeadInlineValue(NdbOperation* anOp);
479  void getHeadFromRecAttr();
480  int setHeadInlineValue(NdbOperation* anOp);
481  void setHeadPartitionId(NdbOperation* anOp);
482  void setPartPartitionId(NdbOperation* anOp);
483  // data operations
484  int readDataPrivate(char* buf, Uint32& bytes);
485  int writeDataPrivate(const char* buf, Uint32 bytes);
486  int readParts(char* buf, Uint32 part, Uint32 count);
487  int readPart(char* buf, Uint32 part, Uint16& len);
488  int readTableParts(char* buf, Uint32 part, Uint32 count);
489  int readTablePart(char* buf, Uint32 part, Uint16& len);
490  int readEventParts(char* buf, Uint32 part, Uint32 count);
491  int readEventPart(char* buf, Uint32 part, Uint16& len);
492  int insertParts(const char* buf, Uint32 part, Uint32 count);
493  int insertPart(const char* buf, Uint32 part, const Uint16& len);
494  int updateParts(const char* buf, Uint32 part, Uint32 count);
495  int updatePart(const char* buf, Uint32 part, const Uint16& len);
496  int deletePartsThrottled(Uint32 part, Uint32 count);
497  int deleteParts(Uint32 part, Uint32 count);
498  int deletePartsUnknown(Uint32 part);
499  // pending ops
500  int executePendingBlobReads();
501  int executePendingBlobWrites();
502  // callbacks
503  int invokeActiveHook();
504  // blob handle maintenance
505  int atPrepare(NdbTransaction* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn);
506  int atPrepareNdbRecord(NdbTransaction* aCon, NdbOperation* anOp,
507  const NdbColumnImpl* aColumn,
508  const NdbRecord *key_record, const char *key_row);
509  int atPrepareNdbRecordTakeover(NdbTransaction* aCon, NdbOperation* anOp,
510  const NdbColumnImpl* aColumn,
511  const char *keyinfo, Uint32 keyinfo_bytes);
512  int atPrepareNdbRecordScan(NdbTransaction* aCon, NdbOperation* anOp,
513  const NdbColumnImpl* aColumn);
514  int atPrepareCommon(NdbTransaction* aCon, NdbOperation* anOp,
515  const NdbColumnImpl* aColumn);
516  int atPrepare(NdbEventOperationImpl* anOp, NdbEventOperationImpl* aBlobOp, const NdbColumnImpl* aColumn, int version);
517  int prepareColumn();
518  int preExecute(NdbTransaction::ExecType anExecType, bool& batch);
519  int postExecute(NdbTransaction::ExecType anExecType);
520  int preCommit();
521  int atNextResult();
522  int atNextResultNdbRecord(const char *keyinfo, Uint32 keyinfo_bytes);
523  int atNextResultCommon();
524  int atNextEvent();
525  // errors
526  void setErrorCode(int anErrorCode, bool invalidFlag = false);
527  void setErrorCode(NdbOperation* anOp, bool invalidFlag = false);
528  void setErrorCode(NdbEventOperationImpl* anOp, bool invalidFlag = false);
529  // list stuff
530  void next(NdbBlob* obj) { theNext= obj;}
531  NdbBlob* next() { return theNext;}
532  friend struct Ndb_free_list_t<NdbBlob>;
533 
534  NdbBlob(const NdbBlob&); // Not impl.
535  NdbBlob&operator=(const NdbBlob&);
536 };
537 
538 #endif