/ Hex Artifact Content
Login

Artifact 35a2f7dd8a915900873386331386d9ba1ae1b5026d74fd20c2807bc76221f291:


0000: 2f 2a 0a 2a 2a 20 32 30 31 33 20 4a 61 6e 20 31  /*.** 2013 Jan 1
0010: 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  1.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
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 2a  ****************
0170: 0a 2a 2a 20 43 6f 64 65 20 66 6f 72 20 74 65 73  .** Code for tes
0180: 74 69 6e 67 20 74 68 65 20 76 69 72 74 75 61 6c  ting the virtual
0190: 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63 65   table interface
01a0: 73 2e 20 20 54 68 69 73 20 63 6f 64 65 0a 2a 2a  s.  This code.**
01b0: 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65 64   is not included
01c0: 20 69 6e 20 74 68 65 20 53 51 4c 69 74 65 20 6c   in the SQLite l
01d0: 69 62 72 61 72 79 2e 20 20 49 74 20 69 73 20 75  ibrary.  It is u
01e0: 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74 65  sed for automate
01f0: 64 0a 2a 2a 20 74 65 73 74 69 6e 67 20 6f 66 20  d.** testing of 
0200: 74 68 65 20 53 51 4c 69 74 65 20 6c 69 62 72 61  the SQLite libra
0210: 72 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 46 53  ry..**.** The FS
0220: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
0230: 73 20 63 72 65 61 74 65 64 20 61 73 20 66 6f 6c  s created as fol
0240: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52  lows:.**.**   CR
0250: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42  EATE VIRTUAL TAB
0260: 4c 45 20 74 62 6c 20 55 53 49 4e 47 20 66 73 28  LE tbl USING fs(
0270: 69 64 78 29 3b 0a 2a 2a 0a 2a 2a 20 77 68 65 72  idx);.**.** wher
0280: 65 20 69 64 78 20 69 73 20 74 68 65 20 6e 61 6d  e idx is the nam
0290: 65 20 6f 66 20 61 20 74 61 62 6c 65 20 69 6e 20  e of a table in 
02a0: 74 68 65 20 64 62 20 77 69 74 68 20 32 20 63 6f  the db with 2 co
02b0: 6c 75 6d 6e 73 2e 20 20 54 68 65 20 76 69 72 74  lumns.  The virt
02c0: 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 61 6c 73  ual.** table als
02d0: 6f 20 68 61 73 20 74 77 6f 20 63 6f 6c 75 6d 6e  o has two column
02e0: 73 20 2d 20 66 69 6c 65 20 70 61 74 68 20 61 6e  s - file path an
02f0: 64 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74 73 2e  d file contents.
0300: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74  .**.** The first
0310: 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 61 62 6c 65   column of table
0320: 20 69 64 78 20 6d 75 73 74 20 62 65 20 61 6e 20   idx must be an 
0330: 49 50 4b 2c 20 61 6e 64 20 74 68 65 20 73 65 63  IPK, and the sec
0340: 6f 6e 64 20 63 6f 6e 74 61 69 6e 73 20 66 69 6c  ond contains fil
0350: 65 0a 2a 2a 20 70 61 74 68 73 2e 20 46 6f 72 20  e.** paths. For 
0360: 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20  example:.**.**  
0370: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 69 64   CREATE TABLE id
0380: 78 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49  x(id INTEGER PRI
0390: 4d 41 52 59 20 4b 45 59 2c 20 70 61 74 68 20 54  MARY KEY, path T
03a0: 45 58 54 29 3b 0a 2a 2a 20 20 20 49 4e 53 45 52  EXT);.**   INSER
03b0: 54 20 49 4e 54 4f 20 69 64 78 20 56 41 4c 55 45  T INTO idx VALUE
03c0: 53 28 34 2c 20 27 2f 65 74 63 2f 70 61 73 73 77  S(4, '/etc/passw
03d0: 64 27 29 3b 0a 2a 2a 0a 2a 2a 20 41 64 64 69 6e  d');.**.** Addin
03e0: 67 20 74 68 65 20 72 6f 77 20 74 6f 20 74 68 65  g the row to the
03f0: 20 69 64 78 20 74 61 62 6c 65 20 61 75 74 6f 6d   idx table autom
0400: 61 74 69 63 61 6c 6c 79 20 63 72 65 61 74 65 73  atically creates
0410: 20 61 20 72 6f 77 20 69 6e 20 74 68 65 20 0a 2a   a row in the .*
0420: 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  * virtual table 
0430: 77 69 74 68 20 72 6f 77 69 64 3d 34 2c 20 70 61  with rowid=4, pa
0440: 74 68 3d 2f 65 74 63 2f 70 61 73 73 77 64 20 61  th=/etc/passwd a
0450: 6e 64 20 61 20 74 65 78 74 20 66 69 65 6c 64 20  nd a text field 
0460: 74 68 61 74 20 0a 2a 2a 20 63 6f 6e 74 61 69 6e  that .** contain
0470: 73 20 64 61 74 61 20 72 65 61 64 20 66 72 6f 6d  s data read from
0480: 20 66 69 6c 65 20 2f 65 74 63 2f 70 61 73 73 77   file /etc/passw
0490: 64 20 6f 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a  d on disk..**.**
04a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
04b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
04c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
04d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
04e0: 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 56 69 72 74 75  *******.** Virtu
04f0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20  al table module 
0500: 22 66 73 64 69 72 22 0a 2a 2a 0a 2a 2a 20 54 68  "fsdir".**.** Th
0510: 69 73 20 6d 6f 64 75 6c 65 20 69 73 20 64 65 73  is module is des
0520: 69 67 6e 65 64 20 74 6f 20 62 65 20 75 73 65 64  igned to be used
0530: 20 61 73 20 61 20 72 65 61 64 2d 6f 6e 6c 79 20   as a read-only 
0540: 65 70 6f 6e 79 6d 6f 75 73 20 76 69 72 74 75 61  eponymous virtua
0550: 6c 20 74 61 62 6c 65 2e 0a 2a 2a 20 49 74 73 20  l table..** Its 
0560: 73 63 68 65 6d 61 20 69 73 20 61 73 20 66 6f 6c  schema is as fol
0570: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52  lows:.**.**   CR
0580: 45 41 54 45 20 54 41 42 4c 45 20 66 73 64 69 72  EATE TABLE fsdir
0590: 28 64 69 72 20 54 45 58 54 2c 20 6e 61 6d 65 20  (dir TEXT, name 
05a0: 54 45 58 54 29 3b 0a 2a 2a 0a 2a 2a 20 57 68 65  TEXT);.**.** Whe
05b0: 6e 20 71 75 65 72 69 65 64 2c 20 61 20 57 48 45  n queried, a WHE
05c0: 52 45 20 74 65 72 6d 20 6f 66 20 74 68 65 20 66  RE term of the f
05d0: 6f 72 6d 20 22 64 69 72 20 3d 20 24 64 69 72 22  orm "dir = $dir"
05e0: 20 6d 75 73 74 20 62 65 20 70 72 6f 76 69 64 65   must be provide
05f0: 64 2e 20 54 68 65 0a 2a 2a 20 76 69 72 74 75 61  d. The.** virtua
0600: 6c 20 74 61 62 6c 65 20 74 68 65 6e 20 61 70 70  l table then app
0610: 65 61 72 73 20 74 6f 20 68 61 76 65 20 6f 6e 65  ears to have one
0620: 20 72 6f 77 20 66 6f 72 20 65 61 63 68 20 65 6e   row for each en
0630: 74 72 79 20 69 6e 20 66 69 6c 65 2d 73 79 73 74  try in file-syst
0640: 65 6d 0a 2a 2a 20 64 69 72 65 63 74 6f 72 79 20  em.** directory 
0650: 24 64 69 72 2e 20 43 6f 6c 75 6d 6e 20 64 69 72  $dir. Column dir
0660: 20 63 6f 6e 74 61 69 6e 73 20 61 20 63 6f 70 79   contains a copy
0670: 20 6f 66 20 24 64 69 72 2c 20 61 6e 64 20 63 6f   of $dir, and co
0680: 6c 75 6d 6e 20 22 6e 61 6d 65 22 0a 2a 2a 20 63  lumn "name".** c
0690: 6f 6e 74 61 69 6e 73 20 74 68 65 20 6e 61 6d 65  ontains the name
06a0: 20 6f 66 20 74 68 65 20 64 69 72 65 63 74 6f 72   of the director
06b0: 79 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20 49  y entry..**.** I
06c0: 66 20 74 68 65 20 73 70 65 63 69 66 69 65 64 20  f the specified 
06d0: 24 64 69 72 20 63 61 6e 6e 6f 74 20 62 65 20 6f  $dir cannot be o
06e0: 70 65 6e 65 64 20 6f 72 20 69 73 20 6e 6f 74 20  pened or is not 
06f0: 61 20 64 69 72 65 63 74 6f 72 79 2c 20 69 74 20  a directory, it 
0700: 69 73 20 6e 6f 74 0a 2a 2a 20 61 6e 20 65 72 72  is not.** an err
0710: 6f 72 2e 20 54 68 65 20 76 69 72 74 75 61 6c 20  or. The virtual 
0720: 74 61 62 6c 65 20 61 70 70 65 61 72 73 20 74 6f  table appears to
0730: 20 62 65 20 65 6d 70 74 79 20 69 6e 20 74 68 69   be empty in thi
0740: 73 20 63 61 73 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  s case..**.*****
0750: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0760: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0770: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0780: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0790: 2a 2a 2a 2a 0a 2a 2a 20 56 69 72 74 75 61 6c 20  ****.** Virtual 
07a0: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 22 66 73  table module "fs
07b0: 74 72 65 65 22 0a 2a 2a 0a 2a 2a 20 54 68 69 73  tree".**.** This
07c0: 20 6d 6f 64 75 6c 65 20 69 73 20 61 6c 73 6f 20   module is also 
07d0: 61 20 72 65 61 64 2d 6f 6e 6c 79 20 65 70 6f 6e  a read-only epon
07e0: 79 6d 6f 75 73 20 76 69 72 74 75 61 6c 20 74 61  ymous virtual ta
07f0: 62 6c 65 20 77 69 74 68 20 74 68 65 20 0a 2a 2a  ble with the .**
0800: 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 63 68 65 6d   following schem
0810: 61 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54  a:.**.**   CREAT
0820: 45 20 54 41 42 4c 45 20 66 73 74 72 65 65 28 70  E TABLE fstree(p
0830: 61 74 68 20 54 45 58 54 2c 20 73 69 7a 65 20 49  ath TEXT, size I
0840: 4e 54 2c 20 64 61 74 61 20 42 4c 4f 42 29 3b 0a  NT, data BLOB);.
0850: 2a 2a 0a 2a 2a 20 52 75 6e 6e 69 6e 67 20 61 20  **.** Running a 
0860: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 66  "SELECT * FROM f
0870: 73 74 72 65 65 22 20 71 75 65 72 79 20 6f 6e 20  stree" query on 
0880: 74 68 69 73 20 74 61 62 6c 65 20 72 65 74 75 72  this table retur
0890: 6e 73 20 74 68 65 20 65 6e 74 69 72 65 0a 2a 2a  ns the entire.**
08a0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
08b0: 20 66 69 6c 65 2d 73 79 73 74 65 6d 2c 20 73 74   file-system, st
08c0: 61 72 74 69 6e 67 20 61 74 20 22 2f 22 2e 20 54  arting at "/". T
08d0: 6f 20 72 65 73 74 72 69 63 74 20 74 68 65 20 73  o restrict the s
08e0: 65 61 72 63 68 0a 2a 2a 20 73 70 61 63 65 2c 20  earch.** space, 
08f0: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
0900: 65 20 73 75 70 70 6f 72 74 73 20 4c 49 4b 45 20  e supports LIKE 
0910: 61 6e 64 20 47 4c 4f 42 20 63 6f 6e 73 74 72 61  and GLOB constra
0920: 69 6e 74 73 20 6f 6e 20 74 68 65 0a 2a 2a 20 27  ints on the.** '
0930: 70 61 74 68 27 20 63 6f 6c 75 6d 6e 2e 20 46 6f  path' column. Fo
0940: 72 20 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a  r example:.**.**
0950: 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d     SELECT * FROM
0960: 20 66 73 74 72 65 65 20 57 48 45 52 45 20 70 61   fstree WHERE pa
0970: 74 68 20 4c 49 4b 45 20 27 2f 68 6f 6d 65 2f 64  th LIKE '/home/d
0980: 61 6e 2f 73 71 6c 69 74 65 2f 25 27 0a 2a 2f 0a  an/sqlite/%'.*/.
0990: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
09a0: 49 6e 74 2e 68 22 0a 23 69 66 20 64 65 66 69 6e  Int.h".#if defin
09b0: 65 64 28 49 4e 43 4c 55 44 45 5f 53 51 4c 49 54  ed(INCLUDE_SQLIT
09c0: 45 5f 54 43 4c 5f 48 29 0a 23 20 20 69 6e 63 6c  E_TCL_H).#  incl
09d0: 75 64 65 20 22 73 71 6c 69 74 65 5f 74 63 6c 2e  ude "sqlite_tcl.
09e0: 68 22 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c  h".#else.#  incl
09f0: 75 64 65 20 22 74 63 6c 2e 68 22 0a 23 65 6e 64  ude "tcl.h".#end
0a00: 69 66 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  if..#include <st
0a10: 64 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  dlib.h>.#include
0a20: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
0a30: 6c 75 64 65 20 3c 73 79 73 2f 74 79 70 65 73 2e  lude <sys/types.
0a40: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73  h>.#include <sys
0a50: 2f 73 74 61 74 2e 68 3e 0a 23 69 6e 63 6c 75 64  /stat.h>.#includ
0a60: 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 0a 23 69 66  e <fcntl.h>..#if
0a70: 20 53 51 4c 49 54 45 5f 4f 53 5f 55 4e 49 58 20   SQLITE_OS_UNIX 
0a80: 7c 7c 20 64 65 66 69 6e 65 64 28 5f 5f 4d 49 4e  || defined(__MIN
0a90: 47 57 5f 48 29 0a 23 20 69 6e 63 6c 75 64 65 20  GW_H).# include 
0aa0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 20 69 6e 63  <unistd.h>.# inc
0ab0: 6c 75 64 65 20 3c 64 69 72 65 6e 74 2e 68 3e 0a  lude <dirent.h>.
0ac0: 23 20 69 66 6e 64 65 66 20 44 49 52 45 4e 54 0a  # ifndef DIRENT.
0ad0: 23 20 20 64 65 66 69 6e 65 20 44 49 52 45 4e 54  #  define DIRENT
0ae0: 20 64 69 72 65 6e 74 0a 23 20 65 6e 64 69 66 0a   dirent.# endif.
0af0: 23 65 6e 64 69 66 0a 23 69 66 20 53 51 4c 49 54  #endif.#if SQLIT
0b00: 45 5f 4f 53 5f 57 49 4e 0a 23 20 69 6e 63 6c 75  E_OS_WIN.# inclu
0b10: 64 65 20 3c 69 6f 2e 68 3e 0a 23 20 69 66 20 21  de <io.h>.# if !
0b20: 64 65 66 69 6e 65 64 28 5f 5f 4d 49 4e 47 57 5f  defined(__MINGW_
0b30: 48 29 0a 23 20 20 69 6e 63 6c 75 64 65 20 22 74  H).#  include "t
0b40: 65 73 74 5f 77 69 6e 64 69 72 65 6e 74 2e 68 22  est_windirent.h"
0b50: 0a 23 20 65 6e 64 69 66 0a 23 20 69 66 6e 64 65  .# endif.# ifnde
0b60: 66 20 53 5f 49 53 52 45 47 0a 23 20 20 64 65 66  f S_ISREG.#  def
0b70: 69 6e 65 20 53 5f 49 53 52 45 47 28 6d 6f 64 65  ine S_ISREG(mode
0b80: 29 20 28 28 28 6d 6f 64 65 29 20 26 20 53 5f 49  ) (((mode) & S_I
0b90: 46 4d 54 29 20 3d 3d 20 53 5f 49 46 52 45 47 29  FMT) == S_IFREG)
0ba0: 0a 23 20 65 6e 64 69 66 0a 23 65 6e 64 69 66 0a  .# endif.#endif.
0bb0: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
0bc0: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
0bd0: 45 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  E..typedef struc
0be0: 74 20 66 73 5f 76 74 61 62 20 66 73 5f 76 74 61  t fs_vtab fs_vta
0bf0: 62 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  b;.typedef struc
0c00: 74 20 66 73 5f 63 75 72 73 6f 72 20 66 73 5f 63  t fs_cursor fs_c
0c10: 75 72 73 6f 72 3b 0a 0a 2f 2a 20 0a 2a 2a 20 41  ursor;../* .** A
0c20: 20 66 73 20 76 69 72 74 75 61 6c 2d 74 61 62 6c   fs virtual-tabl
0c30: 65 20 6f 62 6a 65 63 74 20 0a 2a 2f 0a 73 74 72  e object .*/.str
0c40: 75 63 74 20 66 73 5f 76 74 61 62 20 7b 0a 20 20  uct fs_vtab {.  
0c50: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61 73  sqlite3_vtab bas
0c60: 65 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  e;.  sqlite3 *db
0c70: 3b 0a 20 20 63 68 61 72 20 2a 7a 44 62 3b 20 20  ;.  char *zDb;  
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c90: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 64      /* Name of d
0ca0: 62 20 63 6f 6e 74 61 69 6e 69 6e 67 20 7a 54 62  b containing zTb
0cb0: 6c 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 54 62  l */.  char *zTb
0cc0: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
0cd0: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
0ce0: 66 20 64 6f 63 69 64 2d 3e 66 69 6c 65 20 6d 61  f docid->file ma
0cf0: 70 20 74 61 62 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f  p table */.};../
0d00: 2a 20 41 20 66 73 20 63 75 72 73 6f 72 20 6f 62  * A fs cursor ob
0d10: 6a 65 63 74 20 2a 2f 0a 73 74 72 75 63 74 20 66  ject */.struct f
0d20: 73 5f 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c  s_cursor {.  sql
0d30: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
0d40: 20 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33   base;.  sqlite3
0d50: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20  _stmt *pStmt;.  
0d60: 63 68 61 72 20 2a 7a 42 75 66 3b 0a 20 20 69 6e  char *zBuf;.  in
0d70: 74 20 6e 42 75 66 3b 0a 20 20 69 6e 74 20 6e 41  t nBuf;.  int nA
0d80: 6c 6c 6f 63 3b 0a 7d 3b 0a 0a 2f 2a 2a 2a 2a 2a  lloc;.};../*****
0d90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0da0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0db0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0dd0: 2a 2a 2a 2a 0a 2a 2a 20 53 74 61 72 74 20 6f 66  ****.** Start of
0de0: 20 66 73 64 69 72 20 69 6d 70 6c 65 6d 65 6e 74   fsdir implement
0df0: 61 74 69 6f 6e 2e 0a 2a 2f 0a 74 79 70 65 64 65  ation..*/.typede
0e00: 66 20 73 74 72 75 63 74 20 46 73 64 69 72 56 74  f struct FsdirVt
0e10: 61 62 20 46 73 64 69 72 56 74 61 62 3b 0a 74 79  ab FsdirVtab;.ty
0e20: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 73 64  pedef struct Fsd
0e30: 69 72 43 73 72 20 46 73 64 69 72 43 73 72 3b 0a  irCsr FsdirCsr;.
0e40: 73 74 72 75 63 74 20 46 73 64 69 72 56 74 61 62  struct FsdirVtab
0e50: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61   {.  sqlite3_vta
0e60: 62 20 62 61 73 65 3b 0a 7d 3b 0a 0a 73 74 72 75  b base;.};..stru
0e70: 63 74 20 46 73 64 69 72 43 73 72 20 7b 0a 20 20  ct FsdirCsr {.  
0e80: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
0e90: 73 6f 72 20 62 61 73 65 3b 0a 20 20 63 68 61 72  sor base;.  char
0ea0: 20 2a 7a 44 69 72 3b 20 20 20 20 20 20 20 20 20   *zDir;         
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
0ec0: 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  uffer containing
0ed0: 20 64 69 72 65 63 74 6f 72 79 20 73 63 61 6e 6e   directory scann
0ee0: 65 64 20 2a 2f 0a 20 20 44 49 52 20 2a 70 44 69  ed */.  DIR *pDi
0ef0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
0f00: 20 20 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e 20          /* Open 
0f10: 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 20 20 73  directory */.  s
0f20: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 52 6f  qlite3_int64 iRo
0f30: 77 69 64 3b 0a 20 20 73 74 72 75 63 74 20 44 49  wid;.  struct DI
0f40: 52 45 4e 54 20 65 6e 74 72 79 3b 20 20 20 20 20  RENT entry;     
0f50: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
0f60: 74 20 65 6e 74 72 79 20 2a 2f 0a 7d 3b 0a 0a 2f  t entry */.};../
0f70: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
0f80: 6f 6e 20 69 73 20 74 68 65 20 69 6d 70 6c 65 6d  on is the implem
0f90: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 62 6f 74 68  entation of both
0fa0: 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 20 61 6e   the xConnect an
0fb0: 64 20 78 43 72 65 61 74 65 0a 2a 2a 20 6d 65 74  d xCreate.** met
0fc0: 68 6f 64 73 20 6f 66 20 74 68 65 20 66 73 64 69  hods of the fsdi
0fd0: 72 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  r virtual table.
0fe0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 72 67 76 5b  .**.** The argv[
0ff0: 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73  ] array contains
1000: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a   the following:.
1010: 2a 2a 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d 20  **.**   argv[0] 
1020: 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d 65    -> module name
1030: 20 20 28 22 66 73 22 29 0a 2a 2a 20 20 20 61 72    ("fs").**   ar
1040: 67 76 5b 31 5d 20 20 20 2d 3e 20 64 61 74 61 62  gv[1]   -> datab
1050: 61 73 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72  ase name.**   ar
1060: 67 76 5b 32 5d 20 20 20 2d 3e 20 74 61 62 6c 65  gv[2]   -> table
1070: 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76 5b   name.**   argv[
1080: 2e 2e 2e 5d 20 2d 3e 20 6f 74 68 65 72 20 6d 6f  ...] -> other mo
1090: 64 75 6c 65 20 61 72 67 75 6d 65 6e 74 20 66 69  dule argument fi
10a0: 65 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  elds..*/.static 
10b0: 69 6e 74 20 66 73 64 69 72 43 6f 6e 6e 65 63 74  int fsdirConnect
10c0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
10d0: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20  .  void *pAux,. 
10e0: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
10f0: 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67   char *const*arg
1100: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  v,.  sqlite3_vta
1110: 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68  b **ppVtab,.  ch
1120: 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20  ar **pzErr.){.  
1130: 46 73 64 69 72 56 74 61 62 20 2a 70 54 61 62 3b  FsdirVtab *pTab;
1140: 0a 0a 20 20 69 66 28 20 61 72 67 63 21 3d 33 20  ..  if( argc!=3 
1150: 29 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20  ){.    *pzErr = 
1160: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
1170: 22 77 72 6f 6e 67 20 6e 75 6d 62 65 72 20 6f 66  "wrong number of
1180: 20 61 72 67 75 6d 65 6e 74 73 22 29 3b 0a 20 20   arguments");.  
1190: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
11a0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 70 54  ERROR;.  }..  pT
11b0: 61 62 20 3d 20 28 46 73 64 69 72 56 74 61 62 20  ab = (FsdirVtab 
11c0: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
11d0: 28 73 69 7a 65 6f 66 28 46 73 64 69 72 56 74 61  (sizeof(FsdirVta
11e0: 62 29 29 3b 0a 20 20 69 66 28 20 21 70 54 61 62  b));.  if( !pTab
11f0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
1200: 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74  _NOMEM;.  memset
1210: 28 70 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f 66  (pTab, 0, sizeof
1220: 28 46 73 64 69 72 56 74 61 62 29 29 3b 0a 0a 20  (FsdirVtab));.. 
1230: 20 2a 70 70 56 74 61 62 20 3d 20 26 70 54 61 62   *ppVtab = &pTab
1240: 2d 3e 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65  ->base;.  sqlite
1250: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64  3_declare_vtab(d
1260: 62 2c 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  b, "CREATE TABLE
1270: 20 78 79 7a 28 64 69 72 2c 20 6e 61 6d 65 29 3b   xyz(dir, name);
1280: 22 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51  ");..  return SQ
1290: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
12a0: 2a 20 78 44 65 73 74 72 6f 79 2f 78 44 69 73 63  * xDestroy/xDisc
12b0: 6f 6e 6e 65 63 74 20 69 6d 70 6c 65 6d 65 6e 74  onnect implement
12c0: 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ation..*/.static
12d0: 20 69 6e 74 20 66 73 64 69 72 44 69 73 63 6f 6e   int fsdirDiscon
12e0: 6e 65 63 74 28 73 71 6c 69 74 65 33 5f 76 74 61  nect(sqlite3_vta
12f0: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 73 71 6c  b *pVtab){.  sql
1300: 69 74 65 33 5f 66 72 65 65 28 70 56 74 61 62 29  ite3_free(pVtab)
1310: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
1320: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78  E_OK;.}../*.** x
1330: 42 65 73 74 49 6e 64 65 78 20 69 6d 70 6c 65 6d  BestIndex implem
1340: 65 6e 74 61 74 69 6f 6e 2e 20 54 68 65 20 6f 6e  entation. The on
1350: 6c 79 20 63 6f 6e 73 74 72 61 69 6e 74 20 73 75  ly constraint su
1360: 70 70 6f 72 74 65 64 20 69 73 3a 0a 2a 2a 0a 2a  pported is:.**.*
1370: 2a 20 20 20 28 64 69 72 20 3d 20 3f 29 0a 2a 2f  *   (dir = ?).*/
1380: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64 69  .static int fsdi
1390: 72 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74  rBestIndex(sqlit
13a0: 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 73 71  e3_vtab *tab, sq
13b0: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
13c0: 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a 20 20 69   *pIdxInfo){.  i
13d0: 6e 74 20 69 69 3b 0a 0a 20 20 70 49 64 78 49 6e  nt ii;..  pIdxIn
13e0: 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73  fo->estimatedCos
13f0: 74 20 3d 20 31 30 30 30 30 30 30 30 30 30 2e 30  t = 1000000000.0
1400: 3b 0a 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69  ;..  for(ii=0; i
1410: 69 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e  i<pIdxInfo->nCon
1420: 73 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a  straint; ii++){.
1430: 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69 74      struct sqlit
1440: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
1450: 69 6e 74 20 63 6f 6e 73 74 20 2a 70 20 3d 20 26  int const *p = &
1460: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
1470: 72 61 69 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 69  raint[ii];.    i
1480: 66 28 20 70 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 30  f( p->iColumn==0
1490: 20 26 26 20 70 2d 3e 75 73 61 62 6c 65 20 26 26   && p->usable &&
14a0: 20 70 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49   p->op==SQLITE_I
14b0: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
14c0: 45 51 20 29 7b 0a 20 20 20 20 20 20 73 74 72 75  EQ ){.      stru
14d0: 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ct sqlite3_index
14e0: 5f 63 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67  _constraint_usag
14f0: 65 20 2a 70 55 73 61 67 65 3b 0a 20 20 20 20 20  e *pUsage;.     
1500: 20 70 55 73 61 67 65 20 3d 20 26 70 49 64 78 49   pUsage = &pIdxI
1510: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
1520: 55 73 61 67 65 5b 69 69 5d 3b 0a 20 20 20 20 20  Usage[ii];.     
1530: 20 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20 3d 20   pUsage->omit = 
1540: 31 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d  1;.      pUsage-
1550: 3e 61 72 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a  >argvIndex = 1;.
1560: 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e        pIdxInfo->
1570: 69 64 78 4e 75 6d 20 3d 20 31 3b 0a 20 20 20 20  idxNum = 1;.    
1580: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
1590: 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 2e 30 3b  matedCost = 1.0;
15a0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
15b0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
15c0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
15d0: 2f 2a 0a 2a 2a 20 78 4f 70 65 6e 20 69 6d 70 6c  /*.** xOpen impl
15e0: 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a  ementation..**.*
15f0: 2a 20 4f 70 65 6e 20 61 20 6e 65 77 20 66 73 64  * Open a new fsd
1600: 69 72 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74  ir cursor..*/.st
1610: 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 4f 70  atic int fsdirOp
1620: 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  en(sqlite3_vtab 
1630: 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f  *pVTab, sqlite3_
1640: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70  vtab_cursor **pp
1650: 43 75 72 73 6f 72 29 7b 0a 20 20 46 73 64 69 72  Cursor){.  Fsdir
1660: 43 73 72 20 2a 70 43 75 72 3b 0a 20 20 2f 2a 20  Csr *pCur;.  /* 
1670: 41 6c 6c 6f 63 61 74 65 20 61 6e 20 65 78 74 72  Allocate an extr
1680: 61 20 32 35 36 20 62 79 74 65 73 20 62 65 63 61  a 256 bytes beca
1690: 75 73 65 20 69 74 20 69 73 20 75 6e 64 65 66 69  use it is undefi
16a0: 6e 65 64 20 68 6f 77 20 62 69 67 20 64 69 72 65  ned how big dire
16b0: 6e 74 2e 64 5f 6e 61 6d 65 0a 20 20 2a 2a 20 69  nt.d_name.  ** i
16c0: 73 20 61 6e 64 20 77 65 20 6e 65 65 64 20 65 6e  s and we need en
16d0: 6f 75 67 68 20 73 70 61 63 65 2e 20 20 4c 69 6e  ough space.  Lin
16e0: 75 78 20 70 72 6f 76 69 64 65 73 20 70 6c 65 6e  ux provides plen
16f0: 74 79 20 61 6c 72 65 61 64 79 2c 20 62 75 74 0a  ty already, but.
1700: 20 20 2a 2a 20 53 6f 6c 61 72 69 73 20 6f 6e 6c    ** Solaris onl
1710: 79 20 70 72 6f 76 69 64 65 73 20 6f 6e 65 20 62  y provides one b
1720: 79 74 65 2e 20 2a 2f 0a 20 20 70 43 75 72 20 3d  yte. */.  pCur =
1730: 20 28 46 73 64 69 72 43 73 72 2a 29 73 71 6c 69   (FsdirCsr*)sqli
1740: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
1750: 66 28 46 73 64 69 72 43 73 72 29 2b 32 35 36 29  f(FsdirCsr)+256)
1760: 3b 0a 20 20 69 66 28 20 70 43 75 72 3d 3d 30 20  ;.  if( pCur==0 
1770: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
1780: 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28  NOMEM;.  memset(
1790: 70 43 75 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pCur, 0, sizeof(
17a0: 46 73 64 69 72 43 73 72 29 29 3b 0a 20 20 2a 70  FsdirCsr));.  *p
17b0: 70 43 75 72 73 6f 72 20 3d 20 26 70 43 75 72 2d  pCursor = &pCur-
17c0: 3e 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20  >base;.  return 
17d0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
17e0: 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 66 73 64 69  .** Close a fsdi
17f0: 72 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61  r cursor..*/.sta
1800: 74 69 63 20 69 6e 74 20 66 73 64 69 72 43 6c 6f  tic int fsdirClo
1810: 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  se(sqlite3_vtab_
1820: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
1830: 46 73 64 69 72 43 73 72 20 2a 70 43 75 72 20 3d  FsdirCsr *pCur =
1840: 20 28 46 73 64 69 72 43 73 72 2a 29 63 75 72 3b   (FsdirCsr*)cur;
1850: 0a 20 20 69 66 28 20 70 43 75 72 2d 3e 70 44 69  .  if( pCur->pDi
1860: 72 20 29 20 63 6c 6f 73 65 64 69 72 28 70 43 75  r ) closedir(pCu
1870: 72 2d 3e 70 44 69 72 29 3b 0a 20 20 73 71 6c 69  r->pDir);.  sqli
1880: 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a  te3_free(pCur->z
1890: 44 69 72 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Dir);.  sqlite3_
18a0: 66 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72 65  free(pCur);.  re
18b0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
18c0: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6b 69 70 20 74 68  }../*.** Skip th
18d0: 65 20 63 75 72 73 6f 72 20 74 6f 20 74 68 65 20  e cursor to the 
18e0: 6e 65 78 74 20 65 6e 74 72 79 2e 0a 2a 2f 0a 73  next entry..*/.s
18f0: 74 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 4e  tatic int fsdirN
1900: 65 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62  ext(sqlite3_vtab
1910: 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20  _cursor *cur){. 
1920: 20 46 73 64 69 72 43 73 72 20 2a 70 43 73 72 20   FsdirCsr *pCsr 
1930: 3d 20 28 46 73 64 69 72 43 73 72 2a 29 63 75 72  = (FsdirCsr*)cur
1940: 3b 0a 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 70  ;..  if( pCsr->p
1950: 44 69 72 20 29 7b 0a 20 20 20 20 73 74 72 75 63  Dir ){.    struc
1960: 74 20 44 49 52 45 4e 54 20 2a 70 52 65 73 20 3d  t DIRENT *pRes =
1970: 20 30 3b 0a 23 69 66 20 64 65 66 69 6e 65 64 28   0;.#if defined(
1980: 5f 5f 4d 49 4e 47 57 5f 48 29 0a 20 20 20 20 70  __MINGW_H).    p
1990: 52 65 73 20 3d 20 72 65 61 64 64 69 72 28 70 43  Res = readdir(pC
19a0: 73 72 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20 69  sr->pDir);.    i
19b0: 66 28 20 70 52 65 73 21 3d 30 20 29 7b 0a 20 20  f( pRes!=0 ){.  
19c0: 20 20 20 20 6d 65 6d 63 70 79 28 26 70 43 73 72      memcpy(&pCsr
19d0: 2d 3e 65 6e 74 72 79 2c 20 70 52 65 73 2c 20 73  ->entry, pRes, s
19e0: 69 7a 65 6f 66 28 73 74 72 75 63 74 20 44 49 52  izeof(struct DIR
19f0: 45 4e 54 29 29 3b 0a 20 20 20 20 7d 0a 23 65 6c  ENT));.    }.#el
1a00: 73 65 0a 20 20 20 20 72 65 61 64 64 69 72 5f 72  se.    readdir_r
1a10: 28 70 43 73 72 2d 3e 70 44 69 72 2c 20 26 70 43  (pCsr->pDir, &pC
1a20: 73 72 2d 3e 65 6e 74 72 79 2c 20 26 70 52 65 73  sr->entry, &pRes
1a30: 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66  );.#endif.    if
1a40: 28 20 70 52 65 73 3d 3d 30 20 29 7b 0a 20 20 20  ( pRes==0 ){.   
1a50: 20 20 20 63 6c 6f 73 65 64 69 72 28 70 43 73 72     closedir(pCsr
1a60: 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20 20 20 70  ->pDir);.      p
1a70: 43 73 72 2d 3e 70 44 69 72 20 3d 20 30 3b 0a 20  Csr->pDir = 0;. 
1a80: 20 20 20 7d 0a 20 20 20 20 70 43 73 72 2d 3e 69     }.    pCsr->i
1a90: 52 6f 77 69 64 2b 2b 3b 0a 20 20 7d 0a 0a 20 20  Rowid++;.  }..  
1aa0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
1ab0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 46 69 6c 74  ;.}../*.** xFilt
1ac0: 65 72 20 6d 65 74 68 6f 64 20 69 6d 70 6c 65 6d  er method implem
1ad0: 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61  entation..*/.sta
1ae0: 74 69 63 20 69 6e 74 20 66 73 64 69 72 46 69 6c  tic int fsdirFil
1af0: 74 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  ter(.  sqlite3_v
1b00: 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61  tab_cursor *pVta
1b10: 62 43 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20  bCursor, .  int 
1b20: 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68  idxNum, const ch
1b30: 61 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e  ar *idxStr,.  in
1b40: 74 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f  t argc, sqlite3_
1b50: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
1b60: 20 20 46 73 64 69 72 43 73 72 20 2a 70 43 73 72    FsdirCsr *pCsr
1b70: 20 3d 20 28 46 73 64 69 72 43 73 72 2a 29 70 56   = (FsdirCsr*)pV
1b80: 74 61 62 43 75 72 73 6f 72 3b 0a 20 20 63 6f 6e  tabCursor;.  con
1b90: 73 74 20 63 68 61 72 20 2a 7a 44 69 72 3b 0a 20  st char *zDir;. 
1ba0: 20 69 6e 74 20 6e 44 69 72 3b 0a 0a 0a 20 20 69   int nDir;...  i
1bb0: 66 28 20 69 64 78 4e 75 6d 21 3d 31 20 7c 7c 20  f( idxNum!=1 || 
1bc0: 61 72 67 63 21 3d 31 20 29 7b 0a 20 20 20 20 72  argc!=1 ){.    r
1bd0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
1be0: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 70 43 73 72 2d  OR;.  }..  pCsr-
1bf0: 3e 69 52 6f 77 69 64 20 3d 20 30 3b 0a 20 20 73  >iRowid = 0;.  s
1c00: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 73 72  qlite3_free(pCsr
1c10: 2d 3e 7a 44 69 72 29 3b 0a 20 20 69 66 28 20 70  ->zDir);.  if( p
1c20: 43 73 72 2d 3e 70 44 69 72 20 29 7b 0a 20 20 20  Csr->pDir ){.   
1c30: 20 63 6c 6f 73 65 64 69 72 28 70 43 73 72 2d 3e   closedir(pCsr->
1c40: 70 44 69 72 29 3b 0a 20 20 20 20 70 43 73 72 2d  pDir);.    pCsr-
1c50: 3e 70 44 69 72 20 3d 20 30 3b 0a 20 20 7d 0a 0a  >pDir = 0;.  }..
1c60: 20 20 7a 44 69 72 20 3d 20 28 63 6f 6e 73 74 20    zDir = (const 
1c70: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
1c80: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d  lue_text(argv[0]
1c90: 29 3b 0a 20 20 6e 44 69 72 20 3d 20 73 71 6c 69  );.  nDir = sqli
1ca0: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
1cb0: 61 72 67 76 5b 30 5d 29 3b 0a 20 20 70 43 73 72  argv[0]);.  pCsr
1cc0: 2d 3e 7a 44 69 72 20 3d 20 73 71 6c 69 74 65 33  ->zDir = sqlite3
1cd0: 5f 6d 61 6c 6c 6f 63 28 6e 44 69 72 2b 31 29 3b  _malloc(nDir+1);
1ce0: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 7a 44 69  .  if( pCsr->zDi
1cf0: 72 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  r==0 ) return SQ
1d00: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65  LITE_NOMEM;.  me
1d10: 6d 63 70 79 28 70 43 73 72 2d 3e 7a 44 69 72 2c  mcpy(pCsr->zDir,
1d20: 20 7a 44 69 72 2c 20 6e 44 69 72 2b 31 29 3b 0a   zDir, nDir+1);.
1d30: 0a 20 20 70 43 73 72 2d 3e 70 44 69 72 20 3d 20  .  pCsr->pDir = 
1d40: 6f 70 65 6e 64 69 72 28 70 43 73 72 2d 3e 7a 44  opendir(pCsr->zD
1d50: 69 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 66 73  ir);.  return fs
1d60: 64 69 72 4e 65 78 74 28 70 56 74 61 62 43 75 72  dirNext(pVtabCur
1d70: 73 6f 72 29 3b 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  sor); .}../*.** 
1d80: 78 45 6f 66 20 6d 65 74 68 6f 64 20 69 6d 70 6c  xEof method impl
1d90: 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73  ementation..*/.s
1da0: 74 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 45  tatic int fsdirE
1db0: 6f 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  of(sqlite3_vtab_
1dc0: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
1dd0: 46 73 64 69 72 43 73 72 20 2a 70 43 73 72 20 3d  FsdirCsr *pCsr =
1de0: 20 28 46 73 64 69 72 43 73 72 2a 29 63 75 72 3b   (FsdirCsr*)cur;
1df0: 0a 20 20 72 65 74 75 72 6e 20 70 43 73 72 2d 3e  .  return pCsr->
1e00: 70 44 69 72 3d 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a  pDir==0;.}../*.*
1e10: 2a 20 78 43 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64  * xColumn method
1e20: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e   implementation.
1e30: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
1e40: 73 64 69 72 43 6f 6c 75 6d 6e 28 73 71 6c 69 74  sdirColumn(sqlit
1e50: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
1e60: 63 75 72 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6e  cur, sqlite3_con
1e70: 74 65 78 74 20 2a 63 74 78 2c 20 69 6e 74 20 69  text *ctx, int i
1e80: 29 7b 0a 20 20 46 73 64 69 72 43 73 72 20 2a 70  ){.  FsdirCsr *p
1e90: 43 73 72 20 3d 20 28 46 73 64 69 72 43 73 72 2a  Csr = (FsdirCsr*
1ea0: 29 63 75 72 3b 0a 20 20 73 77 69 74 63 68 28 20  )cur;.  switch( 
1eb0: 69 20 29 7b 0a 20 20 20 20 63 61 73 65 20 30 3a  i ){.    case 0:
1ec0: 20 2f 2a 20 64 69 72 20 2a 2f 0a 20 20 20 20 20   /* dir */.     
1ed0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
1ee0: 74 65 78 74 28 63 74 78 2c 20 70 43 73 72 2d 3e  text(ctx, pCsr->
1ef0: 7a 44 69 72 2c 20 2d 31 2c 20 53 51 4c 49 54 45  zDir, -1, SQLITE
1f00: 5f 53 54 41 54 49 43 29 3b 0a 20 20 20 20 20 20  _STATIC);.      
1f10: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65  break;..    case
1f20: 20 31 3a 20 2f 2a 20 6e 61 6d 65 20 2a 2f 0a 20   1: /* name */. 
1f30: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
1f40: 75 6c 74 5f 74 65 78 74 28 63 74 78 2c 20 70 43  ult_text(ctx, pC
1f50: 73 72 2d 3e 65 6e 74 72 79 2e 64 5f 6e 61 6d 65  sr->entry.d_name
1f60: 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41  , -1, SQLITE_TRA
1f70: 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 20 20 62  NSIENT);.      b
1f80: 72 65 61 6b 3b 0a 0a 20 20 20 20 64 65 66 61 75  reak;..    defau
1f90: 6c 74 3a 0a 20 20 20 20 20 20 61 73 73 65 72 74  lt:.      assert
1fa0: 28 20 30 20 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  ( 0 );.  }..  re
1fb0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
1fc0: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 52 6f 77 69 64 20  }../*.** xRowid 
1fd0: 6d 65 74 68 6f 64 20 69 6d 70 6c 65 6d 65 6e 74  method implement
1fe0: 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ation..*/.static
1ff0: 20 69 6e 74 20 66 73 64 69 72 52 6f 77 69 64 28   int fsdirRowid(
2000: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
2010: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
2020: 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b  _int64 *pRowid){
2030: 0a 20 20 46 73 64 69 72 43 73 72 20 2a 70 43 73  .  FsdirCsr *pCs
2040: 72 20 3d 20 28 46 73 64 69 72 43 73 72 2a 29 63  r = (FsdirCsr*)c
2050: 75 72 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20  ur;.  *pRowid = 
2060: 70 43 73 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20  pCsr->iRowid;.  
2070: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2080: 3b 0a 7d 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 6f 66  ;.}./*.** End of
2090: 20 66 73 64 69 72 20 69 6d 70 6c 65 6d 65 6e 74   fsdir implement
20a0: 61 74 69 6f 6e 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ation..*********
20b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20f0: 2f 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /../************
2100: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2110: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a  *************.**
2140: 20 53 74 61 72 74 20 6f 66 20 66 73 74 72 65 65   Start of fstree
2150: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e   implementation.
2160: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
2170: 63 74 20 46 73 74 72 65 65 56 74 61 62 20 46 73  ct FstreeVtab Fs
2180: 74 72 65 65 56 74 61 62 3b 0a 74 79 70 65 64 65  treeVtab;.typede
2190: 66 20 73 74 72 75 63 74 20 46 73 74 72 65 65 43  f struct FstreeC
21a0: 73 72 20 46 73 74 72 65 65 43 73 72 3b 0a 73 74  sr FstreeCsr;.st
21b0: 72 75 63 74 20 46 73 74 72 65 65 56 74 61 62 20  ruct FstreeVtab 
21c0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
21d0: 20 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33   base;.  sqlite3
21e0: 20 2a 64 62 3b 0a 7d 3b 0a 0a 73 74 72 75 63 74   *db;.};..struct
21f0: 20 46 73 74 72 65 65 43 73 72 20 7b 0a 20 20 73   FstreeCsr {.  s
2200: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
2210: 6f 72 20 62 61 73 65 3b 0a 20 20 73 71 6c 69 74  or base;.  sqlit
2220: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20  e3_stmt *pStmt; 
2230: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
2240: 61 74 65 6d 65 6e 74 20 74 6f 20 6c 69 73 74 20  atement to list 
2250: 70 61 74 68 73 20 2a 2f 0a 20 20 69 6e 74 20 66  paths */.  int f
2260: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
2270: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
2280: 6c 65 20 64 65 73 63 72 69 70 74 6f 72 20 6f 70  le descriptor op
2290: 65 6e 20 6f 6e 20 63 75 72 72 65 6e 74 20 70 61  en on current pa
22a0: 74 68 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  th */.};../*.** 
22b0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
22c0: 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74   the implementat
22d0: 69 6f 6e 20 6f 66 20 62 6f 74 68 20 74 68 65 20  ion of both the 
22e0: 78 43 6f 6e 6e 65 63 74 20 61 6e 64 20 78 43 72  xConnect and xCr
22f0: 65 61 74 65 0a 2a 2a 20 6d 65 74 68 6f 64 73 20  eate.** methods 
2300: 6f 66 20 74 68 65 20 66 73 74 72 65 65 20 76 69  of the fstree vi
2310: 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2a 0a  rtual table..**.
2320: 2a 2a 20 54 68 65 20 61 72 67 76 5b 5d 20 61 72  ** The argv[] ar
2330: 72 61 79 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ray contains the
2340: 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a 2a   following:.**.*
2350: 2a 20 20 20 61 72 67 76 5b 30 5d 20 20 20 2d 3e  *   argv[0]   ->
2360: 20 6d 6f 64 75 6c 65 20 6e 61 6d 65 20 20 28 22   module name  ("
2370: 66 73 22 29 0a 2a 2a 20 20 20 61 72 67 76 5b 31  fs").**   argv[1
2380: 5d 20 20 20 2d 3e 20 64 61 74 61 62 61 73 65 20  ]   -> database 
2390: 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76 5b 32  name.**   argv[2
23a0: 5d 20 20 20 2d 3e 20 74 61 62 6c 65 20 6e 61 6d  ]   -> table nam
23b0: 65 0a 2a 2a 20 20 20 61 72 67 76 5b 2e 2e 2e 5d  e.**   argv[...]
23c0: 20 2d 3e 20 6f 74 68 65 72 20 6d 6f 64 75 6c 65   -> other module
23d0: 20 61 72 67 75 6d 65 6e 74 20 66 69 65 6c 64 73   argument fields
23e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
23f0: 66 73 74 72 65 65 43 6f 6e 6e 65 63 74 28 0a 20  fstreeConnect(. 
2400: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
2410: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
2420: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
2430: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
2440: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
2450: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
2460: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 46 73 74  **pzErr.){.  Fst
2470: 72 65 65 56 74 61 62 20 2a 70 54 61 62 3b 0a 0a  reeVtab *pTab;..
2480: 20 20 69 66 28 20 61 72 67 63 21 3d 33 20 29 7b    if( argc!=3 ){
2490: 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71  .    *pzErr = sq
24a0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 77  lite3_mprintf("w
24b0: 72 6f 6e 67 20 6e 75 6d 62 65 72 20 6f 66 20 61  rong number of a
24c0: 72 67 75 6d 65 6e 74 73 22 29 3b 0a 20 20 20 20  rguments");.    
24d0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
24e0: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 70 54 61 62  ROR;.  }..  pTab
24f0: 20 3d 20 28 46 73 74 72 65 65 56 74 61 62 20 2a   = (FstreeVtab *
2500: 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28  )sqlite3_malloc(
2510: 73 69 7a 65 6f 66 28 46 73 74 72 65 65 56 74 61  sizeof(FstreeVta
2520: 62 29 29 3b 0a 20 20 69 66 28 20 21 70 54 61 62  b));.  if( !pTab
2530: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
2540: 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74  _NOMEM;.  memset
2550: 28 70 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f 66  (pTab, 0, sizeof
2560: 28 46 73 74 72 65 65 56 74 61 62 29 29 3b 0a 20  (FstreeVtab));. 
2570: 20 70 54 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a   pTab->db = db;.
2580: 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 26 70 54  .  *ppVtab = &pT
2590: 61 62 2d 3e 62 61 73 65 3b 0a 20 20 73 71 6c 69  ab->base;.  sqli
25a0: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
25b0: 28 64 62 2c 20 22 43 52 45 41 54 45 20 54 41 42  (db, "CREATE TAB
25c0: 4c 45 20 78 79 7a 28 70 61 74 68 2c 20 73 69 7a  LE xyz(path, siz
25d0: 65 2c 20 64 61 74 61 29 3b 22 29 3b 0a 0a 20 20  e, data);");..  
25e0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
25f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 44 65 73 74  ;.}../*.** xDest
2600: 72 6f 79 2f 78 44 69 73 63 6f 6e 6e 65 63 74 20  roy/xDisconnect 
2610: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a  implementation..
2620: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
2630: 74 72 65 65 44 69 73 63 6f 6e 6e 65 63 74 28 73  treeDisconnect(s
2640: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
2650: 61 62 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ab){.  sqlite3_f
2660: 72 65 65 28 70 56 74 61 62 29 3b 0a 20 20 72 65  ree(pVtab);.  re
2670: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
2680: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 42 65 73 74 49 6e  }../*.** xBestIn
2690: 64 65 78 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  dex implementati
26a0: 6f 6e 2e 20 54 68 65 20 6f 6e 6c 79 20 63 6f 6e  on. The only con
26b0: 73 74 72 61 69 6e 74 20 73 75 70 70 6f 72 74 65  straint supporte
26c0: 64 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 28 64  d is:.**.**   (d
26d0: 69 72 20 3d 20 3f 29 0a 2a 2f 0a 73 74 61 74 69  ir = ?).*/.stati
26e0: 63 20 69 6e 74 20 66 73 74 72 65 65 42 65 73 74  c int fstreeBest
26f0: 49 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74  Index(sqlite3_vt
2700: 61 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65 33  ab *tab, sqlite3
2710: 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64  _index_info *pId
2720: 78 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69  xInfo){.  int ii
2730: 3b 0a 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69  ;..  for(ii=0; i
2740: 69 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e  i<pIdxInfo->nCon
2750: 73 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a  straint; ii++){.
2760: 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69 74      struct sqlit
2770: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
2780: 69 6e 74 20 63 6f 6e 73 74 20 2a 70 20 3d 20 26  int const *p = &
2790: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
27a0: 72 61 69 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 69  raint[ii];.    i
27b0: 66 28 20 70 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 30  f( p->iColumn==0
27c0: 20 26 26 20 70 2d 3e 75 73 61 62 6c 65 20 26 26   && p->usable &&
27d0: 20 28 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e   (.          p->
27e0: 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58  op==SQLITE_INDEX
27f0: 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47 4c 4f 42  _CONSTRAINT_GLOB
2800: 0a 20 20 20 20 20 20 20 7c 7c 20 70 2d 3e 6f 70  .       || p->op
2810: 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  ==SQLITE_INDEX_C
2820: 4f 4e 53 54 52 41 49 4e 54 5f 4c 49 4b 45 0a 20  ONSTRAINT_LIKE. 
2830: 20 20 20 20 20 20 7c 7c 20 70 2d 3e 6f 70 3d 3d        || p->op==
2840: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
2850: 53 54 52 41 49 4e 54 5f 45 51 0a 20 20 20 20 29  STRAINT_EQ.    )
2860: 29 7b 0a 20 20 20 20 20 20 73 74 72 75 63 74 20  ){.      struct 
2870: 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f  sqlite3_index_co
2880: 6e 73 74 72 61 69 6e 74 5f 75 73 61 67 65 20 2a  nstraint_usage *
2890: 70 55 73 61 67 65 3b 0a 20 20 20 20 20 20 70 55  pUsage;.      pU
28a0: 73 61 67 65 20 3d 20 26 70 49 64 78 49 6e 66 6f  sage = &pIdxInfo
28b0: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61  ->aConstraintUsa
28c0: 67 65 5b 69 69 5d 3b 0a 20 20 20 20 20 20 70 49  ge[ii];.      pI
28d0: 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d  dxInfo->idxNum =
28e0: 20 70 2d 3e 6f 70 3b 0a 20 20 20 20 20 20 70 55   p->op;.      pU
28f0: 73 61 67 65 2d 3e 61 72 67 76 49 6e 64 65 78 20  sage->argvIndex 
2900: 3d 20 31 3b 0a 20 20 20 20 20 20 70 49 64 78 49  = 1;.      pIdxI
2910: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f  nfo->estimatedCo
2920: 73 74 20 3d 20 31 30 30 30 30 30 2e 30 3b 0a 20  st = 100000.0;. 
2930: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
2940: 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d  TE_OK;.    }.  }
2950: 0a 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73  ..  pIdxInfo->es
2960: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 30  timatedCost = 10
2970: 30 30 30 30 30 30 30 30 2e 30 3b 0a 20 20 72 65  00000000.0;.  re
2980: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
2990: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 4f 70 65 6e 20 69  }../*.** xOpen i
29a0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
29b0: 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20 6e 65 77 20  *.** Open a new 
29c0: 66 73 74 72 65 65 20 63 75 72 73 6f 72 2e 0a 2a  fstree cursor..*
29d0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 74  /.static int fst
29e0: 72 65 65 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  reeOpen(sqlite3_
29f0: 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c  vtab *pVTab, sql
2a00: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
2a10: 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20   **ppCursor){.  
2a20: 46 73 74 72 65 65 43 73 72 20 2a 70 43 75 72 3b  FstreeCsr *pCur;
2a30: 0a 20 20 70 43 75 72 20 3d 20 28 46 73 74 72 65  .  pCur = (Fstre
2a40: 65 43 73 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61  eCsr*)sqlite3_ma
2a50: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 46 73 74 72  lloc(sizeof(Fstr
2a60: 65 65 43 73 72 29 29 3b 0a 20 20 69 66 28 20 70  eeCsr));.  if( p
2a70: 43 75 72 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  Cur==0 ) return 
2a80: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
2a90: 6d 65 6d 73 65 74 28 70 43 75 72 2c 20 30 2c 20  memset(pCur, 0, 
2aa0: 73 69 7a 65 6f 66 28 46 73 74 72 65 65 43 73 72  sizeof(FstreeCsr
2ab0: 29 29 3b 0a 20 20 70 43 75 72 2d 3e 66 64 20 3d  ));.  pCur->fd =
2ac0: 20 2d 31 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72   -1;.  *ppCursor
2ad0: 20 3d 20 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a   = &pCur->base;.
2ae0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2af0: 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  OK;.}..static vo
2b00: 69 64 20 66 73 74 72 65 65 43 6c 6f 73 65 46 64  id fstreeCloseFd
2b10: 28 46 73 74 72 65 65 43 73 72 20 2a 70 43 73 72  (FstreeCsr *pCsr
2b20: 29 7b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 66  ){.  if( pCsr->f
2b30: 64 3e 3d 30 20 29 7b 0a 20 20 20 20 63 6c 6f 73  d>=0 ){.    clos
2b40: 65 28 70 43 73 72 2d 3e 66 64 29 3b 0a 20 20 20  e(pCsr->fd);.   
2b50: 20 70 43 73 72 2d 3e 66 64 20 3d 20 2d 31 3b 0a   pCsr->fd = -1;.
2b60: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f    }.}../*.** Clo
2b70: 73 65 20 61 20 66 73 74 72 65 65 20 63 75 72 73  se a fstree curs
2b80: 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  or..*/.static in
2b90: 74 20 66 73 74 72 65 65 43 6c 6f 73 65 28 73 71  t fstreeClose(sq
2ba0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
2bb0: 72 20 2a 63 75 72 29 7b 0a 20 20 46 73 74 72 65  r *cur){.  Fstre
2bc0: 65 43 73 72 20 2a 70 43 73 72 20 3d 20 28 46 73  eCsr *pCsr = (Fs
2bd0: 74 72 65 65 43 73 72 2a 29 63 75 72 3b 0a 20 20  treeCsr*)cur;.  
2be0: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
2bf0: 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCsr->pStmt);. 
2c00: 20 66 73 74 72 65 65 43 6c 6f 73 65 46 64 28 70   fstreeCloseFd(p
2c10: 43 73 72 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Csr);.  sqlite3_
2c20: 66 72 65 65 28 70 43 73 72 29 3b 0a 20 20 72 65  free(pCsr);.  re
2c30: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
2c40: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6b 69 70 20 74 68  }../*.** Skip th
2c50: 65 20 63 75 72 73 6f 72 20 74 6f 20 74 68 65 20  e cursor to the 
2c60: 6e 65 78 74 20 65 6e 74 72 79 2e 0a 2a 2f 0a 73  next entry..*/.s
2c70: 74 61 74 69 63 20 69 6e 74 20 66 73 74 72 65 65  tatic int fstree
2c80: 4e 65 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61  Next(sqlite3_vta
2c90: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a  b_cursor *cur){.
2ca0: 20 20 46 73 74 72 65 65 43 73 72 20 2a 70 43 73    FstreeCsr *pCs
2cb0: 72 20 3d 20 28 46 73 74 72 65 65 43 73 72 2a 29  r = (FstreeCsr*)
2cc0: 63 75 72 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a  cur;.  int rc;..
2cd0: 20 20 66 73 74 72 65 65 43 6c 6f 73 65 46 64 28    fstreeCloseFd(
2ce0: 70 43 73 72 29 3b 0a 20 20 72 63 20 3d 20 73 71  pCsr);.  rc = sq
2cf0: 6c 69 74 65 33 5f 73 74 65 70 28 70 43 73 72 2d  lite3_step(pCsr-
2d00: 3e 70 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72  >pStmt);.  if( r
2d10: 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b  c!=SQLITE_ROW ){
2d20: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
2d30: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43 73 72 2d  3_finalize(pCsr-
2d40: 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 70 43 73  >pStmt);.    pCs
2d50: 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  r->pStmt = 0;.  
2d60: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20  }else{.    rc = 
2d70: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 70  SQLITE_OK;.    p
2d80: 43 73 72 2d 3e 66 64 20 3d 20 6f 70 65 6e 28 28  Csr->fd = open((
2d90: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69  const char*)sqli
2da0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
2db0: 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 30 29 2c  pCsr->pStmt, 0),
2dc0: 20 4f 5f 52 44 4f 4e 4c 59 29 3b 0a 20 20 7d 0a   O_RDONLY);.  }.
2dd0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
2de0: 0a 2f 2a 0a 2a 2a 20 78 46 69 6c 74 65 72 20 6d  ./*.** xFilter m
2df0: 65 74 68 6f 64 20 69 6d 70 6c 65 6d 65 6e 74 61  ethod implementa
2e00: 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tion..*/.static 
2e10: 69 6e 74 20 66 73 74 72 65 65 46 69 6c 74 65 72  int fstreeFilter
2e20: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  (.  sqlite3_vtab
2e30: 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62 43 75  _cursor *pVtabCu
2e40: 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69 64 78  rsor, .  int idx
2e50: 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Num, const char 
2e60: 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74 20 61  *idxStr,.  int a
2e70: 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  rgc, sqlite3_val
2e80: 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 46  ue **argv.){.  F
2e90: 73 74 72 65 65 43 73 72 20 2a 70 43 73 72 20 3d  streeCsr *pCsr =
2ea0: 20 28 46 73 74 72 65 65 43 73 72 2a 29 70 56 74   (FstreeCsr*)pVt
2eb0: 61 62 43 75 72 73 6f 72 3b 0a 20 20 46 73 74 72  abCursor;.  Fstr
2ec0: 65 65 56 74 61 62 20 2a 70 54 61 62 20 3d 20 28  eeVtab *pTab = (
2ed0: 46 73 74 72 65 65 56 74 61 62 2a 29 28 70 43 73  FstreeVtab*)(pCs
2ee0: 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a  r->base.pVtab);.
2ef0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 6f 6e 73    int rc;.  cons
2f00: 74 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20 0a  t char *zSql = .
2f10: 22 57 49 54 48 20 72 28 64 29 20 41 53 20 28 22  "WITH r(d) AS ("
2f20: 0a 22 20 20 53 45 4c 45 43 54 20 43 41 53 45 20  ."  SELECT CASE 
2f30: 57 48 45 4e 20 64 69 72 3d 3f 32 20 54 48 45 4e  WHEN dir=?2 THEN
2f40: 20 3f 33 20 45 4c 53 45 20 64 69 72 20 45 4e 44   ?3 ELSE dir END
2f50: 20 7c 7c 20 27 2f 27 20 7c 7c 20 6e 61 6d 65 20   || '/' || name 
2f60: 22 0a 22 20 20 20 20 46 52 4f 4d 20 66 73 64 69  "."    FROM fsdi
2f70: 72 20 57 48 45 52 45 20 64 69 72 3d 3f 31 20 41  r WHERE dir=?1 A
2f80: 4e 44 20 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45  ND name NOT LIKE
2f90: 20 27 2e 25 27 22 0a 22 20 20 55 4e 49 4f 4e 20   '.%'"."  UNION 
2fa0: 41 4c 4c 22 0a 22 20 20 53 45 4c 45 43 54 20 64  ALL"."  SELECT d
2fb0: 69 72 20 7c 7c 20 27 2f 27 20 7c 7c 20 6e 61 6d  ir || '/' || nam
2fc0: 65 20 46 52 4f 4d 20 72 2c 20 66 73 64 69 72 20  e FROM r, fsdir 
2fd0: 57 48 45 52 45 20 64 69 72 3d 64 20 41 4e 44 20  WHERE dir=d AND 
2fe0: 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20 27 2e  name NOT LIKE '.
2ff0: 25 27 22 0a 22 29 20 53 45 4c 45 43 54 20 64 20  %'".") SELECT d 
3000: 46 52 4f 4d 20 72 3b 22 3b 0a 0a 20 20 63 68 61  FROM r;";..  cha
3010: 72 20 2a 7a 52 6f 6f 74 3b 0a 20 20 69 6e 74 20  r *zRoot;.  int 
3020: 6e 52 6f 6f 74 3b 0a 20 20 63 68 61 72 20 2a 7a  nRoot;.  char *z
3030: 50 72 65 66 69 78 3b 0a 20 20 69 6e 74 20 6e 50  Prefix;.  int nP
3040: 72 65 66 69 78 3b 0a 20 20 63 6f 6e 73 74 20 63  refix;.  const c
3050: 68 61 72 20 2a 7a 44 69 72 3b 0a 20 20 69 6e 74  har *zDir;.  int
3060: 20 6e 44 69 72 3b 0a 20 20 63 68 61 72 20 61 57   nDir;.  char aW
3070: 69 6c 64 5b 32 5d 20 3d 20 7b 20 27 5c 30 27 2c  ild[2] = { '\0',
3080: 20 27 5c 30 27 20 7d 3b 0a 0a 23 69 66 20 53 51   '\0' };..#if SQ
3090: 4c 49 54 45 5f 4f 53 5f 57 49 4e 0a 20 20 63 6f  LITE_OS_WIN.  co
30a0: 6e 73 74 20 63 68 61 72 20 2a 7a 44 72 69 76 65  nst char *zDrive
30b0: 20 3d 20 77 69 6e 64 69 72 65 6e 74 5f 67 65 74   = windirent_get
30c0: 65 6e 76 28 22 66 73 74 72 65 65 44 72 69 76 65  env("fstreeDrive
30d0: 22 29 3b 0a 20 20 69 66 28 20 7a 44 72 69 76 65  ");.  if( zDrive
30e0: 3d 3d 30 20 29 7b 0a 20 20 20 20 7a 44 72 69 76  ==0 ){.    zDriv
30f0: 65 20 3d 20 77 69 6e 64 69 72 65 6e 74 5f 67 65  e = windirent_ge
3100: 74 65 6e 76 28 22 53 79 73 74 65 6d 44 72 69 76  tenv("SystemDriv
3110: 65 22 29 3b 0a 20 20 7d 0a 20 20 7a 52 6f 6f 74  e");.  }.  zRoot
3120: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
3130: 74 66 28 22 25 73 25 63 22 2c 20 7a 44 72 69 76  tf("%s%c", zDriv
3140: 65 2c 20 27 2f 27 29 3b 0a 20 20 6e 52 6f 6f 74  e, '/');.  nRoot
3150: 20 3d 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e   = sqlite3Strlen
3160: 33 30 28 7a 52 6f 6f 74 29 3b 0a 20 20 7a 50 72  30(zRoot);.  zPr
3170: 65 66 69 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d  efix = sqlite3_m
3180: 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 44 72  printf("%s", zDr
3190: 69 76 65 29 3b 0a 20 20 6e 50 72 65 66 69 78 20  ive);.  nPrefix 
31a0: 3d 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e 33  = sqlite3Strlen3
31b0: 30 28 7a 50 72 65 66 69 78 29 3b 0a 23 65 6c 73  0(zPrefix);.#els
31c0: 65 0a 20 20 7a 52 6f 6f 74 20 3d 20 22 2f 22 3b  e.  zRoot = "/";
31d0: 0a 20 20 6e 52 6f 6f 74 20 3d 20 31 3b 0a 20 20  .  nRoot = 1;.  
31e0: 7a 50 72 65 66 69 78 20 3d 20 22 22 3b 0a 20 20  zPrefix = "";.  
31f0: 6e 50 72 65 66 69 78 20 3d 20 30 3b 0a 23 65 6e  nPrefix = 0;.#en
3200: 64 69 66 0a 0a 20 20 7a 44 69 72 20 3d 20 7a 52  dif..  zDir = zR
3210: 6f 6f 74 3b 0a 20 20 6e 44 69 72 20 3d 20 6e 52  oot;.  nDir = nR
3220: 6f 6f 74 3b 0a 0a 20 20 66 73 74 72 65 65 43 6c  oot;..  fstreeCl
3230: 6f 73 65 46 64 28 70 43 73 72 29 3b 0a 20 20 73  oseFd(pCsr);.  s
3240: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
3250: 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  pCsr->pStmt);.  
3260: 70 43 73 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b  pCsr->pStmt = 0;
3270: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
3280: 70 72 65 70 61 72 65 5f 76 32 28 70 54 61 62 2d  prepare_v2(pTab-
3290: 3e 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26  >db, zSql, -1, &
32a0: 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b  pCsr->pStmt, 0);
32b0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
32c0: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
32d0: 3b 0a 0a 20 20 69 66 28 20 69 64 78 4e 75 6d 20  ;..  if( idxNum 
32e0: 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  ){.    const cha
32f0: 72 20 2a 7a 51 75 65 72 79 20 3d 20 28 63 6f 6e  r *zQuery = (con
3300: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
3310: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
3320: 5b 30 5d 29 3b 0a 20 20 20 20 73 77 69 74 63 68  [0]);.    switch
3330: 28 20 69 64 78 4e 75 6d 20 29 7b 0a 20 20 20 20  ( idxNum ){.    
3340: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
3350: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47  DEX_CONSTRAINT_G
3360: 4c 4f 42 3a 0a 20 20 20 20 20 20 20 20 61 57 69  LOB:.        aWi
3370: 6c 64 5b 30 5d 20 3d 20 27 2a 27 3b 0a 20 20 20  ld[0] = '*';.   
3380: 20 20 20 20 20 61 57 69 6c 64 5b 31 5d 20 3d 20       aWild[1] = 
3390: 27 3f 27 3b 0a 20 20 20 20 20 20 20 20 62 72 65  '?';.        bre
33a0: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53  ak;.      case S
33b0: 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53  QLITE_INDEX_CONS
33c0: 54 52 41 49 4e 54 5f 4c 49 4b 45 3a 0a 20 20 20  TRAINT_LIKE:.   
33d0: 20 20 20 20 20 61 57 69 6c 64 5b 30 5d 20 3d 20       aWild[0] = 
33e0: 27 5f 27 3b 0a 20 20 20 20 20 20 20 20 61 57 69  '_';.        aWi
33f0: 6c 64 5b 31 5d 20 3d 20 27 25 27 3b 0a 20 20 20  ld[1] = '%';.   
3400: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
3410: 7d 0a 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74  }..    if( sqlit
3420: 65 33 5f 73 74 72 6e 69 63 6d 70 28 7a 51 75 65  e3_strnicmp(zQue
3430: 72 79 2c 20 7a 50 72 65 66 69 78 2c 20 6e 50 72  ry, zPrefix, nPr
3440: 65 66 69 78 29 3d 3d 30 20 29 7b 0a 20 20 20 20  efix)==0 ){.    
3450: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 66    int i;.      f
3460: 6f 72 28 69 3d 6e 50 72 65 66 69 78 3b 20 7a 51  or(i=nPrefix; zQ
3470: 75 65 72 79 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20  uery[i]; i++){. 
3480: 20 20 20 20 20 20 20 69 66 28 20 7a 51 75 65 72         if( zQuer
3490: 79 5b 69 5d 3d 3d 61 57 69 6c 64 5b 30 5d 20 7c  y[i]==aWild[0] |
34a0: 7c 20 7a 51 75 65 72 79 5b 69 5d 3d 3d 61 57 69  | zQuery[i]==aWi
34b0: 6c 64 5b 31 5d 20 29 20 62 72 65 61 6b 3b 0a 20  ld[1] ) break;. 
34c0: 20 20 20 20 20 20 20 69 66 28 20 7a 51 75 65 72         if( zQuer
34d0: 79 5b 69 5d 3d 3d 27 2f 27 20 29 20 6e 44 69 72  y[i]=='/' ) nDir
34e0: 20 3d 20 69 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = i;.      }.  
34f0: 20 20 20 20 7a 44 69 72 20 3d 20 7a 51 75 65 72      zDir = zQuer
3500: 79 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  y;.    }.  }.  i
3510: 66 28 20 6e 44 69 72 3d 3d 30 20 29 20 6e 44 69  f( nDir==0 ) nDi
3520: 72 20 3d 20 31 3b 0a 0a 20 20 73 71 6c 69 74 65  r = 1;..  sqlite
3530: 33 5f 62 69 6e 64 5f 74 65 78 74 28 70 43 73 72  3_bind_text(pCsr
3540: 2d 3e 70 53 74 6d 74 2c 20 31 2c 20 7a 44 69 72  ->pStmt, 1, zDir
3550: 2c 20 6e 44 69 72 2c 20 53 51 4c 49 54 45 5f 54  , nDir, SQLITE_T
3560: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 73 71 6c  RANSIENT);.  sql
3570: 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28 70  ite3_bind_text(p
3580: 43 73 72 2d 3e 70 53 74 6d 74 2c 20 32 2c 20 7a  Csr->pStmt, 2, z
3590: 52 6f 6f 74 2c 20 6e 52 6f 6f 74 2c 20 53 51 4c  Root, nRoot, SQL
35a0: 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a  ITE_TRANSIENT);.
35b0: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74    sqlite3_bind_t
35c0: 65 78 74 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c  ext(pCsr->pStmt,
35d0: 20 33 2c 20 7a 50 72 65 66 69 78 2c 20 6e 50 72   3, zPrefix, nPr
35e0: 65 66 69 78 2c 20 53 51 4c 49 54 45 5f 54 52 41  efix, SQLITE_TRA
35f0: 4e 53 49 45 4e 54 29 3b 0a 0a 23 69 66 20 53 51  NSIENT);..#if SQ
3600: 4c 49 54 45 5f 4f 53 5f 57 49 4e 0a 20 20 73 71  LITE_OS_WIN.  sq
3610: 6c 69 74 65 33 5f 66 72 65 65 28 7a 50 72 65 66  lite3_free(zPref
3620: 69 78 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ix);.  sqlite3_f
3630: 72 65 65 28 7a 52 6f 6f 74 29 3b 0a 23 65 6e 64  ree(zRoot);.#end
3640: 69 66 0a 0a 20 20 72 65 74 75 72 6e 20 66 73 74  if..  return fst
3650: 72 65 65 4e 65 78 74 28 70 56 74 61 62 43 75 72  reeNext(pVtabCur
3660: 73 6f 72 29 3b 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  sor); .}../*.** 
3670: 78 45 6f 66 20 6d 65 74 68 6f 64 20 69 6d 70 6c  xEof method impl
3680: 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73  ementation..*/.s
3690: 74 61 74 69 63 20 69 6e 74 20 66 73 74 72 65 65  tatic int fstree
36a0: 45 6f 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62  Eof(sqlite3_vtab
36b0: 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20  _cursor *cur){. 
36c0: 20 46 73 74 72 65 65 43 73 72 20 2a 70 43 73 72   FstreeCsr *pCsr
36d0: 20 3d 20 28 46 73 74 72 65 65 43 73 72 2a 29 63   = (FstreeCsr*)c
36e0: 75 72 3b 0a 20 20 72 65 74 75 72 6e 20 70 43 73  ur;.  return pCs
36f0: 72 2d 3e 70 53 74 6d 74 3d 3d 30 3b 0a 7d 0a 0a  r->pStmt==0;.}..
3700: 2f 2a 0a 2a 2a 20 78 43 6f 6c 75 6d 6e 20 6d 65  /*.** xColumn me
3710: 74 68 6f 64 20 69 6d 70 6c 65 6d 65 6e 74 61 74  thod implementat
3720: 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ion..*/.static i
3730: 6e 74 20 66 73 74 72 65 65 43 6f 6c 75 6d 6e 28  nt fstreeColumn(
3740: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3750: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
3760: 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20  3_context *ctx, 
3770: 69 6e 74 20 69 29 7b 0a 20 20 46 73 74 72 65 65  int i){.  Fstree
3780: 43 73 72 20 2a 70 43 73 72 20 3d 20 28 46 73 74  Csr *pCsr = (Fst
3790: 72 65 65 43 73 72 2a 29 63 75 72 3b 0a 20 20 69  reeCsr*)cur;.  i
37a0: 66 28 20 69 3d 3d 30 20 29 7b 20 20 20 20 20 20  f( i==0 ){      
37b0: 2f 2a 20 70 61 74 68 20 2a 2f 0a 20 20 20 20 73  /* path */.    s
37c0: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61  qlite3_result_va
37d0: 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74 65 33  lue(ctx, sqlite3
37e0: 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 43  _column_value(pC
37f0: 73 72 2d 3e 70 53 74 6d 74 2c 20 30 29 29 3b 0a  sr->pStmt, 0));.
3800: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 74 72    }else{.    str
3810: 75 63 74 20 73 74 61 74 20 73 42 75 66 3b 0a 20  uct stat sBuf;. 
3820: 20 20 20 66 73 74 61 74 28 70 43 73 72 2d 3e 66     fstat(pCsr->f
3830: 64 2c 20 26 73 42 75 66 29 3b 0a 0a 20 20 20 20  d, &sBuf);..    
3840: 69 66 28 20 53 5f 49 53 52 45 47 28 73 42 75 66  if( S_ISREG(sBuf
3850: 2e 73 74 5f 6d 6f 64 65 29 20 29 7b 0a 20 20 20  .st_mode) ){.   
3860: 20 20 20 69 66 28 20 69 3d 3d 31 20 29 7b 0a 20     if( i==1 ){. 
3870: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72         sqlite3_r
3880: 65 73 75 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c  esult_int64(ctx,
3890: 20 73 42 75 66 2e 73 74 5f 73 69 7a 65 29 3b 0a   sBuf.st_size);.
38a0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
38b0: 20 20 20 20 20 69 6e 74 20 6e 52 65 61 64 3b 0a       int nRead;.
38c0: 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 61 42          char *aB
38d0: 75 66 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  uf = sqlite3_mal
38e0: 6c 6f 63 28 73 42 75 66 2e 73 74 5f 6d 6f 64 65  loc(sBuf.st_mode
38f0: 2b 31 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  +1);.        if(
3900: 20 21 61 42 75 66 20 29 20 72 65 74 75 72 6e 20   !aBuf ) return 
3910: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
3920: 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 72 65        nRead = re
3930: 61 64 28 70 43 73 72 2d 3e 66 64 2c 20 61 42 75  ad(pCsr->fd, aBu
3940: 66 2c 20 73 42 75 66 2e 73 74 5f 6d 6f 64 65 29  f, sBuf.st_mode)
3950: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 6e 52  ;.        if( nR
3960: 65 61 64 21 3d 73 42 75 66 2e 73 74 5f 6d 6f 64  ead!=sBuf.st_mod
3970: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  e ){.          r
3980: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45  eturn SQLITE_IOE
3990: 52 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  RR;.        }.  
39a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
39b0: 73 75 6c 74 5f 62 6c 6f 62 28 63 74 78 2c 20 61  sult_blob(ctx, a
39c0: 42 75 66 2c 20 6e 52 65 61 64 2c 20 53 51 4c 49  Buf, nRead, SQLI
39d0: 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20  TE_TRANSIENT);. 
39e0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66         sqlite3_f
39f0: 72 65 65 28 61 42 75 66 29 3b 0a 20 20 20 20 20  ree(aBuf);.     
3a00: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
3a10: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
3a20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 52 6f 77 69  ;.}../*.** xRowi
3a30: 64 20 6d 65 74 68 6f 64 20 69 6d 70 6c 65 6d 65  d method impleme
3a40: 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  ntation..*/.stat
3a50: 69 63 20 69 6e 74 20 66 73 74 72 65 65 52 6f 77  ic int fstreeRow
3a60: 69 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  id(sqlite3_vtab_
3a70: 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c  cursor *cur, sql
3a80: 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
3a90: 64 29 7b 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20  d){.  *pRowid = 
3aa0: 30 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  0;.  return SQLI
3ab0: 54 45 5f 4f 4b 3b 0a 7d 0a 2f 2a 0a 2a 2a 20 45  TE_OK;.}./*.** E
3ac0: 6e 64 20 6f 66 20 66 73 74 72 65 65 20 69 6d 70  nd of fstree imp
3ad0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2a 2a  lementation..***
3ae0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3af0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3b00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3b10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3b20: 2a 2a 2a 2a 2a 2a 2f 0a 0a 0a 0a 0a 2f 2a 0a 2a  ******/...../*.*
3b30: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
3b40: 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  is the implement
3b50: 61 74 69 6f 6e 20 6f 66 20 62 6f 74 68 20 74 68  ation of both th
3b60: 65 20 78 43 6f 6e 6e 65 63 74 20 61 6e 64 20 78  e xConnect and x
3b70: 43 72 65 61 74 65 0a 2a 2a 20 6d 65 74 68 6f 64  Create.** method
3b80: 73 20 6f 66 20 74 68 65 20 66 73 20 76 69 72 74  s of the fs virt
3b90: 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a  ual table..**.**
3ba0: 20 54 68 65 20 61 72 67 76 5b 5d 20 61 72 72 61   The argv[] arra
3bb0: 79 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 66  y contains the f
3bc0: 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20  ollowing:.**.** 
3bd0: 20 20 61 72 67 76 5b 30 5d 20 20 20 2d 3e 20 6d    argv[0]   -> m
3be0: 6f 64 75 6c 65 20 6e 61 6d 65 20 20 28 22 66 73  odule name  ("fs
3bf0: 22 29 0a 2a 2a 20 20 20 61 72 67 76 5b 31 5d 20  ").**   argv[1] 
3c00: 20 20 2d 3e 20 64 61 74 61 62 61 73 65 20 6e 61    -> database na
3c10: 6d 65 0a 2a 2a 20 20 20 61 72 67 76 5b 32 5d 20  me.**   argv[2] 
3c20: 20 20 2d 3e 20 74 61 62 6c 65 20 6e 61 6d 65 0a    -> table name.
3c30: 2a 2a 20 20 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d  **   argv[...] -
3c40: 3e 20 6f 74 68 65 72 20 6d 6f 64 75 6c 65 20 61  > other module a
3c50: 72 67 75 6d 65 6e 74 20 66 69 65 6c 64 73 2e 0a  rgument fields..
3c60: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
3c70: 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69 74  Connect(.  sqlit
3c80: 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a  e3 *db,.  void *
3c90: 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63  pAux,.  int argc
3ca0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  , const char *co
3cb0: 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69  nst*argv,.  sqli
3cc0: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61  te3_vtab **ppVta
3cd0: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  b,.  char **pzEr
3ce0: 72 0a 29 7b 0a 20 20 66 73 5f 76 74 61 62 20 2a  r.){.  fs_vtab *
3cf0: 70 56 74 61 62 3b 0a 20 20 69 6e 74 20 6e 42 79  pVtab;.  int nBy
3d00: 74 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  te;.  const char
3d10: 20 2a 7a 54 62 6c 3b 0a 20 20 63 6f 6e 73 74 20   *zTbl;.  const 
3d20: 63 68 61 72 20 2a 7a 44 62 20 3d 20 61 72 67 76  char *zDb = argv
3d30: 5b 31 5d 3b 0a 0a 20 20 69 66 28 20 61 72 67 63  [1];..  if( argc
3d40: 21 3d 34 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72  !=4 ){.    *pzEr
3d50: 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  r = sqlite3_mpri
3d60: 6e 74 66 28 22 77 72 6f 6e 67 20 6e 75 6d 62 65  ntf("wrong numbe
3d70: 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 22 29  r of arguments")
3d80: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  ;.    return SQL
3d90: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  ITE_ERROR;.  }. 
3da0: 20 7a 54 62 6c 20 3d 20 61 72 67 76 5b 33 5d 3b   zTbl = argv[3];
3db0: 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  ..  nByte = size
3dc0: 6f 66 28 66 73 5f 76 74 61 62 29 20 2b 20 28 69  of(fs_vtab) + (i
3dd0: 6e 74 29 73 74 72 6c 65 6e 28 7a 54 62 6c 29 20  nt)strlen(zTbl) 
3de0: 2b 20 31 20 2b 20 28 69 6e 74 29 73 74 72 6c 65  + 1 + (int)strle
3df0: 6e 28 7a 44 62 29 20 2b 20 31 3b 0a 20 20 70 56  n(zDb) + 1;.  pV
3e00: 74 61 62 20 3d 20 28 66 73 5f 76 74 61 62 20 2a  tab = (fs_vtab *
3e10: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
3e20: 72 6f 28 20 6e 42 79 74 65 20 29 3b 0a 20 20 69  ro( nByte );.  i
3e30: 66 28 20 21 70 56 74 61 62 20 29 20 72 65 74 75  f( !pVtab ) retu
3e40: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
3e50: 0a 0a 20 20 70 56 74 61 62 2d 3e 7a 54 62 6c 20  ..  pVtab->zTbl 
3e60: 3d 20 28 63 68 61 72 20 2a 29 26 70 56 74 61 62  = (char *)&pVtab
3e70: 5b 31 5d 3b 0a 20 20 70 56 74 61 62 2d 3e 7a 44  [1];.  pVtab->zD
3e80: 62 20 3d 20 26 70 56 74 61 62 2d 3e 7a 54 62 6c  b = &pVtab->zTbl
3e90: 5b 73 74 72 6c 65 6e 28 7a 54 62 6c 29 2b 31 5d  [strlen(zTbl)+1]
3ea0: 3b 0a 20 20 70 56 74 61 62 2d 3e 64 62 20 3d 20  ;.  pVtab->db = 
3eb0: 64 62 3b 0a 20 20 6d 65 6d 63 70 79 28 70 56 74  db;.  memcpy(pVt
3ec0: 61 62 2d 3e 7a 54 62 6c 2c 20 7a 54 62 6c 2c 20  ab->zTbl, zTbl, 
3ed0: 73 74 72 6c 65 6e 28 7a 54 62 6c 29 29 3b 0a 20  strlen(zTbl));. 
3ee0: 20 6d 65 6d 63 70 79 28 70 56 74 61 62 2d 3e 7a   memcpy(pVtab->z
3ef0: 44 62 2c 20 7a 44 62 2c 20 73 74 72 6c 65 6e 28  Db, zDb, strlen(
3f00: 7a 44 62 29 29 3b 0a 20 20 2a 70 70 56 74 61 62  zDb));.  *ppVtab
3f10: 20 3d 20 26 70 56 74 61 62 2d 3e 62 61 73 65 3b   = &pVtab->base;
3f20: 0a 20 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61  .  sqlite3_decla
3f30: 72 65 5f 76 74 61 62 28 64 62 2c 20 22 43 52 45  re_vtab(db, "CRE
3f40: 41 54 45 20 54 41 42 4c 45 20 78 28 70 61 74 68  ATE TABLE x(path
3f50: 20 54 45 58 54 2c 20 64 61 74 61 20 54 45 58 54   TEXT, data TEXT
3f60: 29 22 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53  )");..  return S
3f70: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 2f 2a 20 4e  QLITE_OK;.}./* N
3f80: 6f 74 65 20 74 68 61 74 20 66 6f 72 20 74 68 69  ote that for thi
3f90: 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2c  s virtual table,
3fa0: 20 74 68 65 20 78 43 72 65 61 74 65 20 61 6e 64   the xCreate and
3fb0: 20 78 43 6f 6e 6e 65 63 74 0a 2a 2a 20 6d 65 74   xConnect.** met
3fc0: 68 6f 64 73 20 61 72 65 20 69 64 65 6e 74 69 63  hods are identic
3fd0: 61 6c 2e 20 2a 2f 0a 0a 73 74 61 74 69 63 20 69  al. */..static i
3fe0: 6e 74 20 66 73 44 69 73 63 6f 6e 6e 65 63 74 28  nt fsDisconnect(
3ff0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
4000: 74 61 62 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  tab){.  sqlite3_
4010: 66 72 65 65 28 70 56 74 61 62 29 3b 0a 20 20 72  free(pVtab);.  r
4020: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4030: 0a 7d 0a 2f 2a 20 54 68 65 20 78 44 69 73 63 6f  .}./* The xDisco
4040: 6e 6e 65 63 74 20 61 6e 64 20 78 44 65 73 74 72  nnect and xDestr
4050: 6f 79 20 6d 65 74 68 6f 64 73 20 61 72 65 20 61  oy methods are a
4060: 6c 73 6f 20 74 68 65 20 73 61 6d 65 20 2a 2f 0a  lso the same */.
4070: 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20 6e 65  ./*.** Open a ne
4080: 77 20 66 73 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a  w fs cursor..*/.
4090: 73 74 61 74 69 63 20 69 6e 74 20 66 73 4f 70 65  static int fsOpe
40a0: 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  n(sqlite3_vtab *
40b0: 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76  pVTab, sqlite3_v
40c0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43  tab_cursor **ppC
40d0: 75 72 73 6f 72 29 7b 0a 20 20 66 73 5f 63 75 72  ursor){.  fs_cur
40e0: 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75  sor *pCur;.  pCu
40f0: 72 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  r = sqlite3Mallo
4100: 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 66 73 5f  cZero(sizeof(fs_
4110: 63 75 72 73 6f 72 29 29 3b 0a 20 20 2a 70 70 43  cursor));.  *ppC
4120: 75 72 73 6f 72 20 3d 20 26 70 43 75 72 2d 3e 62  ursor = &pCur->b
4130: 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  ase;.  return SQ
4140: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
4150: 2a 20 43 6c 6f 73 65 20 61 20 66 73 20 63 75 72  * Close a fs cur
4160: 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  sor..*/.static i
4170: 6e 74 20 66 73 43 6c 6f 73 65 28 73 71 6c 69 74  nt fsClose(sqlit
4180: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
4190: 63 75 72 29 7b 0a 20 20 66 73 5f 63 75 72 73 6f  cur){.  fs_curso
41a0: 72 20 2a 70 43 75 72 20 3d 20 28 66 73 5f 63 75  r *pCur = (fs_cu
41b0: 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20 73 71  rsor *)cur;.  sq
41c0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
41d0: 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 73  Cur->pStmt);.  s
41e0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75 72  qlite3_free(pCur
41f0: 2d 3e 7a 42 75 66 29 3b 0a 20 20 73 71 6c 69 74  ->zBuf);.  sqlit
4200: 65 33 5f 66 72 65 65 28 70 43 75 72 29 3b 0a 20  e3_free(pCur);. 
4210: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4220: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
4230: 20 66 73 4e 65 78 74 28 73 71 6c 69 74 65 33 5f   fsNext(sqlite3_
4240: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
4250: 29 7b 0a 20 20 66 73 5f 63 75 72 73 6f 72 20 2a  ){.  fs_cursor *
4260: 70 43 75 72 20 3d 20 28 66 73 5f 63 75 72 73 6f  pCur = (fs_curso
4270: 72 20 2a 29 63 75 72 3b 0a 20 20 69 6e 74 20 72  r *)cur;.  int r
4280: 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
4290: 65 33 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 53  e3_step(pCur->pS
42a0: 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  tmt);.  if( rc==
42b0: 53 51 4c 49 54 45 5f 52 4f 57 20 7c 7c 20 72 63  SQLITE_ROW || rc
42c0: 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 20  ==SQLITE_DONE ) 
42d0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
42e0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
42f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 46 69  .static int fsFi
4300: 6c 74 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f  lter(.  sqlite3_
4310: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 56 74  vtab_cursor *pVt
4320: 61 62 43 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74  abCursor, .  int
4330: 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63   idxNum, const c
4340: 68 61 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69  har *idxStr,.  i
4350: 6e 74 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33  nt argc, sqlite3
4360: 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b  _value **argv.){
4370: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 66 73 5f  .  int rc;.  fs_
4380: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
4390: 66 73 5f 63 75 72 73 6f 72 20 2a 29 70 56 74 61  fs_cursor *)pVta
43a0: 62 43 75 72 73 6f 72 3b 0a 20 20 66 73 5f 76 74  bCursor;.  fs_vt
43b0: 61 62 20 2a 70 20 3d 20 28 66 73 5f 76 74 61 62  ab *p = (fs_vtab
43c0: 20 2a 29 28 70 56 74 61 62 43 75 72 73 6f 72 2d   *)(pVtabCursor-
43d0: 3e 70 56 74 61 62 29 3b 0a 0a 20 20 61 73 73 65  >pVtab);..  asse
43e0: 72 74 28 20 28 69 64 78 4e 75 6d 3d 3d 30 20 26  rt( (idxNum==0 &
43f0: 26 20 61 72 67 63 3d 3d 30 29 20 7c 7c 20 28 69  & argc==0) || (i
4400: 64 78 4e 75 6d 3d 3d 31 20 26 26 20 61 72 67 63  dxNum==1 && argc
4410: 3d 3d 31 29 20 29 3b 0a 20 20 69 66 28 20 69 64  ==1) );.  if( id
4420: 78 4e 75 6d 3d 3d 31 20 29 7b 0a 20 20 20 20 63  xNum==1 ){.    c
4430: 68 61 72 20 2a 7a 53 74 6d 74 20 3d 20 73 71 6c  har *zStmt = sql
4440: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20  ite3_mprintf(.  
4450: 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 2a 20        "SELECT * 
4460: 46 52 4f 4d 20 25 51 2e 25 51 20 57 48 45 52 45  FROM %Q.%Q WHERE
4470: 20 72 6f 77 69 64 3d 3f 22 2c 20 70 2d 3e 7a 44   rowid=?", p->zD
4480: 62 2c 20 70 2d 3e 7a 54 62 6c 29 3b 0a 20 20 20  b, p->zTbl);.   
4490: 20 69 66 28 20 21 7a 53 74 6d 74 20 29 20 72 65   if( !zStmt ) re
44a0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
44b0: 4d 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  M;.    rc = sqli
44c0: 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 70  te3_prepare_v2(p
44d0: 2d 3e 64 62 2c 20 7a 53 74 6d 74 2c 20 2d 31 2c  ->db, zStmt, -1,
44e0: 20 26 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 30   &pCur->pStmt, 0
44f0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
4500: 72 65 65 28 7a 53 74 6d 74 29 3b 0a 20 20 20 20  ree(zStmt);.    
4510: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
4520: 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  K ){.      sqlit
4530: 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 43  e3_bind_value(pC
4540: 75 72 2d 3e 70 53 74 6d 74 2c 20 31 2c 20 61 72  ur->pStmt, 1, ar
4550: 67 76 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20  gv[0]);.    }.  
4560: 7d 65 6c 73 65 7b 0a 20 20 20 20 63 68 61 72 20  }else{.    char 
4570: 2a 7a 53 74 6d 74 20 3d 20 73 71 6c 69 74 65 33  *zStmt = sqlite3
4580: 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54  _mprintf("SELECT
4590: 20 2a 20 46 52 4f 4d 20 25 51 2e 25 51 22 2c 20   * FROM %Q.%Q", 
45a0: 70 2d 3e 7a 44 62 2c 20 70 2d 3e 7a 54 62 6c 29  p->zDb, p->zTbl)
45b0: 3b 0a 20 20 20 20 69 66 28 20 21 7a 53 74 6d 74  ;.    if( !zStmt
45c0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
45d0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 63 20 3d  _NOMEM;.    rc =
45e0: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
45f0: 5f 76 32 28 70 2d 3e 64 62 2c 20 7a 53 74 6d 74  _v2(p->db, zStmt
4600: 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e 70 53 74  , -1, &pCur->pSt
4610: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69  mt, 0);.    sqli
4620: 74 65 33 5f 66 72 65 65 28 7a 53 74 6d 74 29 3b  te3_free(zStmt);
4630: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
4640: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4650: 20 72 63 20 3d 20 66 73 4e 65 78 74 28 70 56 74   rc = fsNext(pVt
4660: 61 62 43 75 72 73 6f 72 29 3b 20 0a 20 20 7d 0a  abCursor); .  }.
4670: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
4680: 73 74 61 74 69 63 20 69 6e 74 20 66 73 43 6f 6c  static int fsCol
4690: 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62  umn(sqlite3_vtab
46a0: 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71  _cursor *cur, sq
46b0: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63  lite3_context *c
46c0: 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20 66 73  tx, int i){.  fs
46d0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  _cursor *pCur = 
46e0: 28 66 73 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b  (fs_cursor*)cur;
46f0: 0a 0a 20 20 61 73 73 65 72 74 28 20 69 3d 3d 30  ..  assert( i==0
4700: 20 7c 7c 20 69 3d 3d 31 20 7c 7c 20 69 3d 3d 32   || i==1 || i==2
4710: 20 29 3b 0a 20 20 69 66 28 20 69 3d 3d 30 20 29   );.  if( i==0 )
4720: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  {.    sqlite3_re
4730: 73 75 6c 74 5f 76 61 6c 75 65 28 63 74 78 2c 20  sult_value(ctx, 
4740: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76  sqlite3_column_v
4750: 61 6c 75 65 28 70 43 75 72 2d 3e 70 53 74 6d 74  alue(pCur->pStmt
4760: 2c 20 30 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  , 0));.  }else{.
4770: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
4780: 7a 46 69 6c 65 20 3d 20 28 63 6f 6e 73 74 20 63  zFile = (const c
4790: 68 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f  har *)sqlite3_co
47a0: 6c 75 6d 6e 5f 74 65 78 74 28 70 43 75 72 2d 3e  lumn_text(pCur->
47b0: 70 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20 73  pStmt, 1);.    s
47c0: 74 72 75 63 74 20 73 74 61 74 20 73 62 75 66 3b  truct stat sbuf;
47d0: 0a 20 20 20 20 69 6e 74 20 66 64 3b 0a 0a 20 20  .    int fd;..  
47e0: 20 20 69 6e 74 20 6e 3b 0a 20 20 20 20 66 64 20    int n;.    fd 
47f0: 3d 20 6f 70 65 6e 28 7a 46 69 6c 65 2c 20 4f 5f  = open(zFile, O_
4800: 52 44 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28  RDONLY);.    if(
4810: 20 66 64 3c 30 20 29 20 72 65 74 75 72 6e 20 53   fd<0 ) return S
4820: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 20  QLITE_IOERR;.   
4830: 20 66 73 74 61 74 28 66 64 2c 20 26 73 62 75 66   fstat(fd, &sbuf
4840: 29 3b 0a 0a 20 20 20 20 69 66 28 20 73 62 75 66  );..    if( sbuf
4850: 2e 73 74 5f 73 69 7a 65 3e 3d 70 43 75 72 2d 3e  .st_size>=pCur->
4860: 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 20 20  nAlloc ){.      
4870: 69 6e 74 20 6e 4e 65 77 20 3d 20 73 62 75 66 2e  int nNew = sbuf.
4880: 73 74 5f 73 69 7a 65 2a 32 3b 0a 20 20 20 20 20  st_size*2;.     
4890: 20 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 20   char *zNew;.   
48a0: 20 20 20 69 66 28 20 6e 4e 65 77 3c 31 30 32 34     if( nNew<1024
48b0: 20 29 20 6e 4e 65 77 20 3d 20 31 30 32 34 3b 0a   ) nNew = 1024;.
48c0: 0a 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71  .      zNew = sq
48d0: 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28 70 43 75  lite3Realloc(pCu
48e0: 72 2d 3e 7a 42 75 66 2c 20 6e 4e 65 77 29 3b 0a  r->zBuf, nNew);.
48f0: 20 20 20 20 20 20 69 66 28 20 7a 4e 65 77 3d 3d        if( zNew==
4900: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6c 6f  0 ){.        clo
4910: 73 65 28 66 64 29 3b 0a 20 20 20 20 20 20 20 20  se(fd);.        
4920: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
4930: 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  MEM;.      }.   
4940: 20 20 20 70 43 75 72 2d 3e 7a 42 75 66 20 3d 20     pCur->zBuf = 
4950: 7a 4e 65 77 3b 0a 20 20 20 20 20 20 70 43 75 72  zNew;.      pCur
4960: 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b  ->nAlloc = nNew;
4970: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6e 20 3d 20  .    }..    n = 
4980: 28 69 6e 74 29 72 65 61 64 28 66 64 2c 20 70 43  (int)read(fd, pC
4990: 75 72 2d 3e 7a 42 75 66 2c 20 73 62 75 66 2e 73  ur->zBuf, sbuf.s
49a0: 74 5f 73 69 7a 65 29 3b 0a 20 20 20 20 63 6c 6f  t_size);.    clo
49b0: 73 65 28 66 64 29 3b 0a 20 20 20 20 69 66 28 20  se(fd);.    if( 
49c0: 6e 21 3d 73 62 75 66 2e 73 74 5f 73 69 7a 65 20  n!=sbuf.st_size 
49d0: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
49e0: 45 52 52 4f 52 3b 0a 20 20 20 20 70 43 75 72 2d  ERROR;.    pCur-
49f0: 3e 6e 42 75 66 20 3d 20 73 62 75 66 2e 73 74 5f  >nBuf = sbuf.st_
4a00: 73 69 7a 65 3b 0a 20 20 20 20 70 43 75 72 2d 3e  size;.    pCur->
4a10: 7a 42 75 66 5b 70 43 75 72 2d 3e 6e 42 75 66 5d  zBuf[pCur->nBuf]
4a20: 20 3d 20 27 5c 30 27 3b 0a 0a 20 20 20 20 73 71   = '\0';..    sq
4a30: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
4a40: 74 28 63 74 78 2c 20 70 43 75 72 2d 3e 7a 42 75  t(ctx, pCur->zBu
4a50: 66 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52  f, -1, SQLITE_TR
4a60: 41 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20  ANSIENT);.  }.  
4a70: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
4a80: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
4a90: 66 73 52 6f 77 69 64 28 73 71 6c 69 74 65 33 5f  fsRowid(sqlite3_
4aa0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
4ab0: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a  , sqlite_int64 *
4ac0: 70 52 6f 77 69 64 29 7b 0a 20 20 66 73 5f 63 75  pRowid){.  fs_cu
4ad0: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73  rsor *pCur = (fs
4ae0: 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20  _cursor*)cur;.  
4af0: 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65  *pRowid = sqlite
4b00: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70  3_column_int64(p
4b10: 43 75 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a  Cur->pStmt, 0);.
4b20: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
4b30: 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  OK;.}..static in
4b40: 74 20 66 73 45 6f 66 28 73 71 6c 69 74 65 33 5f  t fsEof(sqlite3_
4b50: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
4b60: 29 7b 0a 20 20 66 73 5f 63 75 72 73 6f 72 20 2a  ){.  fs_cursor *
4b70: 70 43 75 72 20 3d 20 28 66 73 5f 63 75 72 73 6f  pCur = (fs_curso
4b80: 72 2a 29 63 75 72 3b 0a 20 20 72 65 74 75 72 6e  r*)cur;.  return
4b90: 20 28 73 71 6c 69 74 65 33 5f 64 61 74 61 5f 63   (sqlite3_data_c
4ba0: 6f 75 6e 74 28 70 43 75 72 2d 3e 70 53 74 6d 74  ount(pCur->pStmt
4bb0: 29 3d 3d 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  )==0);.}..static
4bc0: 20 69 6e 74 20 66 73 42 65 73 74 49 6e 64 65 78   int fsBestIndex
4bd0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
4be0: 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  ab, sqlite3_inde
4bf0: 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f  x_info *pIdxInfo
4c00: 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 0a 20 20  ){.  int ii;..  
4c10: 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 49 64  for(ii=0; ii<pId
4c20: 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69  xInfo->nConstrai
4c30: 6e 74 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 73  nt; ii++){.    s
4c40: 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e  truct sqlite3_in
4c50: 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 63  dex_constraint c
4c60: 6f 6e 73 74 20 2a 70 43 6f 6e 73 20 3d 20 26 70  onst *pCons = &p
4c70: 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  IdxInfo->aConstr
4c80: 61 69 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 69 66  aint[ii];.    if
4c90: 28 20 70 43 6f 6e 73 2d 3e 69 43 6f 6c 75 6d 6e  ( pCons->iColumn
4ca0: 3c 30 20 26 26 20 70 43 6f 6e 73 2d 3e 75 73 61  <0 && pCons->usa
4cb0: 62 6c 65 0a 20 20 20 20 20 20 20 20 20 20 20 26  ble.           &
4cc0: 26 20 70 43 6f 6e 73 2d 3e 6f 70 3d 3d 53 51 4c  & pCons->op==SQL
4cd0: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
4ce0: 41 49 4e 54 5f 45 51 20 29 7b 0a 20 20 20 20 20  AINT_EQ ){.     
4cf0: 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f   struct sqlite3_
4d00: 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74  index_constraint
4d10: 5f 75 73 61 67 65 20 2a 70 55 73 61 67 65 3b 0a  _usage *pUsage;.
4d20: 20 20 20 20 20 20 70 55 73 61 67 65 20 3d 20 26        pUsage = &
4d30: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
4d40: 72 61 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a  raintUsage[ii];.
4d50: 20 20 20 20 20 20 70 55 73 61 67 65 2d 3e 6f 6d        pUsage->om
4d60: 69 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 55  it = 0;.      pU
4d70: 73 61 67 65 2d 3e 61 72 67 76 49 6e 64 65 78 20  sage->argvIndex 
4d80: 3d 20 31 3b 0a 20 20 20 20 20 20 70 49 64 78 49  = 1;.      pIdxI
4d90: 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 31 3b  nfo->idxNum = 1;
4da0: 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d  .      pIdxInfo-
4db0: 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d  >estimatedCost =
4dc0: 20 31 2e 30 3b 0a 20 20 20 20 20 20 62 72 65 61   1.0;.      brea
4dd0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  k;.    }.  }..  
4de0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
4df0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 76 69 72  ;.}../*.** A vir
4e00: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
4e10: 65 20 74 68 61 74 20 70 72 6f 76 69 64 65 73 20  e that provides 
4e20: 72 65 61 64 2d 6f 6e 6c 79 20 61 63 63 65 73 73  read-only access
4e30: 20 74 6f 20 61 0a 2a 2a 20 54 63 6c 20 67 6c 6f   to a.** Tcl glo
4e40: 62 61 6c 20 76 61 72 69 61 62 6c 65 20 6e 61 6d  bal variable nam
4e50: 65 73 70 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69  espace..*/.stati
4e60: 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65  c sqlite3_module
4e70: 20 66 73 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20   fsModule = {.  
4e80: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
4e90: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
4ea0: 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 66 73 43 6f  ersion */.  fsCo
4eb0: 6e 6e 65 63 74 2c 0a 20 20 66 73 43 6f 6e 6e 65  nnect,.  fsConne
4ec0: 63 74 2c 0a 20 20 66 73 42 65 73 74 49 6e 64 65  ct,.  fsBestInde
4ed0: 78 2c 0a 20 20 66 73 44 69 73 63 6f 6e 6e 65 63  x,.  fsDisconnec
4ee0: 74 2c 20 0a 20 20 66 73 44 69 73 63 6f 6e 6e 65  t, .  fsDisconne
4ef0: 63 74 2c 0a 20 20 66 73 4f 70 65 6e 2c 20 20 20  ct,.  fsOpen,   
4f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4f10: 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70     /* xOpen - op
4f20: 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  en a cursor */. 
4f30: 20 66 73 43 6c 6f 73 65 2c 20 20 20 20 20 20 20   fsClose,       
4f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4f50: 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20   xClose - close 
4f60: 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66 73  a cursor */.  fs
4f70: 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20  Filter,         
4f80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
4f90: 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72  ilter - configur
4fa0: 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e  e scan constrain
4fb0: 74 73 20 2a 2f 0a 20 20 66 73 4e 65 78 74 2c 20  ts */.  fsNext, 
4fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4fd0: 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20       /* xNext - 
4fe0: 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72  advance a cursor
4ff0: 20 2a 2f 0a 20 20 66 73 45 6f 66 2c 20 20 20 20   */.  fsEof,    
5000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5010: 20 20 20 2f 2a 20 78 45 6f 66 20 2d 20 63 68 65     /* xEof - che
5020: 63 6b 20 66 6f 72 20 65 6e 64 20 6f 66 20 73 63  ck for end of sc
5030: 61 6e 20 2a 2f 0a 20 20 66 73 43 6f 6c 75 6d 6e  an */.  fsColumn
5040: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5050: 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20       /* xColumn 
5060: 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20  - read data */. 
5070: 20 66 73 52 6f 77 69 64 2c 20 20 20 20 20 20 20   fsRowid,       
5080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5090: 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64   xRowid - read d
50a0: 61 74 61 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ata */.  0,     
50b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50c0: 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74 65        /* xUpdate
50d0: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
50e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50f0: 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a 2f 0a     /* xBegin */.
5100: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
5110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5120: 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 30 2c 20  * xSync */.  0, 
5130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5140: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
5150: 6d 6d 69 74 20 2a 2f 0a 20 20 30 2c 20 20 20 20  mmit */.  0,    
5160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5170: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62         /* xRollb
5180: 61 63 6b 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ack */.  0,     
5190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51a0: 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 4d 65        /* xFindMe
51b0: 74 68 6f 64 20 2a 2f 0a 20 20 30 2c 20 20 20 20  thod */.  0,    
51c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51d0: 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6e 61 6d         /* xRenam
51e0: 65 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20  e */.};..static 
51f0: 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 66  sqlite3_module f
5200: 73 64 69 72 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20  sdirModule = {. 
5210: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
5220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5230: 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a   /* iVersion */.
5240: 20 20 66 73 64 69 72 43 6f 6e 6e 65 63 74 2c 20    fsdirConnect, 
5250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5260: 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a    /* xCreate */.
5270: 20 20 66 73 64 69 72 43 6f 6e 6e 65 63 74 2c 20    fsdirConnect, 
5280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5290: 20 20 2f 2a 20 78 43 6f 6e 6e 65 63 74 20 2a 2f    /* xConnect */
52a0: 0a 20 20 66 73 64 69 72 42 65 73 74 49 6e 64 65  .  fsdirBestInde
52b0: 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x,              
52c0: 20 20 20 2f 2a 20 78 42 65 73 74 49 6e 64 65 78     /* xBestIndex
52d0: 20 2a 2f 0a 20 20 66 73 64 69 72 44 69 73 63 6f   */.  fsdirDisco
52e0: 6e 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20  nnect,          
52f0: 20 20 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e        /* xDiscon
5300: 6e 65 63 74 20 2a 2f 0a 20 20 66 73 64 69 72 44  nect */.  fsdirD
5310: 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20  isconnect,      
5320: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
5330: 73 74 72 6f 79 20 2a 2f 0a 20 20 66 73 64 69 72  stroy */.  fsdir
5340: 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20  Open,           
5350: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f             /* xO
5360: 70 65 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72  pen - open a cur
5370: 73 6f 72 20 2a 2f 0a 20 20 66 73 64 69 72 43 6c  sor */.  fsdirCl
5380: 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ose,            
5390: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f           /* xClo
53a0: 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72  se - close a cur
53b0: 73 6f 72 20 2a 2f 0a 20 20 66 73 64 69 72 46 69  sor */.  fsdirFi
53c0: 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20  lter,           
53d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c           /* xFil
53e0: 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20  ter - configure 
53f0: 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73  scan constraints
5400: 20 2a 2f 0a 20 20 66 73 64 69 72 4e 65 78 74 2c   */.  fsdirNext,
5410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5420: 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d        /* xNext -
5430: 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f   advance a curso
5440: 72 20 2a 2f 0a 20 20 66 73 64 69 72 45 6f 66 2c  r */.  fsdirEof,
5450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5460: 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 2d         /* xEof -
5470: 20 63 68 65 63 6b 20 66 6f 72 20 65 6e 64 20 6f   check for end o
5480: 66 20 73 63 61 6e 20 2a 2f 0a 20 20 66 73 64 69  f scan */.  fsdi
5490: 72 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20  rColumn,        
54a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
54b0: 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61  Column - read da
54c0: 74 61 20 2a 2f 0a 20 20 66 73 64 69 72 52 6f 77  ta */.  fsdirRow
54d0: 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  id,             
54e0: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69          /* xRowi
54f0: 64 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  d - read data */
5500: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
5510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5520: 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2a 2f     /* xUpdate */
5530: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
5540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5550: 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a 2f 0a     /* xBegin */.
5560: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
5570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5580: 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20    /* xSync */.  
5590: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
55a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55b0: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20  /* xCommit */.  
55c0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
55d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55e0: 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a  /* xRollback */.
55f0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
5600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5610: 20 20 2f 2a 20 78 46 69 6e 64 4d 65 74 68 6f 64    /* xFindMethod
5620: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
5630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5640: 20 20 20 20 20 20 2f 2a 20 78 52 65 6e 61 6d 65        /* xRename
5650: 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 73   */.};..static s
5660: 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 66 73  qlite3_module fs
5670: 74 72 65 65 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20  treeModule = {. 
5680: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
5690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56a0: 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a   /* iVersion */.
56b0: 20 20 66 73 74 72 65 65 43 6f 6e 6e 65 63 74 2c    fstreeConnect,
56c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56d0: 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a    /* xCreate */.
56e0: 20 20 66 73 74 72 65 65 43 6f 6e 6e 65 63 74 2c    fstreeConnect,
56f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5700: 20 20 2f 2a 20 78 43 6f 6e 6e 65 63 74 20 2a 2f    /* xConnect */
5710: 0a 20 20 66 73 74 72 65 65 42 65 73 74 49 6e 64  .  fstreeBestInd
5720: 65 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ex,             
5730: 20 20 20 2f 2a 20 78 42 65 73 74 49 6e 64 65 78     /* xBestIndex
5740: 20 2a 2f 0a 20 20 66 73 74 72 65 65 44 69 73 63   */.  fstreeDisc
5750: 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20  onnect,         
5760: 20 20 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e        /* xDiscon
5770: 6e 65 63 74 20 2a 2f 0a 20 20 66 73 74 72 65 65  nect */.  fstree
5780: 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20  Disconnect,     
5790: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
57a0: 73 74 72 6f 79 20 2a 2f 0a 20 20 66 73 74 72 65  stroy */.  fstre
57b0: 65 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  eOpen,          
57c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f             /* xO
57d0: 70 65 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72  pen - open a cur
57e0: 73 6f 72 20 2a 2f 0a 20 20 66 73 74 72 65 65 43  sor */.  fstreeC
57f0: 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20  lose,           
5800: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f           /* xClo
5810: 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72  se - close a cur
5820: 73 6f 72 20 2a 2f 0a 20 20 66 73 74 72 65 65 46  sor */.  fstreeF
5830: 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20 20  ilter,          
5840: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c           /* xFil
5850: 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20  ter - configure 
5860: 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73  scan constraints
5870: 20 2a 2f 0a 20 20 66 73 74 72 65 65 4e 65 78 74   */.  fstreeNext
5880: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5890: 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d        /* xNext -
58a0: 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f   advance a curso
58b0: 72 20 2a 2f 0a 20 20 66 73 74 72 65 65 45 6f 66  r */.  fstreeEof
58c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
58d0: 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 2d         /* xEof -
58e0: 20 63 68 65 63 6b 20 66 6f 72 20 65 6e 64 20 6f   check for end o
58f0: 66 20 73 63 61 6e 20 2a 2f 0a 20 20 66 73 74 72  f scan */.  fstr
5900: 65 65 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20  eeColumn,       
5910: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5920: 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61  Column - read da
5930: 74 61 20 2a 2f 0a 20 20 66 73 74 72 65 65 52 6f  ta */.  fstreeRo
5940: 77 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  wid,            
5950: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69          /* xRowi
5960: 64 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  d - read data */
5970: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
5980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5990: 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2a 2f     /* xUpdate */
59a0: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
59b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59c0: 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a 2f 0a     /* xBegin */.
59d0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
59e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59f0: 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20    /* xSync */.  
5a00: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
5a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a20: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20  /* xCommit */.  
5a30: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
5a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a50: 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a  /* xRollback */.
5a60: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
5a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a80: 20 20 2f 2a 20 78 46 69 6e 64 4d 65 74 68 6f 64    /* xFindMethod
5a90: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
5aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ab0: 20 20 20 20 20 20 2f 2a 20 78 52 65 6e 61 6d 65        /* xRename
5ac0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65   */.};../*.** De
5ad0: 63 6f 64 65 20 61 20 70 6f 69 6e 74 65 72 20 74  code a pointer t
5ae0: 6f 20 61 6e 20 73 71 6c 69 74 65 33 20 6f 62 6a  o an sqlite3 obj
5af0: 65 63 74 2e 0a 2a 2f 0a 65 78 74 65 72 6e 20 69  ect..*/.extern i
5b00: 6e 74 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28  nt getDbPointer(
5b10: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
5b20: 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  rp, const char *
5b30: 7a 41 2c 20 73 71 6c 69 74 65 33 20 2a 2a 70 70  zA, sqlite3 **pp
5b40: 44 62 29 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69  Db);../*.** Regi
5b50: 73 74 65 72 20 74 68 65 20 65 63 68 6f 20 76 69  ster the echo vi
5b60: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
5b70: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
5b80: 74 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20  t SQLITE_TCLAPI 
5b90: 72 65 67 69 73 74 65 72 5f 66 73 5f 6d 6f 64 75  register_fs_modu
5ba0: 6c 65 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61  le(.  ClientData
5bb0: 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20   clientData, /* 
5bc0: 50 6f 69 6e 74 65 72 20 74 6f 20 73 71 6c 69 74  Pointer to sqlit
5bd0: 65 33 5f 65 6e 61 62 6c 65 5f 58 58 58 20 66 75  e3_enable_XXX fu
5be0: 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f  nction */.  Tcl_
5bf0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
5c00: 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e     /* The TCL in
5c10: 74 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69  terpreter that i
5c20: 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d  nvoked this comm
5c30: 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a  and */.  int obj
5c40: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
5c50: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67  /* Number of arg
5c60: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f  uments */.  Tcl_
5c70: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
5c80: 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72  ]  /* Command ar
5c90: 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20  guments */.){.  
5ca0: 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 69  sqlite3 *db;.  i
5cb0: 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20  f( objc!=2 ){.  
5cc0: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
5cd0: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
5ce0: 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20 20 20 72  jv, "DB");.    r
5cf0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
5d00: 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74 44 62  .  }.  if( getDb
5d10: 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70 2c 20  Pointer(interp, 
5d20: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
5d30: 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29 20 72  jv[1]), &db) ) r
5d40: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
5d50: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
5d60: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
5d70: 45 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61  E.  sqlite3_crea
5d80: 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22 66  te_module(db, "f
5d90: 73 22 2c 20 26 66 73 4d 6f 64 75 6c 65 2c 20 28  s", &fsModule, (
5da0: 76 6f 69 64 20 2a 29 69 6e 74 65 72 70 29 3b 0a  void *)interp);.
5db0: 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65    sqlite3_create
5dc0: 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22 66 73 64  _module(db, "fsd
5dd0: 69 72 22 2c 20 26 66 73 64 69 72 4d 6f 64 75 6c  ir", &fsdirModul
5de0: 65 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33  e, 0);.  sqlite3
5df0: 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64  _create_module(d
5e00: 62 2c 20 22 66 73 74 72 65 65 22 2c 20 26 66 73  b, "fstree", &fs
5e10: 74 72 65 65 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a  treeModule, 0);.
5e20: 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20  #endif.  return 
5e30: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69  TCL_OK;.}..#endi
5e40: 66 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  f.../*.** Regist
5e50: 65 72 20 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68  er commands with
5e60: 20 74 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72   the TCL interpr
5e70: 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c  eter..*/.int Sql
5e80: 69 74 65 74 65 73 74 66 73 5f 49 6e 69 74 28 54  itetestfs_Init(T
5e90: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
5ea0: 70 29 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  p){.#ifndef SQLI
5eb0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
5ec0: 41 42 4c 45 0a 20 20 73 74 61 74 69 63 20 73 74  ABLE.  static st
5ed0: 72 75 63 74 20 7b 0a 20 20 20 20 20 63 68 61 72  ruct {.     char
5ee0: 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63   *zName;.     Tc
5ef0: 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50  l_ObjCmdProc *xP
5f00: 72 6f 63 3b 0a 20 20 20 20 20 76 6f 69 64 20 2a  roc;.     void *
5f10: 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 7d 20  clientData;.  } 
5f20: 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a 20 20  aObjCmd[] = {.  
5f30: 20 20 20 7b 20 22 72 65 67 69 73 74 65 72 5f 66     { "register_f
5f40: 73 5f 6d 6f 64 75 6c 65 22 2c 20 20 20 72 65 67  s_module",   reg
5f50: 69 73 74 65 72 5f 66 73 5f 6d 6f 64 75 6c 65 2c  ister_fs_module,
5f60: 20 30 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74   0 },.  };.  int
5f70: 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
5f80: 3c 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 29  <sizeof(aObjCmd)
5f90: 2f 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 5b  /sizeof(aObjCmd[
5fa0: 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54  0]); i++){.    T
5fb0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
5fc0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 61 4f 62 6a  and(interp, aObj
5fd0: 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 0a 20  Cmd[i].zName, . 
5fe0: 20 20 20 20 20 20 20 61 4f 62 6a 43 6d 64 5b 69         aObjCmd[i
5ff0: 5d 2e 78 50 72 6f 63 2c 20 61 4f 62 6a 43 6d 64  ].xProc, aObjCmd
6000: 5b 69 5d 2e 63 6c 69 65 6e 74 44 61 74 61 2c 20  [i].clientData, 
6010: 30 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20  0);.  }.#endif. 
6020: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
6030: 7d 0a                                            }.