/ Hex Artifact Content
Login

Artifact c3c64e4d5e90e8ba41159232c2189dba4be7b862:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 2d 30 37 2d 32 38  /*.** 2014-07-28
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20  **.** This file 
0180: 69 6d 70 6c 65 6d 65 6e 74 73 20 61 20 75 74 69  implements a uti
0190: 6c 69 74 79 20 70 72 6f 67 72 61 6d 20 74 68 61  lity program tha
01a0: 74 20 77 69 6c 6c 20 6c 6f 61 64 20 6d 61 6e 79  t will load many
01b0: 20 64 69 73 6b 0a 2a 2a 20 66 69 6c 65 73 20 28   disk.** files (
01c0: 61 6c 6c 20 66 69 6c 65 73 20 75 6e 64 65 72 20  all files under 
01d0: 61 20 67 69 76 65 6e 20 64 69 72 65 63 74 6f 72  a given director
01e0: 79 29 20 69 6e 74 6f 20 61 20 46 54 53 20 74 61  y) into a FTS ta
01f0: 62 6c 65 2e 20 20 54 68 69 73 20 69 73 0a 2a 2a  ble.  This is.**
0200: 20 75 73 65 64 20 66 6f 72 20 70 65 72 66 6f 72   used for perfor
0210: 6d 61 6e 63 65 20 74 65 73 74 69 6e 67 20 6f 66  mance testing of
0220: 20 46 54 53 33 2c 20 46 54 53 34 2c 20 61 6e 64   FTS3, FTS4, and
0230: 20 46 54 53 35 2e 0a 2a 2f 0a 0a 23 69 6e 63 6c   FTS5..*/..#incl
0240: 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69  ude <stdio.h>.#i
0250: 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e 68  nclude <stdlib.h
0260: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 63 74 79 70  >.#include <ctyp
0270: 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 61  e.h>.#include <a
0280: 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75 64  ssert.h>.#includ
0290: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e  e <string.h>.#in
02a0: 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a  clude <errno.h>.
02b0: 23 69 6e 63 6c 75 64 65 20 3c 64 69 72 65 6e 74  #include <dirent
02c0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .h>.#include "sq
02d0: 6c 69 74 65 33 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20  lite3.h"../*.** 
02e0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
02f0: 66 20 74 68 65 20 22 72 65 61 64 74 65 78 74 28  f the "readtext(
0300: 58 29 22 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e  X)" SQL function
0310: 2e 20 20 54 68 65 20 65 6e 74 69 72 65 20 63 6f  .  The entire co
0320: 6e 74 65 6e 74 0a 2a 2a 20 6f 66 20 74 68 65 20  ntent.** of the 
0330: 66 69 6c 65 20 6e 61 6d 65 64 20 58 20 69 73 20  file named X is 
0340: 72 65 61 64 20 61 6e 64 20 72 65 74 75 72 6e 65  read and returne
0350: 64 20 61 73 20 61 20 54 45 58 54 20 76 61 6c 75  d as a TEXT valu
0360: 65 2e 20 49 74 20 69 73 20 61 73 73 75 6d 65 64  e. It is assumed
0370: 0a 2a 2a 20 74 68 65 20 66 69 6c 65 20 63 6f 6e  .** the file con
0380: 74 61 69 6e 73 20 55 54 46 2d 38 20 74 65 78 74  tains UTF-8 text
0390: 2e 20 4e 55 4c 4c 20 69 73 20 72 65 74 75 72 6e  . NULL is return
03a0: 65 64 20 69 66 20 74 68 65 20 66 69 6c 65 20 64  ed if the file d
03b0: 6f 65 73 20 6e 6f 74 20 0a 2a 2a 20 65 78 69 73  oes not .** exis
03c0: 74 20 6f 72 20 69 73 20 75 6e 72 65 61 64 61 62  t or is unreadab
03d0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
03e0: 69 64 20 72 65 61 64 66 69 6c 65 46 75 6e 63 28  id readfileFunc(
03f0: 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  .  sqlite3_conte
0400: 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69  xt *context,.  i
0410: 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74  nt argc,.  sqlit
0420: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a  e3_value **argv.
0430: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
0440: 2a 7a 4e 61 6d 65 3b 0a 20 20 46 49 4c 45 20 2a  *zName;.  FILE *
0450: 69 6e 3b 0a 20 20 6c 6f 6e 67 20 6e 49 6e 3b 0a  in;.  long nIn;.
0460: 20 20 76 6f 69 64 20 2a 70 42 75 66 3b 0a 0a 20    void *pBuf;.. 
0470: 20 7a 4e 61 6d 65 20 3d 20 28 63 6f 6e 73 74 20   zName = (const 
0480: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
0490: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d  lue_text(argv[0]
04a0: 29 3b 0a 20 20 69 66 28 20 7a 4e 61 6d 65 3d 3d  );.  if( zName==
04b0: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 6e  0 ) return;.  in
04c0: 20 3d 20 66 6f 70 65 6e 28 7a 4e 61 6d 65 2c 20   = fopen(zName, 
04d0: 22 72 62 22 29 3b 0a 20 20 69 66 28 20 69 6e 3d  "rb");.  if( in=
04e0: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 66  =0 ) return;.  f
04f0: 73 65 65 6b 28 69 6e 2c 20 30 2c 20 53 45 45 4b  seek(in, 0, SEEK
0500: 5f 45 4e 44 29 3b 0a 20 20 6e 49 6e 20 3d 20 66  _END);.  nIn = f
0510: 74 65 6c 6c 28 69 6e 29 3b 0a 20 20 72 65 77 69  tell(in);.  rewi
0520: 6e 64 28 69 6e 29 3b 0a 20 20 70 42 75 66 20 3d  nd(in);.  pBuf =
0530: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
0540: 20 6e 49 6e 20 29 3b 0a 20 20 69 66 28 20 70 42   nIn );.  if( pB
0550: 75 66 20 26 26 20 31 3d 3d 66 72 65 61 64 28 70  uf && 1==fread(p
0560: 42 75 66 2c 20 6e 49 6e 2c 20 31 2c 20 69 6e 29  Buf, nIn, 1, in)
0570: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
0580: 72 65 73 75 6c 74 5f 74 65 78 74 28 63 6f 6e 74  result_text(cont
0590: 65 78 74 2c 20 70 42 75 66 2c 20 6e 49 6e 2c 20  ext, pBuf, nIn, 
05a0: 73 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20  sqlite3_free);. 
05b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69   }else{.    sqli
05c0: 74 65 33 5f 66 72 65 65 28 70 42 75 66 29 3b 0a  te3_free(pBuf);.
05d0: 20 20 7d 0a 20 20 66 63 6c 6f 73 65 28 69 6e 29    }.  fclose(in)
05e0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74  ;.}../*.** Print
05f0: 20 75 73 61 67 65 20 74 65 78 74 20 66 6f 72 20   usage text for 
0600: 74 68 69 73 20 70 72 6f 67 72 61 6d 20 61 6e 64  this program and
0610: 20 65 78 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63   exit..*/.static
0620: 20 76 6f 69 64 20 73 68 6f 77 48 65 6c 70 28 63   void showHelp(c
0630: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72 67 76  onst char *zArgv
0640: 30 29 7b 0a 20 20 70 72 69 6e 74 66 28 22 5c 6e  0){.  printf("\n
0650: 22 0a 22 55 73 61 67 65 3a 20 25 73 20 53 57 49  "."Usage: %s SWI
0660: 54 43 48 45 53 2e 2e 2e 20 44 42 5c 6e 22 0a 22  TCHES... DB\n"."
0670: 5c 6e 22 0a 22 20 20 54 68 69 73 20 70 72 6f 67  \n"."  This prog
0680: 72 61 6d 20 6f 70 65 6e 73 20 74 68 65 20 64 61  ram opens the da
0690: 74 61 62 61 73 65 20 6e 61 6d 65 64 20 6f 6e 20  tabase named on 
06a0: 74 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65  the command line
06b0: 20 61 6e 64 20 61 74 74 65 6d 70 74 73 20 74 6f   and attempts to
06c0: 5c 6e 22 0a 22 20 20 63 72 65 61 74 65 20 61 6e  \n"."  create an
06d0: 20 46 54 53 20 74 61 62 6c 65 20 6e 61 6d 65 64   FTS table named
06e0: 20 5c 22 66 74 73 5c 22 20 77 69 74 68 20 61 20   \"fts\" with a 
06f0: 73 69 6e 67 6c 65 20 63 6f 6c 75 6d 6e 2e 20 49  single column. I
0700: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 69 74  f successful, it
0710: 5c 6e 22 0a 22 20 20 72 65 63 75 72 73 69 76 65  \n"."  recursive
0720: 6c 79 20 74 72 61 76 65 72 73 65 73 20 74 68 65  ly traverses the
0730: 20 64 69 72 65 63 74 6f 72 79 20 6e 61 6d 65 64   directory named
0740: 20 62 79 20 74 68 65 20 2d 64 69 72 20 6f 70 74   by the -dir opt
0750: 69 6f 6e 20 61 6e 64 20 69 6e 73 65 72 74 73 5c  ion and inserts\
0760: 6e 22 0a 22 20 20 74 68 65 20 63 6f 6e 74 65 6e  n"."  the conten
0770: 74 73 20 6f 66 20 65 61 63 68 20 66 69 6c 65 20  ts of each file 
0780: 69 6e 74 6f 20 74 68 65 20 66 74 73 20 74 61 62  into the fts tab
0790: 6c 65 2e 20 41 6c 6c 20 66 69 6c 65 73 20 61 72  le. All files ar
07a0: 65 20 61 73 73 75 6d 65 64 20 74 6f 5c 6e 22 0a  e assumed to\n".
07b0: 22 20 20 63 6f 6e 74 61 69 6e 20 55 54 46 2d 38  "  contain UTF-8
07c0: 20 74 65 78 74 2e 5c 6e 22 0a 22 5c 6e 22 0a 22   text.\n"."\n"."
07d0: 53 77 69 74 63 68 65 73 20 61 72 65 3a 5c 6e 22  Switches are:\n"
07e0: 0a 22 20 20 2d 66 74 73 20 5b 33 34 35 5d 20 20  ."  -fts [345]  
07f0: 20 20 20 20 20 46 54 53 20 76 65 72 73 69 6f 6e       FTS version
0800: 20 74 6f 20 75 73 65 20 28 64 65 66 61 75 6c 74   to use (default
0810: 3d 35 29 5c 6e 22 0a 22 20 20 2d 69 64 78 20 5b  =5)\n"."  -idx [
0820: 30 31 5d 20 20 20 20 20 20 20 20 43 72 65 61 74  01]        Creat
0830: 65 20 61 20 6d 61 70 70 69 6e 67 20 66 72 6f 6d  e a mapping from
0840: 20 66 69 6c 65 6e 61 6d 65 20 74 6f 20 72 6f 77   filename to row
0850: 69 64 20 28 64 65 66 61 75 6c 74 3d 30 29 5c 6e  id (default=0)\n
0860: 22 0a 22 20 20 2d 64 69 72 20 3c 70 61 74 68 3e  "."  -dir <path>
0870: 20 20 20 20 20 20 52 6f 6f 74 20 6f 66 20 64 69        Root of di
0880: 72 65 63 74 6f 72 79 20 74 72 65 65 20 74 6f 20  rectory tree to 
0890: 6c 6f 61 64 20 64 61 74 61 20 66 72 6f 6d 20 28  load data from (
08a0: 64 65 66 61 75 6c 74 3d 2e 29 5c 6e 22 0a 22 20  default=.)\n"." 
08b0: 20 2d 74 72 61 6e 73 20 3c 69 6e 74 65 67 65 72   -trans <integer
08c0: 3e 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e 73 65  > Number of inse
08d0: 72 74 73 20 70 65 72 20 74 72 61 6e 73 61 63 74  rts per transact
08e0: 69 6f 6e 20 28 64 65 66 61 75 6c 74 3d 31 29 5c  ion (default=1)\
08f0: 6e 22 0a 2c 20 7a 41 72 67 76 30 0a 29 3b 0a 20  n"., zArgv0.);. 
0900: 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a   exit(1);.}../*.
0910: 2a 2a 20 45 78 69 74 20 77 69 74 68 20 61 20 6d  ** Exit with a m
0920: 65 73 73 61 67 65 20 62 61 73 65 64 20 6f 6e 20  essage based on 
0930: 74 68 65 20 61 72 67 75 6d 65 6e 74 20 61 6e 64  the argument and
0940: 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 61 6c   the current val
0950: 75 65 20 6f 66 20 65 72 72 6e 6f 2e 0a 2a 2f 0a  ue of errno..*/.
0960: 73 74 61 74 69 63 20 76 6f 69 64 20 65 72 72 6f  static void erro
0970: 72 5f 6f 75 74 28 63 6f 6e 73 74 20 63 68 61 72  r_out(const char
0980: 20 2a 7a 54 65 78 74 29 7b 0a 20 20 66 70 72 69   *zText){.  fpri
0990: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 3a  ntf(stderr, "%s:
09a0: 20 25 73 5c 6e 22 2c 20 7a 54 65 78 74 2c 20 73   %s\n", zText, s
09b0: 74 72 65 72 72 6f 72 28 65 72 72 6e 6f 29 29 3b  trerror(errno));
09c0: 0a 20 20 65 78 69 74 28 2d 31 29 3b 0a 7d 0a 0a  .  exit(-1);.}..
09d0: 2f 2a 0a 2a 2a 20 45 78 69 74 20 77 69 74 68 20  /*.** Exit with 
09e0: 61 20 6d 65 73 73 61 67 65 20 62 61 73 65 64 20  a message based 
09f0: 6f 6e 20 74 68 65 20 66 69 72 73 74 20 61 72 67  on the first arg
0a00: 75 6d 65 6e 74 20 61 6e 64 20 74 68 65 20 65 72  ument and the er
0a10: 72 6f 72 20 6d 65 73 73 61 67 65 0a 2a 2a 20 63  ror message.** c
0a20: 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65 64 20  urrently stored 
0a30: 69 6e 20 64 61 74 61 62 61 73 65 20 68 61 6e 64  in database hand
0a40: 6c 65 20 64 62 2e 0a 2a 2f 0a 73 74 61 74 69 63  le db..*/.static
0a50: 20 76 6f 69 64 20 73 71 6c 69 74 65 5f 65 72 72   void sqlite_err
0a60: 6f 72 5f 6f 75 74 28 63 6f 6e 73 74 20 63 68 61  or_out(const cha
0a70: 72 20 2a 7a 54 65 78 74 2c 20 73 71 6c 69 74 65  r *zText, sqlite
0a80: 33 20 2a 64 62 29 7b 0a 20 20 66 70 72 69 6e 74  3 *db){.  fprint
0a90: 66 28 73 74 64 65 72 72 2c 20 22 25 73 3a 20 25  f(stderr, "%s: %
0aa0: 73 5c 6e 22 2c 20 7a 54 65 78 74 2c 20 73 71 6c  s\n", zText, sql
0ab0: 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 29  ite3_errmsg(db))
0ac0: 3b 0a 20 20 65 78 69 74 28 2d 31 29 3b 0a 7d 0a  ;.  exit(-1);.}.
0ad0: 0a 2f 2a 0a 2a 2a 20 43 6f 6e 74 65 78 74 20 6f  ./*.** Context o
0ae0: 62 6a 65 63 74 20 66 6f 72 20 76 69 73 69 74 5f  bject for visit_
0af0: 66 69 6c 65 28 29 2e 0a 2a 2f 0a 74 79 70 65 64  file()..*/.typed
0b00: 65 66 20 73 74 72 75 63 74 20 56 69 73 69 74 43  ef struct VisitC
0b10: 6f 6e 74 65 78 74 20 56 69 73 69 74 43 6f 6e 74  ontext VisitCont
0b20: 65 78 74 3b 0a 73 74 72 75 63 74 20 56 69 73 69  ext;.struct Visi
0b30: 74 43 6f 6e 74 65 78 74 20 7b 0a 20 20 69 6e 74  tContext {.  int
0b40: 20 6e 52 6f 77 50 65 72 54 72 61 6e 73 3b 0a 20   nRowPerTrans;. 
0b50: 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20 20 20   sqlite3 *db;   
0b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b70: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
0b80: 64 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  dle */.  sqlite3
0b90: 5f 73 74 6d 74 20 2a 70 49 6e 73 65 72 74 3b 20  _stmt *pInsert; 
0ba0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 53 45           /* INSE
0bb0: 52 54 20 49 4e 54 4f 20 66 74 73 20 56 41 4c 55  RT INTO fts VALU
0bc0: 45 53 28 72 65 61 64 74 65 78 74 28 3a 31 29 29  ES(readtext(:1))
0bd0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61   */.};../*.** Ca
0be0: 6c 6c 62 61 63 6b 20 75 73 65 64 20 77 69 74 68  llback used with
0bf0: 20 74 72 61 76 65 72 73 65 28 29 2e 20 54 68 65   traverse(). The
0c00: 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20   first argument 
0c10: 70 6f 69 6e 74 73 20 74 6f 20 61 6e 20 6f 62 6a  points to an obj
0c20: 65 63 74 0a 2a 2a 20 6f 66 20 74 79 70 65 20 56  ect.** of type V
0c30: 69 73 69 74 43 6f 6e 74 65 78 74 2e 20 54 68 69  isitContext. Thi
0c40: 73 20 66 75 6e 63 74 69 6f 6e 20 69 6e 73 65 72  s function inser
0c50: 74 73 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  ts the contents 
0c60: 6f 66 20 74 68 65 20 74 65 78 74 0a 2a 2a 20 66  of the text.** f
0c70: 69 6c 65 20 7a 50 61 74 68 20 69 6e 74 6f 20 74  ile zPath into t
0c80: 68 65 20 46 54 53 20 74 61 62 6c 65 2e 0a 2a 2f  he FTS table..*/
0c90: 0a 76 6f 69 64 20 76 69 73 69 74 5f 66 69 6c 65  .void visit_file
0ca0: 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 63 6f 6e  (void *pCtx, con
0cb0: 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 29 7b  st char *zPath){
0cc0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 56 69 73  .  int rc;.  Vis
0cd0: 69 74 43 6f 6e 74 65 78 74 20 2a 70 20 3d 20 28  itContext *p = (
0ce0: 56 69 73 69 74 43 6f 6e 74 65 78 74 2a 29 70 43  VisitContext*)pC
0cf0: 74 78 3b 0a 20 20 2f 2a 20 70 72 69 6e 74 66 28  tx;.  /* printf(
0d00: 22 25 73 5c 6e 22 2c 20 7a 50 61 74 68 29 3b 20  "%s\n", zPath); 
0d10: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 62 69 6e  */.  sqlite3_bin
0d20: 64 5f 74 65 78 74 28 70 2d 3e 70 49 6e 73 65 72  d_text(p->pInser
0d30: 74 2c 20 31 2c 20 7a 50 61 74 68 2c 20 2d 31 2c  t, 1, zPath, -1,
0d40: 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b   SQLITE_STATIC);
0d50: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28  .  sqlite3_step(
0d60: 70 2d 3e 70 49 6e 73 65 72 74 29 3b 0a 20 20 72  p->pInsert);.  r
0d70: 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
0d80: 74 28 70 2d 3e 70 49 6e 73 65 72 74 29 3b 0a 20  t(p->pInsert);. 
0d90: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
0da0: 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  OK ){.    sqlite
0db0: 5f 65 72 72 6f 72 5f 6f 75 74 28 22 69 6e 73 65  _error_out("inse
0dc0: 72 74 22 2c 20 70 2d 3e 64 62 29 3b 0a 20 20 7d  rt", p->db);.  }
0dd0: 65 6c 73 65 20 69 66 28 20 70 2d 3e 6e 52 6f 77  else if( p->nRow
0de0: 50 65 72 54 72 61 6e 73 3e 30 20 0a 20 20 20 20  PerTrans>0 .    
0df0: 20 20 20 20 20 26 26 20 28 73 71 6c 69 74 65 33       && (sqlite3
0e00: 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77  _last_insert_row
0e10: 69 64 28 70 2d 3e 64 62 29 20 25 20 70 2d 3e 6e  id(p->db) % p->n
0e20: 52 6f 77 50 65 72 54 72 61 6e 73 29 3d 3d 30 20  RowPerTrans)==0 
0e30: 0a 20 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  .  ){.    sqlite
0e40: 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 22 43  3_exec(p->db, "C
0e50: 4f 4d 4d 49 54 20 3b 20 42 45 47 49 4e 22 2c 20  OMMIT ; BEGIN", 
0e60: 30 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 7d 0a  0, 0, 0);.  }.}.
0e70: 0a 2f 2a 0a 2a 2a 20 52 65 63 75 72 73 69 76 65  ./*.** Recursive
0e80: 6c 79 20 74 72 61 76 65 72 73 65 20 64 69 72 65  ly traverse dire
0e90: 63 74 6f 72 79 20 7a 44 69 72 2e 20 46 6f 72 20  ctory zDir. For 
0ea0: 65 61 63 68 20 66 69 6c 65 20 74 68 61 74 20 69  each file that i
0eb0: 73 20 6e 6f 74 20 61 20 0a 2a 2a 20 64 69 72 65  s not a .** dire
0ec0: 63 74 6f 72 79 2c 20 69 6e 76 6f 6b 65 20 74 68  ctory, invoke th
0ed0: 65 20 73 75 70 70 6c 69 65 64 20 63 61 6c 6c 62  e supplied callb
0ee0: 61 63 6b 20 77 69 74 68 20 69 74 73 20 70 61 74  ack with its pat
0ef0: 68 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  h..*/.static voi
0f00: 64 20 74 72 61 76 65 72 73 65 28 0a 20 20 63 6f  d traverse(.  co
0f10: 6e 73 74 20 63 68 61 72 20 2a 7a 44 69 72 2c 20  nst char *zDir, 
0f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0f30: 20 44 69 72 65 63 74 6f 72 79 20 74 6f 20 74 72   Directory to tr
0f40: 61 76 65 72 73 65 20 2a 2f 0a 20 20 76 6f 69 64  averse */.  void
0f50: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
0f60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
0f70: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 70 61  irst argument pa
0f80: 73 73 65 64 20 74 6f 20 63 61 6c 6c 62 61 63 6b  ssed to callback
0f90: 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 43 61   */.  void (*xCa
0fa0: 6c 6c 62 61 63 6b 29 28 76 6f 69 64 2a 2c 20 63  llback)(void*, c
0fb0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68  onst char *zPath
0fc0: 29 0a 29 7b 0a 20 20 44 49 52 20 2a 64 3b 0a 20  ).){.  DIR *d;. 
0fd0: 20 73 74 72 75 63 74 20 64 69 72 65 6e 74 20 2a   struct dirent *
0fe0: 65 3b 0a 0a 20 20 64 20 3d 20 6f 70 65 6e 64 69  e;..  d = opendi
0ff0: 72 28 7a 44 69 72 29 3b 0a 20 20 69 66 28 20 64  r(zDir);.  if( d
1000: 3d 3d 30 20 29 20 65 72 72 6f 72 5f 6f 75 74 28  ==0 ) error_out(
1010: 22 6f 70 65 6e 64 69 72 28 29 22 29 3b 0a 0a 20  "opendir()");.. 
1020: 20 66 6f 72 28 65 3d 72 65 61 64 64 69 72 28 64   for(e=readdir(d
1030: 29 3b 20 65 3b 20 65 3d 72 65 61 64 64 69 72 28  ); e; e=readdir(
1040: 64 29 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72  d)){.    if( str
1050: 63 6d 70 28 65 2d 3e 64 5f 6e 61 6d 65 2c 20 22  cmp(e->d_name, "
1060: 2e 22 29 3d 3d 30 20 7c 7c 20 73 74 72 63 6d 70  .")==0 || strcmp
1070: 28 65 2d 3e 64 5f 6e 61 6d 65 2c 20 22 2e 2e 22  (e->d_name, ".."
1080: 29 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b  )==0 ) continue;
1090: 0a 20 20 20 20 63 68 61 72 20 2a 7a 50 61 74 68  .    char *zPath
10a0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
10b0: 74 66 28 22 25 73 2f 25 73 22 2c 20 7a 44 69 72  tf("%s/%s", zDir
10c0: 2c 20 65 2d 3e 64 5f 6e 61 6d 65 29 3b 0a 20 20  , e->d_name);.  
10d0: 20 20 69 66 20 28 65 2d 3e 64 5f 74 79 70 65 20    if (e->d_type 
10e0: 26 20 44 54 5f 44 49 52 29 20 7b 0a 20 20 20 20  & DT_DIR) {.    
10f0: 20 20 74 72 61 76 65 72 73 65 28 7a 50 61 74 68    traverse(zPath
1100: 2c 20 70 43 74 78 2c 20 78 43 61 6c 6c 62 61 63  , pCtx, xCallbac
1110: 6b 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  k);.    }else{. 
1120: 20 20 20 20 20 78 43 61 6c 6c 62 61 63 6b 28 70       xCallback(p
1130: 43 74 78 2c 20 7a 50 61 74 68 29 3b 0a 20 20 20  Ctx, zPath);.   
1140: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66   }.    sqlite3_f
1150: 72 65 65 28 7a 50 61 74 68 29 3b 0a 20 20 7d 0a  ree(zPath);.  }.
1160: 0a 20 20 63 6c 6f 73 65 64 69 72 28 64 29 3b 0a  .  closedir(d);.
1170: 7d 0a 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20  }..int main(int 
1180: 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67  argc, char **arg
1190: 76 29 7b 0a 20 20 69 6e 74 20 69 46 74 73 20 3d  v){.  int iFts =
11a0: 20 35 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   5;             
11b0: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f        /* Value o
11c0: 66 20 2d 66 74 73 20 6f 70 74 69 6f 6e 20 2a 2f  f -fts option */
11d0: 0a 20 20 69 6e 74 20 62 4d 61 70 20 3d 20 30 3b  .  int bMap = 0;
11e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11f0: 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 63 72     /* True to cr
1200: 65 61 74 65 20 6d 61 70 70 69 6e 67 20 74 61 62  eate mapping tab
1210: 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  le */.  const ch
1220: 61 72 20 2a 7a 44 69 72 20 3d 20 22 2e 22 3b 20  ar *zDir = "."; 
1230: 20 20 20 20 20 20 20 20 2f 2a 20 44 69 72 65 63          /* Direc
1240: 74 6f 72 79 20 74 6f 20 73 63 61 6e 20 2a 2f 0a  tory to scan */.
1250: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
1260: 63 3b 0a 20 20 69 6e 74 20 6e 52 6f 77 50 65 72  c;.  int nRowPer
1270: 54 72 61 6e 73 20 3d 20 30 3b 0a 20 20 73 71 6c  Trans = 0;.  sql
1280: 69 74 65 33 20 2a 64 62 3b 0a 20 20 63 68 61 72  ite3 *db;.  char
1290: 20 2a 7a 53 71 6c 3b 0a 20 20 56 69 73 69 74 43   *zSql;.  VisitC
12a0: 6f 6e 74 65 78 74 20 73 43 74 78 3b 0a 0a 20 20  ontext sCtx;..  
12b0: 69 6e 74 20 6e 43 6d 64 20 3d 20 30 3b 0a 20 20  int nCmd = 0;.  
12c0: 63 68 61 72 20 2a 2a 61 43 6d 64 20 3d 20 30 3b  char **aCmd = 0;
12d0: 0a 0a 20 20 69 66 28 20 61 72 67 63 20 25 20 32  ..  if( argc % 2
12e0: 20 29 20 73 68 6f 77 48 65 6c 70 28 61 72 67 76   ) showHelp(argv
12f0: 5b 30 5d 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 31  [0]);..  for(i=1
1300: 3b 20 69 3c 28 61 72 67 63 2d 31 29 3b 20 69 2b  ; i<(argc-1); i+
1310: 3d 32 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  =2){.    char *z
1320: 4f 70 74 20 3d 20 61 72 67 76 5b 69 5d 3b 0a 20  Opt = argv[i];. 
1330: 20 20 20 63 68 61 72 20 2a 7a 41 72 67 20 3d 20     char *zArg = 
1340: 61 72 67 76 5b 69 2b 31 5d 3b 0a 20 20 20 20 69  argv[i+1];.    i
1350: 66 28 20 73 74 72 63 6d 70 28 7a 4f 70 74 2c 20  f( strcmp(zOpt, 
1360: 22 2d 66 74 73 22 29 3d 3d 30 20 29 7b 0a 20 20  "-fts")==0 ){.  
1370: 20 20 20 20 69 46 74 73 20 3d 20 61 74 6f 69 28      iFts = atoi(
1380: 7a 41 72 67 29 3b 0a 20 20 20 20 20 20 69 66 28  zArg);.      if(
1390: 20 69 46 74 73 21 3d 33 20 26 26 20 69 46 74 73   iFts!=3 && iFts
13a0: 21 3d 34 20 26 26 20 69 46 74 73 21 3d 20 35 29  !=4 && iFts!= 5)
13b0: 20 73 68 6f 77 48 65 6c 70 28 61 72 67 76 5b 30   showHelp(argv[0
13c0: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c  ]);.    }.    el
13d0: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 4f  se if( strcmp(zO
13e0: 70 74 2c 20 22 2d 74 72 61 6e 73 22 29 3d 3d 30  pt, "-trans")==0
13f0: 20 29 7b 0a 20 20 20 20 20 20 6e 52 6f 77 50 65   ){.      nRowPe
1400: 72 54 72 61 6e 73 20 3d 20 61 74 6f 69 28 7a 41  rTrans = atoi(zA
1410: 72 67 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65  rg);.    }.    e
1420: 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a  lse if( strcmp(z
1430: 4f 70 74 2c 20 22 2d 69 64 78 22 29 3d 3d 30 20  Opt, "-idx")==0 
1440: 29 7b 0a 20 20 20 20 20 20 62 4d 61 70 20 3d 20  ){.      bMap = 
1450: 61 74 6f 69 28 7a 41 72 67 29 3b 0a 20 20 20 20  atoi(zArg);.    
1460: 20 20 69 66 28 20 62 4d 61 70 21 3d 30 20 26 26    if( bMap!=0 &&
1470: 20 62 4d 61 70 21 3d 31 20 29 20 73 68 6f 77 48   bMap!=1 ) showH
1480: 65 6c 70 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20  elp(argv[0]);.  
1490: 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
14a0: 20 73 74 72 63 6d 70 28 7a 4f 70 74 2c 20 22 2d   strcmp(zOpt, "-
14b0: 64 69 72 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20  dir")==0 ){.    
14c0: 20 20 7a 44 69 72 20 3d 20 7a 41 72 67 3b 0a 20    zDir = zArg;. 
14d0: 20 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66     }.    else if
14e0: 28 20 73 74 72 63 6d 70 28 7a 4f 70 74 2c 20 22  ( strcmp(zOpt, "
14f0: 2d 73 70 65 63 69 61 6c 22 29 3d 3d 30 20 29 7b  -special")==0 ){
1500: 0a 20 20 20 20 20 20 6e 43 6d 64 2b 2b 3b 0a 20  .      nCmd++;. 
1510: 20 20 20 20 20 61 43 6d 64 20 3d 20 73 71 6c 69       aCmd = sqli
1520: 74 65 33 5f 72 65 61 6c 6c 6f 63 28 61 43 6d 64  te3_realloc(aCmd
1530: 2c 20 73 69 7a 65 6f 66 28 63 68 61 72 2a 29 20  , sizeof(char*) 
1540: 2a 20 6e 43 6d 64 29 3b 0a 20 20 20 20 20 20 61  * nCmd);.      a
1550: 43 6d 64 5b 6e 43 6d 64 2d 31 5d 20 3d 20 7a 41  Cmd[nCmd-1] = zA
1560: 72 67 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c  rg;.    }.    el
1570: 73 65 7b 0a 20 20 20 20 20 20 73 68 6f 77 48 65  se{.      showHe
1580: 6c 70 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 20  lp(argv[0]);.   
1590: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 70 65   }.  }..  /* Ope
15a0: 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  n the database f
15b0: 69 6c 65 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71  ile */.  rc = sq
15c0: 6c 69 74 65 33 5f 6f 70 65 6e 28 61 72 67 76 5b  lite3_open(argv[
15d0: 61 72 67 63 2d 31 5d 2c 20 26 64 62 29 3b 0a 20  argc-1], &db);. 
15e0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
15f0: 4f 4b 20 29 20 73 71 6c 69 74 65 5f 65 72 72 6f  OK ) sqlite_erro
1600: 72 5f 6f 75 74 28 22 73 71 6c 69 74 65 33 5f 6f  r_out("sqlite3_o
1610: 70 65 6e 28 29 22 2c 20 64 62 29 3b 0a 0a 20 20  pen()", db);..  
1620: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65  rc = sqlite3_cre
1630: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c  ate_function(db,
1640: 20 22 72 65 61 64 74 65 78 74 22 2c 20 31 2c 20   "readtext", 1, 
1650: 53 51 4c 49 54 45 5f 55 54 46 38 2c 20 30 2c 0a  SQLITE_UTF8, 0,.
1660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
1680: 65 61 64 66 69 6c 65 46 75 6e 63 2c 20 30 2c 20  eadfileFunc, 0, 
1690: 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  0);.  if( rc!=SQ
16a0: 4c 49 54 45 5f 4f 4b 20 29 20 73 71 6c 69 74 65  LITE_OK ) sqlite
16b0: 5f 65 72 72 6f 72 5f 6f 75 74 28 22 73 71 6c 69  _error_out("sqli
16c0: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74  te3_create_funct
16d0: 69 6f 6e 28 29 22 2c 20 64 62 29 3b 0a 0a 20 20  ion()", db);..  
16e0: 2f 2a 20 43 72 65 61 74 65 20 74 68 65 20 46 54  /* Create the FT
16f0: 53 20 74 61 62 6c 65 20 2a 2f 0a 20 20 7a 53 71  S table */.  zSq
1700: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
1710: 6e 74 66 28 22 43 52 45 41 54 45 20 56 49 52 54  ntf("CREATE VIRT
1720: 55 41 4c 20 54 41 42 4c 45 20 66 74 73 20 55 53  UAL TABLE fts US
1730: 49 4e 47 20 66 74 73 25 64 28 63 6f 6e 74 65 6e  ING fts%d(conten
1740: 74 29 22 2c 20 69 46 74 73 29 3b 0a 20 20 72 63  t)", iFts);.  rc
1750: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
1760: 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20  db, zSql, 0, 0, 
1770: 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  0);.  if( rc!=SQ
1780: 4c 49 54 45 5f 4f 4b 20 29 20 73 71 6c 69 74 65  LITE_OK ) sqlite
1790: 5f 65 72 72 6f 72 5f 6f 75 74 28 22 73 71 6c 69  _error_out("sqli
17a0: 74 65 33 5f 65 78 65 63 28 31 29 22 2c 20 64 62  te3_exec(1)", db
17b0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
17c0: 65 28 7a 53 71 6c 29 3b 0a 0a 20 20 66 6f 72 28  e(zSql);..  for(
17d0: 69 3d 30 3b 20 69 3c 6e 43 6d 64 3b 20 69 2b 2b  i=0; i<nCmd; i++
17e0: 29 7b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71  ){.    zSql = sq
17f0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 49  lite3_mprintf("I
1800: 4e 53 45 52 54 20 49 4e 54 4f 20 66 74 73 28 66  NSERT INTO fts(f
1810: 74 73 29 20 56 41 4c 55 45 53 28 25 51 29 22 2c  ts) VALUES(%Q)",
1820: 20 61 43 6d 64 5b 69 5d 29 3b 0a 20 20 20 20 72   aCmd[i]);.    r
1830: 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63  c = sqlite3_exec
1840: 28 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c  (db, zSql, 0, 0,
1850: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21   0);.    if( rc!
1860: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 73 71 6c  =SQLITE_OK ) sql
1870: 69 74 65 5f 65 72 72 6f 72 5f 6f 75 74 28 22 73  ite_error_out("s
1880: 71 6c 69 74 65 33 5f 65 78 65 63 28 31 29 22 2c  qlite3_exec(1)",
1890: 20 64 62 29 3b 0a 20 20 20 20 73 71 6c 69 74 65   db);.    sqlite
18a0: 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20  3_free(zSql);.  
18b0: 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c 65 20  }..  /* Compile 
18c0: 74 68 65 20 49 4e 53 45 52 54 20 73 74 61 74 65  the INSERT state
18d0: 6d 65 6e 74 20 74 6f 20 77 72 69 74 65 20 64 61  ment to write da
18e0: 74 61 20 74 6f 20 74 68 65 20 46 54 53 20 74 61  ta to the FTS ta
18f0: 62 6c 65 2e 20 2a 2f 0a 20 20 6d 65 6d 73 65 74  ble. */.  memset
1900: 28 26 73 43 74 78 2c 20 30 2c 20 73 69 7a 65 6f  (&sCtx, 0, sizeo
1910: 66 28 56 69 73 69 74 43 6f 6e 74 65 78 74 29 29  f(VisitContext))
1920: 3b 0a 20 20 73 43 74 78 2e 64 62 20 3d 20 64 62  ;.  sCtx.db = db
1930: 3b 0a 20 20 73 43 74 78 2e 6e 52 6f 77 50 65 72  ;.  sCtx.nRowPer
1940: 54 72 61 6e 73 20 3d 20 6e 52 6f 77 50 65 72 54  Trans = nRowPerT
1950: 72 61 6e 73 3b 0a 20 20 72 63 20 3d 20 73 71 6c  rans;.  rc = sql
1960: 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28  ite3_prepare_v2(
1970: 64 62 2c 20 0a 20 20 20 20 20 20 22 49 4e 53 45  db, .      "INSE
1980: 52 54 20 49 4e 54 4f 20 66 74 73 20 56 41 4c 55  RT INTO fts VALU
1990: 45 53 28 72 65 61 64 74 65 78 74 28 3f 29 29 22  ES(readtext(?))"
19a0: 2c 20 2d 31 2c 20 26 73 43 74 78 2e 70 49 6e 73  , -1, &sCtx.pIns
19b0: 65 72 74 2c 20 30 0a 20 20 29 3b 0a 20 20 69 66  ert, 0.  );.  if
19c0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
19d0: 29 20 73 71 6c 69 74 65 5f 65 72 72 6f 72 5f 6f  ) sqlite_error_o
19e0: 75 74 28 22 73 71 6c 69 74 65 33 5f 70 72 65 70  ut("sqlite3_prep
19f0: 61 72 65 5f 76 32 28 31 29 22 2c 20 64 62 29 3b  are_v2(1)", db);
1a00: 0a 0a 20 20 2f 2a 20 4c 6f 61 64 20 61 6c 6c 20  ..  /* Load all 
1a10: 66 69 6c 65 73 20 69 6e 20 74 68 65 20 64 69 72  files in the dir
1a20: 65 63 74 6f 72 79 20 68 69 65 72 61 72 63 68 79  ectory hierarchy
1a30: 20 69 6e 74 6f 20 74 68 65 20 46 54 53 20 74 61   into the FTS ta
1a40: 62 6c 65 2e 20 2a 2f 0a 20 20 69 66 28 20 73 43  ble. */.  if( sC
1a50: 74 78 2e 6e 52 6f 77 50 65 72 54 72 61 6e 73 3e  tx.nRowPerTrans>
1a60: 30 20 29 20 73 71 6c 69 74 65 33 5f 65 78 65 63  0 ) sqlite3_exec
1a70: 28 64 62 2c 20 22 42 45 47 49 4e 22 2c 20 30 2c  (db, "BEGIN", 0,
1a80: 20 30 2c 20 30 29 3b 0a 20 20 74 72 61 76 65 72   0, 0);.  traver
1a90: 73 65 28 7a 44 69 72 2c 20 28 76 6f 69 64 2a 29  se(zDir, (void*)
1aa0: 26 73 43 74 78 2c 20 76 69 73 69 74 5f 66 69 6c  &sCtx, visit_fil
1ab0: 65 29 3b 0a 20 20 69 66 28 20 73 43 74 78 2e 6e  e);.  if( sCtx.n
1ac0: 52 6f 77 50 65 72 54 72 61 6e 73 3e 30 20 29 20  RowPerTrans>0 ) 
1ad0: 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
1ae0: 20 22 43 4f 4d 4d 49 54 22 2c 20 30 2c 20 30 2c   "COMMIT", 0, 0,
1af0: 20 30 29 3b 0a 0a 20 20 2f 2a 20 43 6c 65 61 6e   0);..  /* Clean
1b00: 20 75 70 20 61 6e 64 20 65 78 69 74 2e 20 2a 2f   up and exit. */
1b10: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
1b20: 69 7a 65 28 73 43 74 78 2e 70 49 6e 73 65 72 74  ize(sCtx.pInsert
1b30: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6c 6f  );.  sqlite3_clo
1b40: 73 65 28 64 62 29 3b 0a 20 20 73 71 6c 69 74 65  se(db);.  sqlite
1b50: 33 5f 66 72 65 65 28 61 43 6d 64 29 3b 0a 20 20  3_free(aCmd);.  
1b60: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a              return 0;.}.