engine/sqlite/src/vdbeblob.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2007 May 1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** This file contains code used to implement incremental BLOB I/O.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** $Id: vdbeblob.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
#include "vdbeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
** Valid sqlite3_blob* handles point to Incrblob structures.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
typedef struct Incrblob Incrblob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
struct Incrblob {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
  int flags;              /* Copy of "flags" passed to sqlite3_blob_open() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
  int nByte;              /* Size of open blob, in bytes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
  int iOffset;            /* Byte offset of blob in cursor data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
  BtCursor *pCsr;         /* Cursor pointing at blob row */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
  sqlite3_stmt *pStmt;    /* Statement holding cursor open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
  sqlite3 *db;            /* The associated database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
** Open a blob handle.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
EXPORT_C int sqlite3_blob_open(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
  sqlite3* db,            /* The database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
  const char *zDb,        /* The attached database containing the blob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
  const char *zTable,     /* The table containing the blob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  const char *zColumn,    /* The column containing the blob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  sqlite_int64 iRow,      /* The row containing the glob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  int flags,              /* True -> read/write access, false -> read-only */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  sqlite3_blob **ppBlob   /* Handle for accessing the blob returned here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  int nAttempt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
  int iCol;               /* Index of zColumn in row-record */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  /* This VDBE program seeks a btree cursor to the identified 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
  ** db/table/row entry. The reason for using a vdbe program instead
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
  ** of writing code to use the b-tree layer directly is that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
  ** vdbe program will take advantage of the various transaction,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
  ** locking and error handling infrastructure built into the vdbe.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
  ** After seeking the cursor, the vdbe executes an OP_Callback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
  ** Code external to the Vdbe then "borrows" the b-tree cursor and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
  ** uses it to implement the blob_read(), blob_write() and 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
  ** blob_bytes() functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
  ** The sqlite3_blob_close() function finalizes the vdbe program,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
  ** which closes the b-tree cursor and (possibly) commits the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
  ** transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
  static const VdbeOpList openBlob[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
    {OP_Transaction, 0, 0, 0},     /* 0: Start a transaction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
    {OP_VerifyCookie, 0, 0, 0},    /* 1: Check the schema cookie */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
    {OP_Integer, 0, 0, 0},         /* 2: Database number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
    /* One of the following two instructions is replaced by an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
    ** OP_Noop before exection.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
    {OP_OpenRead, 0, 0, 0},        /* 3: Open cursor 0 for reading */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
    {OP_OpenWrite, 0, 0, 0},       /* 4: Open cursor 0 for read/write */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
    {OP_SetNumColumns, 0, 0, 0},   /* 5: Num cols for cursor */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
    {OP_Variable, 1, 0, 0},        /* 6: Push the rowid to the stack */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
    {OP_NotExists, 0, 10, 0},      /* 7: Seek the cursor */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
    {OP_Column, 0, 0, 0},          /* 8  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
    {OP_Callback, 0, 0, 0},        /* 9  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
    {OP_Close, 0, 0, 0},           /* 10 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
    {OP_Halt, 0, 0, 0},            /* 11 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
  Vdbe *v = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  char zErr[128];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
  zErr[0] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
  sqlite3_mutex_enter(db->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
  do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
    Parse sParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
    Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
    memset(&sParse, 0, sizeof(Parse));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
    sParse.db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
    rc = sqlite3SafetyOn(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
      sqlite3_mutex_leave(db->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
    sqlite3BtreeEnterAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
    pTab = sqlite3LocateTable(&sParse, zTable, zDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
    if( !pTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
      if( sParse.zErrMsg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
        sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
      sqlite3_free(sParse.zErrMsg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
      rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
      sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
      sqlite3BtreeLeaveAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
      goto blob_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
    /* Now search pTab for the exact column. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
    for(iCol=0; iCol < pTab->nCol; iCol++) {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
      if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
    if( iCol==pTab->nCol ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
      sqlite3_snprintf(sizeof(zErr), zErr, "no such column: \"%s\"", zColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
      rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
      sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
      sqlite3BtreeLeaveAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
      goto blob_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
    /* If the value is being opened for writing, check that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
    ** column is not indexed. It is against the rules to open an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
    ** indexed column for writing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
    if( flags ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
      Index *pIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
        int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
        for(j=0; j<pIdx->nColumn; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
          if( pIdx->aiColumn[j]==iCol ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
            sqlite3_snprintf(sizeof(zErr), zErr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
                             "cannot open indexed column for writing");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
            rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
            sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
            sqlite3BtreeLeaveAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
            goto blob_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
    v = sqlite3VdbeCreate(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
    if( v ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
      sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
      /* Configure the OP_Transaction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
      sqlite3VdbeChangeP1(v, 0, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
      sqlite3VdbeChangeP2(v, 0, (flags ? 1 : 0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
      /* Configure the OP_VerifyCookie */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
      sqlite3VdbeChangeP1(v, 1, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
      sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
      /* Make sure a mutex is held on the table to be accessed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
      sqlite3VdbeUsesBtree(v, iDb); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
      /* Configure the db number pushed onto the stack */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
      sqlite3VdbeChangeP1(v, 2, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
      ** parameter of the other to pTab->tnum. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
      sqlite3VdbeChangeToNoop(v, (flags ? 3 : 4), 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
      sqlite3VdbeChangeP2(v, (flags ? 4 : 3), pTab->tnum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
      /* Configure the OP_SetNumColumns. Configure the cursor to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
      ** think that the table has one more column than it really
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
      ** does. An OP_Column to retrieve this imaginary column will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
      ** always return an SQL NULL. This is useful because it means
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
      ** we can invoke OP_Column to fill in the vdbe cursors type 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
      ** and offset cache without causing any IO.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
      sqlite3VdbeChangeP2(v, 5, pTab->nCol+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
      if( !db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
        sqlite3VdbeMakeReady(v, 1, 0, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
    sqlite3BtreeLeaveAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
    rc = sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
    if( rc!=SQLITE_OK || db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
      goto blob_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
    sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
    rc = sqlite3_step((sqlite3_stmt *)v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
    if( rc!=SQLITE_ROW ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
      nAttempt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
      rc = sqlite3_finalize((sqlite3_stmt *)v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
      sqlite3_snprintf(sizeof(zErr), zErr, sqlite3_errmsg(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
      v = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
  } while( nAttempt<5 && rc==SQLITE_SCHEMA );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
  if( rc==SQLITE_ROW ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
    /* The row-record has been opened successfully. Check that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
    ** column in question contains text or a blob. If it contains
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
    ** text, it is up to the caller to get the encoding right.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
    Incrblob *pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
    u32 type = v->apCsr[0]->aType[iCol];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
    if( type<12 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
      sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
          type==0?"null": type==7?"real": "integer"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
      );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
      rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
      goto blob_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
    pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
    if( db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
      sqlite3_free(pBlob);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
      goto blob_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
    pBlob->flags = flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
    pBlob->pCsr =  v->apCsr[0]->pCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
    sqlite3BtreeEnterCursor(pBlob->pCsr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
    sqlite3BtreeCacheOverflow(pBlob->pCsr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
    sqlite3BtreeLeaveCursor(pBlob->pCsr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
    pBlob->pStmt = (sqlite3_stmt *)v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
    pBlob->iOffset = v->apCsr[0]->aOffset[iCol];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
    pBlob->nByte = sqlite3VdbeSerialTypeLen(type);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
    pBlob->db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
    *ppBlob = (sqlite3_blob *)pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
    rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  }else if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
    sqlite3_snprintf(sizeof(zErr), zErr, "no such rowid: %lld", iRow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
    rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
blob_open_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
  zErr[sizeof(zErr)-1] = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
  if( rc!=SQLITE_OK || db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
    sqlite3_finalize((sqlite3_stmt *)v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
  sqlite3Error(db, rc, (rc==SQLITE_OK?0:zErr));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
  rc = sqlite3ApiExit(db, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  sqlite3_mutex_leave(db->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
** Close a blob handle that was previously created using
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
** sqlite3_blob_open().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
EXPORT_C int sqlite3_blob_close(sqlite3_blob *pBlob){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  Incrblob *p = (Incrblob *)pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
  rc = sqlite3_finalize(p->pStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
** Perform a read or write operation on a blob
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
static int blobReadWrite(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
  sqlite3_blob *pBlob, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
  void *z, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
  int n, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
  int iOffset, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  int (*xCall)(BtCursor*, u32, u32, void*)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  Incrblob *p = (Incrblob *)pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  Vdbe *v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
  sqlite3 *db = p->db;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
  /* Request is out of range. Return a transient error. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  if( (iOffset+n)>p->nByte ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  sqlite3_mutex_enter(db->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  /* If there is no statement handle, then the blob-handle has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  ** already been invalidated. Return SQLITE_ABORT in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
  v = (Vdbe*)p->pStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
  if( v==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
    rc = SQLITE_ABORT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
    /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
    ** returned, clean-up the statement handle.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
    assert( db == v->db );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
    sqlite3BtreeEnterCursor(p->pCsr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
    rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
    sqlite3BtreeLeaveCursor(p->pCsr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
    if( rc==SQLITE_ABORT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
      sqlite3VdbeFinalize(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
      p->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
      db->errCode = rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
      v->rc = rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  rc = sqlite3ApiExit(db, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  sqlite3_mutex_leave(db->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
** Read data from a blob handle.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
EXPORT_C int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
  return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
** Write data to a blob handle.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
EXPORT_C int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
  return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
** Query a blob handle for the size of the data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
** so no mutex is required for access.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
EXPORT_C int sqlite3_blob_bytes(sqlite3_blob *pBlob){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
  Incrblob *p = (Incrblob *)pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
  return p->nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
#endif /* #ifndef SQLITE_OMIT_INCRBLOB */