~ubuntu-branches/ubuntu/intrepid/digikam/intrepid

« back to all changes in this revision

Viewing changes to digikam/sqlite/table.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2008-07-17 20:25:39 UTC
  • mfrom: (1.3.2 upstream) (37 hardy)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080717202539-1bw3w3nrsso7yj4z
* New upstream release
  - digiKam 0.9.4 Release Plan (KDE3) ~ 13 July 08 (Closes: #490144)
* DEB_CONFIGURE_EXTRA_FLAGS := --without-included-sqlite3
* Debhelper compatibility level V7
* Install pixmaps in debian/*.install
* Add debian/digikam.lintian-overrides

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** 2001 September 15
3
 
**
4
 
** The author disclaims copyright to this source code.  In place of
5
 
** a legal notice, here is a blessing:
6
 
**
7
 
**    May you do good and not evil.
8
 
**    May you find forgiveness for yourself and forgive others.
9
 
**    May you share freely, never taking more than you give.
10
 
**
11
 
*************************************************************************
12
 
** This file contains the sqlite_get_table() and sqlite_free_table()
13
 
** interface routines.  These are just wrappers around the main
14
 
** interface routine of sqlite_exec().
15
 
**
16
 
** These routines are in a separate files so that they will not be linked
17
 
** if they are not used.
18
 
*/
19
 
#include <stdlib.h>
20
 
#include <string.h>
21
 
#include "sqliteInt.h"
22
 
 
23
 
/*
24
 
** This structure is used to pass data from sqlite_get_table() through
25
 
** to the callback function is uses to build the result.
26
 
*/
27
 
typedef struct TabResult {
28
 
  char **azResult;
29
 
  char *zErrMsg;
30
 
  int nResult;
31
 
  int nAlloc;
32
 
  int nRow;
33
 
  int nColumn;
34
 
  int nData;
35
 
  int rc;
36
 
} TabResult;
37
 
 
38
 
/*
39
 
** This routine is called once for each row in the result table.  Its job
40
 
** is to fill in the TabResult structure appropriately, allocating new
41
 
** memory as necessary.
42
 
*/
43
 
static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
44
 
  TabResult *p = (TabResult*)pArg;
45
 
  int need;
46
 
  int i;
47
 
  char *z;
48
 
 
49
 
  /* Make sure there is enough space in p->azResult to hold everything
50
 
  ** we need to remember from this invocation of the callback.
51
 
  */
52
 
  if( p->nRow==0 && argv!=0 ){
53
 
    need = nCol*2;
54
 
  }else{
55
 
    need = nCol;
56
 
  }
57
 
  if( p->nData + need >= p->nAlloc ){
58
 
    char **azNew;
59
 
    p->nAlloc = p->nAlloc*2 + need + 1;
60
 
    azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
61
 
    if( azNew==0 ){
62
 
      p->rc = SQLITE_NOMEM;
63
 
      return 1;
64
 
    }
65
 
    p->azResult = azNew;
66
 
  }
67
 
 
68
 
  /* If this is the first row, then generate an extra row containing
69
 
  ** the names of all columns.
70
 
  */
71
 
  if( p->nRow==0 ){
72
 
    p->nColumn = nCol;
73
 
    for(i=0; i<nCol; i++){
74
 
      if( colv[i]==0 ){
75
 
        z = 0;
76
 
      }else{
77
 
        z = malloc( strlen(colv[i])+1 );
78
 
        if( z==0 ){
79
 
          p->rc = SQLITE_NOMEM;
80
 
          return 1;
81
 
        }
82
 
        strcpy(z, colv[i]);
83
 
      }
84
 
      p->azResult[p->nData++] = z;
85
 
    }
86
 
  }else if( p->nColumn!=nCol ){
87
 
    sqliteSetString(&p->zErrMsg,
88
 
       "sqlite_get_table() called with two or more incompatible queries",
89
 
       (char*)0);
90
 
    p->rc = SQLITE_ERROR;
91
 
    return 1;
92
 
  }
93
 
 
94
 
  /* Copy over the row data
95
 
  */
96
 
  if( argv!=0 ){
97
 
    for(i=0; i<nCol; i++){
98
 
      if( argv[i]==0 ){
99
 
        z = 0;
100
 
      }else{
101
 
        z = malloc( strlen(argv[i])+1 );
102
 
        if( z==0 ){
103
 
          p->rc = SQLITE_NOMEM;
104
 
          return 1;
105
 
        }
106
 
        strcpy(z, argv[i]);
107
 
      }
108
 
      p->azResult[p->nData++] = z;
109
 
    }
110
 
    p->nRow++;
111
 
  }
112
 
  return 0;
113
 
}
114
 
 
115
 
/*
116
 
** Query the database.  But instead of invoking a callback for each row,
117
 
** malloc() for space to hold the result and return the entire results
118
 
** at the conclusion of the call.
119
 
**
120
 
** The result that is written to ***pazResult is held in memory obtained
121
 
** from malloc().  But the caller cannot free this memory directly.  
122
 
** Instead, the entire table should be passed to sqlite_free_table() when
123
 
** the calling procedure is finished using it.
124
 
*/
125
 
int sqlite_get_table(
126
 
  sqlite *db,                 /* The database on which the SQL executes */
127
 
  const char *zSql,           /* The SQL to be executed */
128
 
  char ***pazResult,          /* Write the result table here */
129
 
  int *pnRow,                 /* Write the number of rows in the result here */
130
 
  int *pnColumn,              /* Write the number of columns of result here */
131
 
  char **pzErrMsg             /* Write error messages here */
132
 
){
133
 
  int rc;
134
 
  TabResult res;
135
 
  if( pazResult==0 ){ return SQLITE_ERROR; }
136
 
  *pazResult = 0;
137
 
  if( pnColumn ) *pnColumn = 0;
138
 
  if( pnRow ) *pnRow = 0;
139
 
  res.zErrMsg = 0;
140
 
  res.nResult = 0;
141
 
  res.nRow = 0;
142
 
  res.nColumn = 0;
143
 
  res.nData = 1;
144
 
  res.nAlloc = 20;
145
 
  res.rc = SQLITE_OK;
146
 
  res.azResult = malloc( sizeof(char*)*res.nAlloc );
147
 
  if( res.azResult==0 ){
148
 
    return SQLITE_NOMEM;
149
 
  }
150
 
  res.azResult[0] = 0;
151
 
  rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
152
 
  if( res.azResult ){
153
 
    res.azResult[0] = (char*)res.nData;
154
 
  }
155
 
  if( rc==SQLITE_ABORT ){
156
 
    sqlite_free_table(&res.azResult[1]);
157
 
    if( res.zErrMsg ){
158
 
      if( pzErrMsg ){
159
 
        free(*pzErrMsg);
160
 
        *pzErrMsg = res.zErrMsg;
161
 
        sqliteStrRealloc(pzErrMsg);
162
 
      }else{
163
 
        sqliteFree(res.zErrMsg);
164
 
      }
165
 
    }
166
 
    return res.rc;
167
 
  }
168
 
  sqliteFree(res.zErrMsg);
169
 
  if( rc!=SQLITE_OK ){
170
 
    sqlite_free_table(&res.azResult[1]);
171
 
    return rc;
172
 
  }
173
 
  if( res.nAlloc>res.nData ){
174
 
    char **azNew;
175
 
    azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
176
 
    if( azNew==0 ){
177
 
      sqlite_free_table(&res.azResult[1]);
178
 
      return SQLITE_NOMEM;
179
 
    }
180
 
    res.nAlloc = res.nData+1;
181
 
    res.azResult = azNew;
182
 
  }
183
 
  *pazResult = &res.azResult[1];
184
 
  if( pnColumn ) *pnColumn = res.nColumn;
185
 
  if( pnRow ) *pnRow = res.nRow;
186
 
  return rc;
187
 
}
188
 
 
189
 
/*
190
 
** This routine frees the space the sqlite_get_table() malloced.
191
 
*/
192
 
void sqlite_free_table(
193
 
  char **azResult             /* Result returned from from sqlite_get_table() */
194
 
){
195
 
  if( azResult ){
196
 
    int i, n;
197
 
    azResult--;
198
 
    if( azResult==0 ) return;
199
 
    n = (int)azResult[0];
200
 
    for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
201
 
    free(azResult);
202
 
  }
203
 
}