SQLite

Check-in [f2643315bb]
Login

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

Overview
Comment:Improved \n and \r escapes in the ext/misc/dbdump.c utility function. The implementation of dbdump.c now matches the implementation in the CLI.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f2643315bb41a71eebd79f5d671f9163187e299a52ff8a481186f1e8fa7e5262
User & Date: drh 2017-04-12 17:38:24.004
Context
2017-04-12
17:50
Update fts5 to support "<colset> : ( <expr> )" for column filtering, as well as "<colset> : NEAR(...)" and "<colset> : <phrase>". (check-in: c847543f8b user: dan tags: trunk)
17:38
Improved \n and \r escapes in the ext/misc/dbdump.c utility function. The implementation of dbdump.c now matches the implementation in the CLI. (check-in: f2643315bb user: drh tags: trunk)
2017-04-11
20:48
Avoid updating unaffected indexes on a table as part of an UPDATE that requires foreign key processing in some cases. (check-in: 7aae5c0f99 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/misc/dbdump.c.
320
321
322
323
324
325
326

327
328



















329
330

331
332
333
334
335
336
337
338
339
340
341








342









343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364

365
366
367


368

369
370
371
372

373
374

375
376
377
378
379
380
381
  z = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  p->xCallback(z, p->pArg);
  sqlite3_free(z);
}

/*

** Output the given string as a quoted string using SQL quoting conventions.
**



















** The "\n" and "\r" characters are converted to char(10) and char(13)
** to prevent them from being transformed by end-of-line translators.

*/
static void output_quoted_string(DState *p, const unsigned char *z){
  int i;
  char c;
  int inQuote = 0;
  int bStarted = 0;

  for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
  if( c==0 ){
    output_formatted(p, "'%s'", z);
    return;








  }









  while( *z ){
    for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
    if( c=='\'' ) i++;
    if( i ){
      if( !inQuote ){
        if( bStarted ) p->xCallback("||", p->pArg);
        p->xCallback("'", p->pArg);
        inQuote = 1;
      }
      output_formatted(p, "%.*s", i, z);
      z += i;
      bStarted = 1;
    }
    if( c=='\'' ){
      p->xCallback("'", p->pArg);
      continue;
    }
    if( inQuote ){
      p->xCallback("'", p->pArg);
      inQuote = 0;
    }

    if( c==0 ){

      break;
    }
    for(i=0; (c = z[i])=='\r' || c=='\n'; i++){


      if( bStarted ) p->xCallback("||", p->pArg);

      output_formatted(p, "char(%d)", c);
      bStarted = 1;
    }
    z += i;

  }
  if( inQuote ) p->xCallback("'", p->pArg);

}

/*
** This is an sqlite3_exec callback routine used for dumping the database.
** Each row received by this callback consists of a table name,
** the table type ("index" or "table") and SQL to create the table.
** This routine should print text sufficient to recreate the table.







>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>

|


<
<
<


|
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
|
|
|
<
<
<
<
<
|
|
<
|
|
|
|
|
|
<
|
|
>
|
>
|
|
<
>
>
|
>
|
<

|
>
|
<
>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381





382
383

384
385
386
387
388
389

390
391
392
393
394
395
396

397
398
399
400
401

402
403
404
405

406
407
408
409
410
411
412
413
  z = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  p->xCallback(z, p->pArg);
  sqlite3_free(z);
}

/*
** Find a string that is not found anywhere in z[].  Return a pointer
** to that string.
**
** Try to use zA and zB first.  If both of those are already found in z[]
** then make up some string and store it in the buffer zBuf.
*/
static const char *unused_string(
  const char *z,                    /* Result must not appear anywhere in z */
  const char *zA, const char *zB,   /* Try these first */
  char *zBuf                        /* Space to store a generated string */
){
  unsigned i = 0;
  if( strstr(z, zA)==0 ) return zA;
  if( strstr(z, zB)==0 ) return zB;
  do{
    sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
  }while( strstr(z,zBuf)!=0 );
  return zBuf;
}

/*
** Output the given string as a quoted string using SQL quoting conventions.
** Additionallly , escape the "\n" and "\r" characters so that they do not
** get corrupted by end-of-line translation facilities in some operating
** systems.
*/
static void output_quoted_escaped_string(DState *p, const char *z){
  int i;
  char c;



  for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
  if( c==0 ){
    output_formatted(p,"'%s'",z);
  }else{
    const char *zNL = 0;
    const char *zCR = 0;
    int nNL = 0;
    int nCR = 0;
    char zBuf1[20], zBuf2[20];
    for(i=0; z[i]; i++){
      if( z[i]=='\n' ) nNL++;
      if( z[i]=='\r' ) nCR++;
    }
    if( nNL ){
      p->xCallback("replace(", p->pArg);
      zNL = unused_string(z, "\\n", "\\012", zBuf1);
    }
    if( nCR ){
      p->xCallback("replace(", p->pArg);
      zCR = unused_string(z, "\\r", "\\015", zBuf2);
    }
    p->xCallback("'", p->pArg);
    while( *z ){
      for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
      if( c=='\'' ) i++;
      if( i ){





        output_formatted(p, "%.*s", i, z);
        z += i;

      }
      if( c=='\'' ){
        p->xCallback("'", p->pArg);
        continue;
      }
      if( c==0 ){

        break;
      }
      z++;
      if( c=='\n' ){
        p->xCallback(zNL, p->pArg);
        continue;
      }

      p->xCallback(zCR, p->pArg);
    }
    p->xCallback("'", p->pArg);
    if( nCR ){
      output_formatted(p, ",'%s',char(13))", zCR);

    }
    if( nNL ){
      output_formatted(p, ",'%s',char(10))", zNL);
    }

  }
}

/*
** This is an sqlite3_exec callback routine used for dumping the database.
** Each row received by this callback consists of a table name,
** the table type ("index" or "table") and SQL to create the table.
** This routine should print text sufficient to recreate the table.
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
              break;
            }
            case SQLITE_NULL: {
              p->xCallback("NULL", p->pArg);
              break;
            }
            case SQLITE_TEXT: {

              output_quoted_string(p, sqlite3_column_text(pStmt,i));
              break;
            }
            case SQLITE_BLOB: {
              int nByte = sqlite3_column_bytes(pStmt,i);
              unsigned char *a = (unsigned char*)sqlite3_column_blob(pStmt,i);
              int j;
              p->xCallback("x'", p->pArg);







>
|







523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
              break;
            }
            case SQLITE_NULL: {
              p->xCallback("NULL", p->pArg);
              break;
            }
            case SQLITE_TEXT: {
              output_quoted_escaped_string(p, 
                   (const char*)sqlite3_column_text(pStmt,i));
              break;
            }
            case SQLITE_BLOB: {
              int nByte = sqlite3_column_bytes(pStmt,i);
              unsigned char *a = (unsigned char*)sqlite3_column_blob(pStmt,i);
              int j;
              p->xCallback("x'", p->pArg);