Login
Check-in [6c18a25f11]
Login

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

Overview
Comment:Switched from :memory: to "" (temp) DB for the main db, other minor cleanups.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6c18a25f11b5f656e9a7f811400c369ed7e41508
User & Date: stephan 2014-10-27 20:42:33.450
Context
2014-10-28
08:48
merged in dave. reminder to selves: the merge initially elides some of the content dave previously merged from trunk, and we are not sure why (required manual merge intervention, despite not having any conflicts). check-in: 61233f6026 user: stephan tags: trunk
02:14
merged in stephan's various changes check-in: c2d7402366 user: dave tags: dave
2014-10-27
20:42
Switched from :memory: to "" (temp) DB for the main db, other minor cleanups. check-in: 6c18a25f11 user: stephan tags: trunk
18:24
Added (-E SQL|FILENAME) to f-query, which uses a multi-exec db call instead of prepare/step, so that we can feed it an arbitrary amount of non-SELECT queries (in -E mode any SELECT results do not get output). check-in: 6c907b2a70 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to include/fossil-scm/fossil-db.h.
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
     update this state to include error info from the driver.
     fsl_cx APIs which fail at the DB level uplift this (using
     fsl_error_move()) so that they can pass it on up the call chain.
  */
  fsl_error error;

  /**
     Holds the file name used when opening this db. Might not refer
     to a real file (e.g. might be ":memory:").

  */
  char * filename;

  /**
     Holds the database name for use in creating queries.
     Might or might not be set/needed, depending on
     the context.







|
|
>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
     update this state to include error info from the driver.
     fsl_cx APIs which fail at the DB level uplift this (using
     fsl_error_move()) so that they can pass it on up the call chain.
  */
  fsl_error error;

  /**
     Holds the file name used when opening this db. Might not refer to
     a real file (e.g. might be ":memory:" or "" (similar to
     ":memory:" but may swap to temp storage).
  */
  char * filename;

  /**
     Holds the database name for use in creating queries.
     Might or might not be set/needed, depending on
     the context.
1385
1386
1387
1388
1389
1390
1391

1392
1393




1394
1395
1396
1397
1398
1399
1400
   FSL_RC_NOT_FOUND. The existence of FSL_OPEN_F_CREATE in the
   flags will cause this routine to try to create the file if
   needed. If conflicting flags are specified (e.g. FSL_OPEN_F_RO
   and FSL_OPEN_F_RWC) then which one takes precedence is
   unspecified and possibly unpredictable.

   As a special case, if dbFile is ":memory:" (for an in-memory

   database) then it is is passed through without any
   filesystem-related checks and the openFlags are ignored.





   Returns FSL_RC_MISUSE if !db, !dbFile, !*dbFile, or if db->dbh
   is not NULL (i.e. if it is already opened or its memory was
   default-initialized (use fsl_db_empty to cleanly copy-initialize
   new stack-allocated instances).

   On error db->dbh will be NULL, but db->error might contain error







>
|
|
>
>
>
>







1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
   FSL_RC_NOT_FOUND. The existence of FSL_OPEN_F_CREATE in the
   flags will cause this routine to try to create the file if
   needed. If conflicting flags are specified (e.g. FSL_OPEN_F_RO
   and FSL_OPEN_F_RWC) then which one takes precedence is
   unspecified and possibly unpredictable.

   As a special case, if dbFile is ":memory:" (for an in-memory
   database) or "" (empty string, for a "temporary" database) then it
   is is passed through without any filesystem-related checks and the
   openFlags are ignored.

   See this page for the differences between ":memory:" and "":

   https://www.sqlite.org/inmemorydb.html

   Returns FSL_RC_MISUSE if !db, !dbFile, !*dbFile, or if db->dbh
   is not NULL (i.e. if it is already opened or its memory was
   default-initialized (use fsl_db_empty to cleanly copy-initialize
   new stack-allocated instances).

   On error db->dbh will be NULL, but db->error might contain error
Changes to include/fossil-scm/fossil-internal.h.
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
  /**
     Marker which tells us whether fsl_cx_finalize() needs
     to fsl_free() this instance or not.
  */
  void const * allocStamp;

  /**

     A :memory: db to work around open-vs-attach-vs-main-vs-real-name
     problems wrt to the repo/ckout/config dbs. This db handle gets
     opened automatically at startup and all others which a fsl_cx
     manages get ATTACHed to it.
  */
  fsl_db dbMem;

  /**
     Holds info directly related to a checkout database.
  */
  struct {







>
|
|
|
|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  /**
     Marker which tells us whether fsl_cx_finalize() needs
     to fsl_free() this instance or not.
  */
  void const * allocStamp;

  /**
     A ":memory:" (or "") db to work around
     open-vs-attach-vs-main-vs-real-name problems wrt to the
     repo/ckout/config dbs. This db handle gets opened automatically
     at startup and all others which a fsl_cx manages get ATTACHed to
     it.
  */
  fsl_db dbMem;

  /**
     Holds info directly related to a checkout database.
  */
  struct {
303
304
305
306
307
308
309
310
311
312
313





314
315
316
317
318
319
320
    char * dir;
    /**
       Optimization: fsl_strlen() of dir. Guaranteed to be set to
       dir's length if dir is not NULL.
    */
    fsl_size_t dirLen;
    /**
       The rid of the current checkout. May be 0 for an empt
       repo/checkout. Must be negative if not yet known.
    */
    fsl_id_t rid;





    fsl_uuid_str uuid;
  } ckout;

  /**
     Holds info directly related to a repo database.
  */
  struct {







|



>
>
>
>
>







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    char * dir;
    /**
       Optimization: fsl_strlen() of dir. Guaranteed to be set to
       dir's length if dir is not NULL.
    */
    fsl_size_t dirLen;
    /**
       The rid of the current checkout. May be 0 for an empty
       repo/checkout. Must be negative if not yet known.
    */
    fsl_id_t rid;

    /**
       The UUID of the current checkout. Only set if this->rid
       is positive.
    */
    fsl_uuid_str uuid;
  } ckout;

  /**
     Holds info directly related to a repo database.
  */
  struct {
Changes to s2/unit2/000-200-context.s2.
22
23
24
25
26
27
28
29


30
31
32
33
34
35
36
    assert DB.name === 'main' /* this is our "main" db, but it
                                 gets attached with this
                                 name/alias */;
    assert DB.checkout.name = 'ckout';
    assert DB.repo.name === 'repo' /* even though it's actually
                                      the same sqlite db handle as
                                      the checkout! */;
    assert DB.filename === ':memory:';


    assert DB.checkout.filename;
    assert DB.filename !== DB.checkout.filename;
    assert DB.repo.filename;
    assert DB.repo.filename !== DB.checkout.filename;

    assert !DB.config;
    f.openConfig();







|
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    assert DB.name === 'main' /* this is our "main" db, but it
                                 gets attached with this
                                 name/alias */;
    assert DB.checkout.name = 'ckout';
    assert DB.repo.name === 'repo' /* even though it's actually
                                      the same sqlite db handle as
                                      the checkout! */;
    assert DB.filename === ':memory:'
        || DB.filename === '' /* similar mechanism with different
                                 semantics vis-a-vis temp storage */;
    assert DB.checkout.filename;
    assert DB.filename !== DB.checkout.filename;
    assert DB.repo.filename;
    assert DB.repo.filename !== DB.checkout.filename;

    assert !DB.config;
    f.openConfig();
Changes to src/fsl_cx.c.
76
77
78
79
80
81
82
83




84
85
86
87
88
89
90
      atexit(sqlite3_reset_auto_extension)
        /* Clean up pseudo-leak valgrind complains about:
           https://www.sqlite.org/c3ref/auto_extension.html */;
      bRegistered = 1;
    }
  }
  f->dbMem.f = f /* so that dbMem gets fsl_xxx() SQL funcs installed. */;
  rc = fsl_db_open( &f->dbMem, ":memory:", 0 );




  if(rc){
    if(f->dbMem.error.code){
      fsl_cx_uplift_db_error(f, &f->dbMem);
    }
  }else{
    f->dbMain = &f->dbMem;
    f->dbMem.role = FSL_DB_ROLE_MAIN;







|
>
>
>
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
      atexit(sqlite3_reset_auto_extension)
        /* Clean up pseudo-leak valgrind complains about:
           https://www.sqlite.org/c3ref/auto_extension.html */;
      bRegistered = 1;
    }
  }
  f->dbMem.f = f /* so that dbMem gets fsl_xxx() SQL funcs installed. */;
  rc = fsl_db_open( &f->dbMem, "", 0 );
  if(!rc){
    /* Attempt to ensure that the TEMP tables/indexes use FILE storage. */
    rc = fsl_db_exec(&f->dbMem, "PRAGMA temp_store=FILE;");
  }
  if(rc){
    if(f->dbMem.error.code){
      fsl_cx_uplift_db_error(f, &f->dbMem);
    }
  }else{
    f->dbMain = &f->dbMem;
    f->dbMem.role = FSL_DB_ROLE_MAIN;
188
189
190
191
192
193
194

195
196
197
198
199
200
201
    f->allocStamp = allocStamp;
  }
}

void fsl_cx_err_reset(fsl_cx * f){
  if(f){
    fsl_error_reset(&f->error);

    fsl_db_err_reset(&f->repo.db);
    fsl_db_err_reset(&f->config.db);
    fsl_db_err_reset(&f->ckout.db);
  }
}

int fsl_cx_err_set_e( fsl_cx * f, fsl_error * err ){







>







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    f->allocStamp = allocStamp;
  }
}

void fsl_cx_err_reset(fsl_cx * f){
  if(f){
    fsl_error_reset(&f->error);
    fsl_db_err_reset(&f->dbMem);
    fsl_db_err_reset(&f->repo.db);
    fsl_db_err_reset(&f->config.db);
    fsl_db_err_reset(&f->ckout.db);
  }
}

int fsl_cx_err_set_e( fsl_cx * f, fsl_error * err ){
Changes to src/fsl_db.c.
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
}

int fsl_db_open( fsl_db * db, char const * dbFile,
                 int openFlags ){
  int rc;
  fsl_dbh_t * dbh = NULL;
  int isMem = 0;
  if(!db || !dbFile || !*dbFile) return FSL_RC_MISUSE;
  else if(db->dbh) return FSL_RC_MISUSE;
  else if(!(isMem = (0==fsl_strcmp(":memory:", dbFile)))
          && !(FSL_OPEN_F_CREATE & openFlags)
          && fsl_file_access(dbFile, 0)){
    return fsl_error_set(&db->error, FSL_RC_NOT_FOUND,
                         "DB file not found: %s", dbFile);
  }
  else{
    int sOpenFlags = 0;







|

|







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
}

int fsl_db_open( fsl_db * db, char const * dbFile,
                 int openFlags ){
  int rc;
  fsl_dbh_t * dbh = NULL;
  int isMem = 0;
  if(!db || !dbFile) return FSL_RC_MISUSE;
  else if(db->dbh) return FSL_RC_MISUSE;
  else if(!(isMem = (!*dbFile || 0==fsl_strcmp(":memory:", dbFile)))
          && !(FSL_OPEN_F_CREATE & openFlags)
          && fsl_file_access(dbFile, 0)){
    return fsl_error_set(&db->error, FSL_RC_NOT_FOUND,
                         "DB file not found: %s", dbFile);
  }
  else{
    int sOpenFlags = 0;
1368
1369
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
                           "sqlite code #%d",
                           dbFile, rc);
      }
      /* MARKER(("Error msg: %s\n", (char const *)db->error.msg.mem)); */
      goto end;
    }else{
      assert(!db->filename);
      if(':'==*dbFile){
        /* assume ":memory:" or some such: don't canonicalize it. */

        db->filename = fsl_strdup(dbFile);
      }else{
        fsl_buffer tmp = fsl_buffer_empty;
        rc = fsl_file_canonical_name(dbFile, &tmp, 0);
        if(!rc){
          db->filename = (char *)tmp.mem
            /* transfering ownership */;







|
|
>







1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
                           "sqlite code #%d",
                           dbFile, rc);
      }
      /* MARKER(("Error msg: %s\n", (char const *)db->error.msg.mem)); */
      goto end;
    }else{
      assert(!db->filename);
      if(!*dbFile || ':'==*dbFile){
        /* assume "" or ":memory:" or some such: don't canonicalize it,
           but copy it nonetheless for consistency. */
        db->filename = fsl_strdup(dbFile);
      }else{
        fsl_buffer tmp = fsl_buffer_empty;
        rc = fsl_file_canonical_name(dbFile, &tmp, 0);
        if(!rc){
          db->filename = (char *)tmp.mem
            /* transfering ownership */;