Fossil

Check-in [4fdf0ac2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Cleanups in the th1 query statement finalization.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | th1-query-api
Files: files | file ages | folders
SHA1:4fdf0ac279a979f3313945c63d950749cb40d9ab
User & Date: stephan 2012-07-14 11:15:05
Context
2012-07-14
11:54
Refactored th1's output mechanism: moved output API to Th_Vtab to support arbitrary output destinations, the intention being to be able to support an output buffer stack analog to PHP's ob_start(), ob_get_clean() and friends. check-in: 3c0209f5 user: stephan tags: th1-query-api
11:15
Cleanups in the th1 query statement finalization. check-in: 4fdf0ac2 user: stephan tags: th1-query-api
11:14
Added g.interp cleanup to db_close() to allow th1 to clean up any statement handles it creates. check-in: 008a16c0 user: stephan tags: th1-query-api
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/th.c.

1656
1657
1658
1659
1660
1661
1662

1663





1664

1665
1666
1667
1668
1669
1670
1671
....
2657
2658
2659
2660
2661
2662
2663
2664
2665

2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
  /* Delete all registered commands and the command hash-table itself. */
  Th_HashIterate(interp, interp->paCmd, thFreeCommand, (void *)interp);
  Th_HashDelete(interp, interp->paCmd);

#ifdef TH_USE_SQLITE
  {
    int i;

    for( i = 0; i < interp->stmt.nStmt; ++i ){





      Th_FinalizeStmt( interp, i );

    }
    Th_Free(interp, interp->stmt.aStmt);
  }
#endif
  
  /* Delete the interpreter structure itself. */
  Th_Free(interp, (void *)interp);
................................................................................
  int rc = 0;
  assert( stmtId>0 && stmtId<=interp->stmt.nStmt );
  st = interp->stmt.aStmt[stmtId-1];
  if(NULL != st){
    interp->stmt.aStmt[stmtId-1] = NULL;
    sqlite3_finalize(st);
    return 0;
  }
  return 1;

}

sqlite3_stmt * Th_GetStmt(Th_Interp *interp, int stmtId){
  return ((stmtId<1) || (stmtId > interp->stmt.nStmt))
    ? NULL
    : interp->stmt.aStmt[stmtId-1];
}

#endif
/* end TH_USE_SQLITE */







>

>
>
>
>
>
|
>







 







|
|
>










1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
....
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
  /* Delete all registered commands and the command hash-table itself. */
  Th_HashIterate(interp, interp->paCmd, thFreeCommand, (void *)interp);
  Th_HashDelete(interp, interp->paCmd);

#ifdef TH_USE_SQLITE
  {
    int i;
    sqlite3_stmt * st;
    for( i = 0; i < interp->stmt.nStmt; ++i ){
      st = interp->stmt.aStmt[i];
      if(NULL != st){
        fossil_warning("Auto-finalizing unfinalized query_prepare "
                       "statement id #%d: %s",
                       i+1, sqlite3_sql(st));
        Th_FinalizeStmt( interp, i+1 );
      }
    }
    Th_Free(interp, interp->stmt.aStmt);
  }
#endif
  
  /* Delete the interpreter structure itself. */
  Th_Free(interp, (void *)interp);
................................................................................
  int rc = 0;
  assert( stmtId>0 && stmtId<=interp->stmt.nStmt );
  st = interp->stmt.aStmt[stmtId-1];
  if(NULL != st){
    interp->stmt.aStmt[stmtId-1] = NULL;
    sqlite3_finalize(st);
    return 0;
  }else{
    return 1;
  }
}

sqlite3_stmt * Th_GetStmt(Th_Interp *interp, int stmtId){
  return ((stmtId<1) || (stmtId > interp->stmt.nStmt))
    ? NULL
    : interp->stmt.aStmt[stmtId-1];
}

#endif
/* end TH_USE_SQLITE */

Changes to src/th.h.

191
192
193
194
195
196
197











198








199






200
201
202

typedef struct Th_SubCommand {char *zName; Th_CommandProc xProc;} Th_SubCommand;
int Th_CallSubCommand(Th_Interp*,void*,int,const char**,int*,Th_SubCommand*);

#ifdef TH_USE_SQLITE
#include "stddef.h" /* size_t */
extern void *fossil_realloc(void *p, size_t n);











int Th_AddStmt(Th_Interp *interp, sqlite3_stmt * pStmt);








int Th_FinalizeStmt(Th_Interp *interp, int stmtId);






sqlite3_stmt * Th_GetStmt(Th_Interp *interp, int stmtId);
#endif








>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>

>
>
>
>
>
>



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

typedef struct Th_SubCommand {char *zName; Th_CommandProc xProc;} Th_SubCommand;
int Th_CallSubCommand(Th_Interp*,void*,int,const char**,int*,Th_SubCommand*);

#ifdef TH_USE_SQLITE
#include "stddef.h" /* size_t */
extern void *fossil_realloc(void *p, size_t n);

/*
** Adds the given prepared statement to the interpreter. Returns the
** statements opaque identifier (a positive value). Ownerships of
** pStmt is transfered to interp and it must be cleaned up by the
** client by calling Th_FinalizeStmt(), passing it the value returned
** by this function.
**
** If interp is destroyed before all statements are finalized,
** it will finalize them but may emit a warning message.
*/
int Th_AddStmt(Th_Interp *interp, sqlite3_stmt * pStmt);

/*
** Expects stmtId to be a statement identifier returned by
** Th_AddStmt(). On success, finalizes the statement and returns 0.
** On error (statement not found) non-0 is returned. After this
** call, some subsequent call to Th_AddStmt() may return the
** same statement ID.
*/
int Th_FinalizeStmt(Th_Interp *interp, int stmtId);

/*
** Fetches the statement with the given ID, as returned by
** Th_AddStmt(). Returns NULL if stmtId does not refer (or no longer
** refers) to a statement added via Th_AddStmt().
*/
sqlite3_stmt * Th_GetStmt(Th_Interp *interp, int stmtId);
#endif

Changes to test/th1-query-api-1.th1.

130
131
132
133
134
135
136



































137
138

set exception 0
catch {
    argv_getint noSuchOptionAndNoDefault
} exception
puts exception = $exception "\n"




































puts "If you got this far, you win!\n"
</th1>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

set exception 0
catch {
    argv_getint noSuchOptionAndNoDefault
} exception
puts exception = $exception "\n"


proc multiStmt {} {
    set max 5
    set i 0
    set s(0) 0
    for {set i 0} {$i < $max} {incr i} {
       set s($i) [query_prepare "SELECT $i"]
       puts "s($i) = $s($i)\n"
    }
    for {set i 0} {$i < $max} {incr i} {
       query_step $s($i)
    }
    for {set i 0} {$i < $max} {incr i} {
       puts "closing stmt $s($i)\n"
       query_finalize $s($i)
    }

    puts "Preparing again\n"

    for {set i 0} {$i < $max} {incr i} {
       set s($i) [query_prepare "SELECT $i"]
       puts "s($i) = $s($i)\n"
    }
    for {set i 0} {$i < $max} {incr i} {
       query_step $s($i)
    }
    puts "Closing again\n"

    for {set i 0} {$i < $max} {incr i} {
       puts "closing stmt $s($i)\n"
       query_finalize $s($i)
    }
}
multiStmt

puts "If you got this far, you win!\n"
</th1>