/ Hex Artifact Content
Login

Artifact e16cbe68d3b107e00a907c20a9a02629870eb69b:


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 0a 20 20  y;.    }.  }..  
3510: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78  sqlite3_bind_tex
3520: 74 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 31  t(pCsr->pStmt, 1
3530: 2c 20 7a 44 69 72 2c 20 6e 44 69 72 2c 20 53 51  , zDir, nDir, SQ
3540: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
3550: 0a 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f  .  sqlite3_bind_
3560: 74 65 78 74 28 70 43 73 72 2d 3e 70 53 74 6d 74  text(pCsr->pStmt
3570: 2c 20 32 2c 20 7a 52 6f 6f 74 2c 20 6e 52 6f 6f  , 2, zRoot, nRoo
3580: 74 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49  t, SQLITE_TRANSI
3590: 45 4e 54 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ENT);.  sqlite3_
35a0: 62 69 6e 64 5f 74 65 78 74 28 70 43 73 72 2d 3e  bind_text(pCsr->
35b0: 70 53 74 6d 74 2c 20 33 2c 20 7a 50 72 65 66 69  pStmt, 3, zPrefi
35c0: 78 2c 20 6e 50 72 65 66 69 78 2c 20 53 51 4c 49  x, nPrefix, SQLI
35d0: 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 0a  TE_TRANSIENT);..
35e0: 23 69 66 20 53 51 4c 49 54 45 5f 4f 53 5f 57 49  #if SQLITE_OS_WI
35f0: 4e 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  N.  sqlite3_free
3600: 28 7a 50 72 65 66 69 78 29 3b 0a 20 20 73 71 6c  (zPrefix);.  sql
3610: 69 74 65 33 5f 66 72 65 65 28 7a 52 6f 6f 74 29  ite3_free(zRoot)
3620: 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 72 65 74 75  ;.#endif..  retu
3630: 72 6e 20 66 73 74 72 65 65 4e 65 78 74 28 70 56  rn fstreeNext(pV
3640: 74 61 62 43 75 72 73 6f 72 29 3b 20 0a 7d 0a 0a  tabCursor); .}..
3650: 2f 2a 0a 2a 2a 20 78 45 6f 66 20 6d 65 74 68 6f  /*.** xEof metho
3660: 64 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  d implementation
3670: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3680: 66 73 74 72 65 65 45 6f 66 28 73 71 6c 69 74 65  fstreeEof(sqlite
3690: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
36a0: 75 72 29 7b 0a 20 20 46 73 74 72 65 65 43 73 72  ur){.  FstreeCsr
36b0: 20 2a 70 43 73 72 20 3d 20 28 46 73 74 72 65 65   *pCsr = (Fstree
36c0: 43 73 72 2a 29 63 75 72 3b 0a 20 20 72 65 74 75  Csr*)cur;.  retu
36d0: 72 6e 20 70 43 73 72 2d 3e 70 53 74 6d 74 3d 3d  rn pCsr->pStmt==
36e0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 43 6f 6c  0;.}../*.** xCol
36f0: 75 6d 6e 20 6d 65 74 68 6f 64 20 69 6d 70 6c 65  umn method imple
3700: 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74  mentation..*/.st
3710: 61 74 69 63 20 69 6e 74 20 66 73 74 72 65 65 43  atic int fstreeC
3720: 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74  olumn(sqlite3_vt
3730: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20  ab_cursor *cur, 
3740: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
3750: 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20  *ctx, int i){.  
3760: 46 73 74 72 65 65 43 73 72 20 2a 70 43 73 72 20  FstreeCsr *pCsr 
3770: 3d 20 28 46 73 74 72 65 65 43 73 72 2a 29 63 75  = (FstreeCsr*)cu
3780: 72 3b 0a 20 20 69 66 28 20 69 3d 3d 30 20 29 7b  r;.  if( i==0 ){
3790: 20 20 20 20 20 20 2f 2a 20 70 61 74 68 20 2a 2f        /* path */
37a0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
37b0: 75 6c 74 5f 76 61 6c 75 65 28 63 74 78 2c 20 73  ult_value(ctx, s
37c0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61  qlite3_column_va
37d0: 6c 75 65 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c  lue(pCsr->pStmt,
37e0: 20 30 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   0));.  }else{. 
37f0: 20 20 20 73 74 72 75 63 74 20 73 74 61 74 20 73     struct stat s
3800: 42 75 66 3b 0a 20 20 20 20 66 73 74 61 74 28 70  Buf;.    fstat(p
3810: 43 73 72 2d 3e 66 64 2c 20 26 73 42 75 66 29 3b  Csr->fd, &sBuf);
3820: 0a 0a 20 20 20 20 69 66 28 20 53 5f 49 53 52 45  ..    if( S_ISRE
3830: 47 28 73 42 75 66 2e 73 74 5f 6d 6f 64 65 29 20  G(sBuf.st_mode) 
3840: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3d 3d  ){.      if( i==
3850: 31 20 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c  1 ){.        sql
3860: 69 74 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36  ite3_result_int6
3870: 34 28 63 74 78 2c 20 73 42 75 66 2e 73 74 5f 73  4(ctx, sBuf.st_s
3880: 69 7a 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ize);.      }els
3890: 65 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  e{.        int n
38a0: 52 65 61 64 3b 0a 20 20 20 20 20 20 20 20 63 68  Read;.        ch
38b0: 61 72 20 2a 61 42 75 66 20 3d 20 73 71 6c 69 74  ar *aBuf = sqlit
38c0: 65 33 5f 6d 61 6c 6c 6f 63 28 73 42 75 66 2e 73  e3_malloc(sBuf.s
38d0: 74 5f 6d 6f 64 65 2b 31 29 3b 0a 20 20 20 20 20  t_mode+1);.     
38e0: 20 20 20 69 66 28 20 21 61 42 75 66 20 29 20 72     if( !aBuf ) r
38f0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
3900: 45 4d 3b 0a 20 20 20 20 20 20 20 20 6e 52 65 61  EM;.        nRea
3910: 64 20 3d 20 72 65 61 64 28 70 43 73 72 2d 3e 66  d = read(pCsr->f
3920: 64 2c 20 61 42 75 66 2c 20 73 42 75 66 2e 73 74  d, aBuf, sBuf.st
3930: 5f 6d 6f 64 65 29 3b 0a 20 20 20 20 20 20 20 20  _mode);.        
3940: 69 66 28 20 6e 52 65 61 64 21 3d 73 42 75 66 2e  if( nRead!=sBuf.
3950: 73 74 5f 6d 6f 64 65 20 29 7b 0a 20 20 20 20 20  st_mode ){.     
3960: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
3970: 54 45 5f 49 4f 45 52 52 3b 0a 20 20 20 20 20 20  TE_IOERR;.      
3980: 20 20 7d 0a 20 20 20 20 20 20 20 20 73 71 6c 69    }.        sqli
3990: 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28  te3_result_blob(
39a0: 63 74 78 2c 20 61 42 75 66 2c 20 6e 52 65 61 64  ctx, aBuf, nRead
39b0: 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45  , SQLITE_TRANSIE
39c0: 4e 54 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  NT);.        sql
39d0: 69 74 65 33 5f 66 72 65 65 28 61 42 75 66 29 3b  ite3_free(aBuf);
39e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
39f0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
3a00: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
3a10: 20 78 52 6f 77 69 64 20 6d 65 74 68 6f 64 20 69   xRowid method i
3a20: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
3a30: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 74  /.static int fst
3a40: 72 65 65 52 6f 77 69 64 28 73 71 6c 69 74 65 33  reeRowid(sqlite3
3a50: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
3a60: 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  r, sqlite_int64 
3a70: 2a 70 52 6f 77 69 64 29 7b 0a 20 20 2a 70 52 6f  *pRowid){.  *pRo
3a80: 77 69 64 20 3d 20 30 3b 0a 20 20 72 65 74 75 72  wid = 0;.  retur
3a90: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 2f  n SQLITE_OK;.}./
3aa0: 2a 0a 2a 2a 20 45 6e 64 20 6f 66 20 66 73 74 72  *.** End of fstr
3ab0: 65 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ee implementatio
3ac0: 6e 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  n..*************
3ad0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 2f 0a 0a 0a  ************/...
3b10: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
3b20: 63 74 69 6f 6e 20 69 73 20 74 68 65 20 69 6d 70  ction is the imp
3b30: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 62  lementation of b
3b40: 6f 74 68 20 74 68 65 20 78 43 6f 6e 6e 65 63 74  oth the xConnect
3b50: 20 61 6e 64 20 78 43 72 65 61 74 65 0a 2a 2a 20   and xCreate.** 
3b60: 6d 65 74 68 6f 64 73 20 6f 66 20 74 68 65 20 66  methods of the f
3b70: 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  s virtual table.
3b80: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 72 67 76 5b  .**.** The argv[
3b90: 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73  ] array contains
3ba0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a   the following:.
3bb0: 2a 2a 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d 20  **.**   argv[0] 
3bc0: 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d 65    -> module name
3bd0: 20 20 28 22 66 73 22 29 0a 2a 2a 20 20 20 61 72    ("fs").**   ar
3be0: 67 76 5b 31 5d 20 20 20 2d 3e 20 64 61 74 61 62  gv[1]   -> datab
3bf0: 61 73 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72  ase name.**   ar
3c00: 67 76 5b 32 5d 20 20 20 2d 3e 20 74 61 62 6c 65  gv[2]   -> table
3c10: 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76 5b   name.**   argv[
3c20: 2e 2e 2e 5d 20 2d 3e 20 6f 74 68 65 72 20 6d 6f  ...] -> other mo
3c30: 64 75 6c 65 20 61 72 67 75 6d 65 6e 74 20 66 69  dule argument fi
3c40: 65 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  elds..*/.static 
3c50: 69 6e 74 20 66 73 43 6f 6e 6e 65 63 74 28 0a 20  int fsConnect(. 
3c60: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
3c70: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
3c80: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
3c90: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
3ca0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
3cb0: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
3cc0: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 66 73 5f  **pzErr.){.  fs_
3cd0: 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 20 20 69  vtab *pVtab;.  i
3ce0: 6e 74 20 6e 42 79 74 65 3b 0a 20 20 63 6f 6e 73  nt nByte;.  cons
3cf0: 74 20 63 68 61 72 20 2a 7a 54 62 6c 3b 0a 20 20  t char *zTbl;.  
3d00: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 20  const char *zDb 
3d10: 3d 20 61 72 67 76 5b 31 5d 3b 0a 0a 20 20 69 66  = argv[1];..  if
3d20: 28 20 61 72 67 63 21 3d 34 20 29 7b 0a 20 20 20  ( argc!=4 ){.   
3d30: 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65   *pzErr = sqlite
3d40: 33 5f 6d 70 72 69 6e 74 66 28 22 77 72 6f 6e 67  3_mprintf("wrong
3d50: 20 6e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d   number of argum
3d60: 65 6e 74 73 22 29 3b 0a 20 20 20 20 72 65 74 75  ents");.    retu
3d70: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
3d80: 0a 20 20 7d 0a 20 20 7a 54 62 6c 20 3d 20 61 72  .  }.  zTbl = ar
3d90: 67 76 5b 33 5d 3b 0a 0a 20 20 6e 42 79 74 65 20  gv[3];..  nByte 
3da0: 3d 20 73 69 7a 65 6f 66 28 66 73 5f 76 74 61 62  = sizeof(fs_vtab
3db0: 29 20 2b 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  ) + (int)strlen(
3dc0: 7a 54 62 6c 29 20 2b 20 31 20 2b 20 28 69 6e 74  zTbl) + 1 + (int
3dd0: 29 73 74 72 6c 65 6e 28 7a 44 62 29 20 2b 20 31  )strlen(zDb) + 1
3de0: 3b 0a 20 20 70 56 74 61 62 20 3d 20 28 66 73 5f  ;.  pVtab = (fs_
3df0: 76 74 61 62 20 2a 29 73 71 6c 69 74 65 33 4d 61  vtab *)sqlite3Ma
3e00: 6c 6c 6f 63 5a 65 72 6f 28 20 6e 42 79 74 65 20  llocZero( nByte 
3e10: 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61 62 20  );.  if( !pVtab 
3e20: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
3e30: 4e 4f 4d 45 4d 3b 0a 0a 20 20 70 56 74 61 62 2d  NOMEM;..  pVtab-
3e40: 3e 7a 54 62 6c 20 3d 20 28 63 68 61 72 20 2a 29  >zTbl = (char *)
3e50: 26 70 56 74 61 62 5b 31 5d 3b 0a 20 20 70 56 74  &pVtab[1];.  pVt
3e60: 61 62 2d 3e 7a 44 62 20 3d 20 26 70 56 74 61 62  ab->zDb = &pVtab
3e70: 2d 3e 7a 54 62 6c 5b 73 74 72 6c 65 6e 28 7a 54  ->zTbl[strlen(zT
3e80: 62 6c 29 2b 31 5d 3b 0a 20 20 70 56 74 61 62 2d  bl)+1];.  pVtab-
3e90: 3e 64 62 20 3d 20 64 62 3b 0a 20 20 6d 65 6d 63  >db = db;.  memc
3ea0: 70 79 28 70 56 74 61 62 2d 3e 7a 54 62 6c 2c 20  py(pVtab->zTbl, 
3eb0: 7a 54 62 6c 2c 20 73 74 72 6c 65 6e 28 7a 54 62  zTbl, strlen(zTb
3ec0: 6c 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 56  l));.  memcpy(pV
3ed0: 74 61 62 2d 3e 7a 44 62 2c 20 7a 44 62 2c 20 73  tab->zDb, zDb, s
3ee0: 74 72 6c 65 6e 28 7a 44 62 29 29 3b 0a 20 20 2a  trlen(zDb));.  *
3ef0: 70 70 56 74 61 62 20 3d 20 26 70 56 74 61 62 2d  ppVtab = &pVtab-
3f00: 3e 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33  >base;.  sqlite3
3f10: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62  _declare_vtab(db
3f20: 2c 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20  , "CREATE TABLE 
3f30: 78 28 70 61 74 68 20 54 45 58 54 2c 20 64 61 74  x(path TEXT, dat
3f40: 61 20 54 45 58 54 29 22 29 3b 0a 0a 20 20 72 65  a TEXT)");..  re
3f50: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
3f60: 7d 0a 2f 2a 20 4e 6f 74 65 20 74 68 61 74 20 66  }./* Note that f
3f70: 6f 72 20 74 68 69 73 20 76 69 72 74 75 61 6c 20  or this virtual 
3f80: 74 61 62 6c 65 2c 20 74 68 65 20 78 43 72 65 61  table, the xCrea
3f90: 74 65 20 61 6e 64 20 78 43 6f 6e 6e 65 63 74 0a  te and xConnect.
3fa0: 2a 2a 20 6d 65 74 68 6f 64 73 20 61 72 65 20 69  ** methods are i
3fb0: 64 65 6e 74 69 63 61 6c 2e 20 2a 2f 0a 0a 73 74  dentical. */..st
3fc0: 61 74 69 63 20 69 6e 74 20 66 73 44 69 73 63 6f  atic int fsDisco
3fd0: 6e 6e 65 63 74 28 73 71 6c 69 74 65 33 5f 76 74  nnect(sqlite3_vt
3fe0: 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 73 71  ab *pVtab){.  sq
3ff0: 6c 69 74 65 33 5f 66 72 65 65 28 70 56 74 61 62  lite3_free(pVtab
4000: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
4010: 54 45 5f 4f 4b 3b 0a 7d 0a 2f 2a 20 54 68 65 20  TE_OK;.}./* The 
4020: 78 44 69 73 63 6f 6e 6e 65 63 74 20 61 6e 64 20  xDisconnect and 
4030: 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 73  xDestroy methods
4040: 20 61 72 65 20 61 6c 73 6f 20 74 68 65 20 73 61   are also the sa
4050: 6d 65 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65  me */../*.** Ope
4060: 6e 20 61 20 6e 65 77 20 66 73 20 63 75 72 73 6f  n a new fs curso
4070: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
4080: 20 66 73 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f   fsOpen(sqlite3_
4090: 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c  vtab *pVTab, sql
40a0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
40b0: 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20   **ppCursor){.  
40c0: 66 73 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b  fs_cursor *pCur;
40d0: 0a 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65  .  pCur = sqlite
40e0: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
40f0: 6f 66 28 66 73 5f 63 75 72 73 6f 72 29 29 3b 0a  of(fs_cursor));.
4100: 20 20 2a 70 70 43 75 72 73 6f 72 20 3d 20 26 70    *ppCursor = &p
4110: 43 75 72 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74  Cur->base;.  ret
4120: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4130: 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20  ../*.** Close a 
4140: 66 73 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74  fs cursor..*/.st
4150: 61 74 69 63 20 69 6e 74 20 66 73 43 6c 6f 73 65  atic int fsClose
4160: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
4170: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66 73  rsor *cur){.  fs
4180: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  _cursor *pCur = 
4190: 28 66 73 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  (fs_cursor *)cur
41a0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  ;.  sqlite3_fina
41b0: 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74  lize(pCur->pStmt
41c0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
41d0: 65 28 70 43 75 72 2d 3e 7a 42 75 66 29 3b 0a 20  e(pCur->zBuf);. 
41e0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
41f0: 75 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  ur);.  return SQ
4200: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74  LITE_OK;.}..stat
4210: 69 63 20 69 6e 74 20 66 73 4e 65 78 74 28 73 71  ic int fsNext(sq
4220: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4230: 72 20 2a 63 75 72 29 7b 0a 20 20 66 73 5f 63 75  r *cur){.  fs_cu
4240: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73  rsor *pCur = (fs
4250: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20  _cursor *)cur;. 
4260: 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d   int rc;..  rc =
4270: 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 43   sqlite3_step(pC
4280: 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 69 66  ur->pStmt);.  if
4290: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc==SQLITE_ROW
42a0: 20 7c 7c 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44   || rc==SQLITE_D
42b0: 4f 4e 45 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ONE ) rc = SQLIT
42c0: 45 5f 4f 4b 3b 0a 0a 20 20 72 65 74 75 72 6e 20  E_OK;..  return 
42d0: 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
42e0: 74 20 66 73 46 69 6c 74 65 72 28 0a 20 20 73 71  t fsFilter(.  sq
42f0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4300: 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20  r *pVtabCursor, 
4310: 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63  .  int idxNum, c
4320: 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74  onst char *idxSt
4330: 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73  r,.  int argc, s
4340: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
4350: 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b  rgv.){.  int rc;
4360: 0a 20 20 66 73 5f 63 75 72 73 6f 72 20 2a 70 43  .  fs_cursor *pC
4370: 75 72 20 3d 20 28 66 73 5f 63 75 72 73 6f 72 20  ur = (fs_cursor 
4380: 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20  *)pVtabCursor;. 
4390: 20 66 73 5f 76 74 61 62 20 2a 70 20 3d 20 28 66   fs_vtab *p = (f
43a0: 73 5f 76 74 61 62 20 2a 29 28 70 56 74 61 62 43  s_vtab *)(pVtabC
43b0: 75 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b 0a 0a  ursor->pVtab);..
43c0: 20 20 61 73 73 65 72 74 28 20 28 69 64 78 4e 75    assert( (idxNu
43d0: 6d 3d 3d 30 20 26 26 20 61 72 67 63 3d 3d 30 29  m==0 && argc==0)
43e0: 20 7c 7c 20 28 69 64 78 4e 75 6d 3d 3d 31 20 26   || (idxNum==1 &
43f0: 26 20 61 72 67 63 3d 3d 31 29 20 29 3b 0a 20 20  & argc==1) );.  
4400: 69 66 28 20 69 64 78 4e 75 6d 3d 3d 31 20 29 7b  if( idxNum==1 ){
4410: 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 74 6d 74  .    char *zStmt
4420: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
4430: 74 66 28 0a 20 20 20 20 20 20 20 20 22 53 45 4c  tf(.        "SEL
4440: 45 43 54 20 2a 20 46 52 4f 4d 20 25 51 2e 25 51  ECT * FROM %Q.%Q
4450: 20 57 48 45 52 45 20 72 6f 77 69 64 3d 3f 22 2c   WHERE rowid=?",
4460: 20 70 2d 3e 7a 44 62 2c 20 70 2d 3e 7a 54 62 6c   p->zDb, p->zTbl
4470: 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 53 74 6d  );.    if( !zStm
4480: 74 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  t ) return SQLIT
4490: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 63 20  E_NOMEM;.    rc 
44a0: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
44b0: 65 5f 76 32 28 70 2d 3e 64 62 2c 20 7a 53 74 6d  e_v2(p->db, zStm
44c0: 74 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e 70 53  t, -1, &pCur->pS
44d0: 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c  tmt, 0);.    sql
44e0: 69 74 65 33 5f 66 72 65 65 28 7a 53 74 6d 74 29  ite3_free(zStmt)
44f0: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
4500: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
4510: 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61   sqlite3_bind_va
4520: 6c 75 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c  lue(pCur->pStmt,
4530: 20 31 2c 20 61 72 67 76 5b 30 5d 29 3b 0a 20 20   1, argv[0]);.  
4540: 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20    }.  }else{.   
4550: 20 63 68 61 72 20 2a 7a 53 74 6d 74 20 3d 20 73   char *zStmt = s
4560: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
4570: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 25 51  SELECT * FROM %Q
4580: 2e 25 51 22 2c 20 70 2d 3e 7a 44 62 2c 20 70 2d  .%Q", p->zDb, p-
4590: 3e 7a 54 62 6c 29 3b 0a 20 20 20 20 69 66 28 20  >zTbl);.    if( 
45a0: 21 7a 53 74 6d 74 20 29 20 72 65 74 75 72 6e 20  !zStmt ) return 
45b0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
45c0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
45d0: 72 65 70 61 72 65 5f 76 32 28 70 2d 3e 64 62 2c  repare_v2(p->db,
45e0: 20 7a 53 74 6d 74 2c 20 2d 31 2c 20 26 70 43 75   zStmt, -1, &pCu
45f0: 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  r->pStmt, 0);.  
4600: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
4610: 53 74 6d 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  Stmt);.  }..  if
4620: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4630: 29 7b 0a 20 20 20 20 72 63 20 3d 20 66 73 4e 65  ){.    rc = fsNe
4640: 78 74 28 70 56 74 61 62 43 75 72 73 6f 72 29 3b  xt(pVtabCursor);
4650: 20 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72   .  }.  return r
4660: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
4670: 20 66 73 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65   fsColumn(sqlite
4680: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
4690: 75 72 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  ur, sqlite3_cont
46a0: 65 78 74 20 2a 63 74 78 2c 20 69 6e 74 20 69 29  ext *ctx, int i)
46b0: 7b 0a 20 20 66 73 5f 63 75 72 73 6f 72 20 2a 70  {.  fs_cursor *p
46c0: 43 75 72 20 3d 20 28 66 73 5f 63 75 72 73 6f 72  Cur = (fs_cursor
46d0: 2a 29 63 75 72 3b 0a 0a 20 20 61 73 73 65 72 74  *)cur;..  assert
46e0: 28 20 69 3d 3d 30 20 7c 7c 20 69 3d 3d 31 20 7c  ( i==0 || i==1 |
46f0: 7c 20 69 3d 3d 32 20 29 3b 0a 20 20 69 66 28 20  | i==2 );.  if( 
4700: 69 3d 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69  i==0 ){.    sqli
4710: 74 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65  te3_result_value
4720: 28 63 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f  (ctx, sqlite3_co
4730: 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 43 75 72 2d  lumn_value(pCur-
4740: 3e 70 53 74 6d 74 2c 20 30 29 29 3b 0a 20 20 7d  >pStmt, 0));.  }
4750: 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e 73 74 20  else{.    const 
4760: 63 68 61 72 20 2a 7a 46 69 6c 65 20 3d 20 28 63  char *zFile = (c
4770: 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69  onst char *)sqli
4780: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
4790: 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 31 29 3b  pCur->pStmt, 1);
47a0: 0a 20 20 20 20 73 74 72 75 63 74 20 73 74 61 74  .    struct stat
47b0: 20 73 62 75 66 3b 0a 20 20 20 20 69 6e 74 20 66   sbuf;.    int f
47c0: 64 3b 0a 0a 20 20 20 20 69 6e 74 20 6e 3b 0a 20  d;..    int n;. 
47d0: 20 20 20 66 64 20 3d 20 6f 70 65 6e 28 7a 46 69     fd = open(zFi
47e0: 6c 65 2c 20 4f 5f 52 44 4f 4e 4c 59 29 3b 0a 20  le, O_RDONLY);. 
47f0: 20 20 20 69 66 28 20 66 64 3c 30 20 29 20 72 65     if( fd<0 ) re
4800: 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52  turn SQLITE_IOER
4810: 52 3b 0a 20 20 20 20 66 73 74 61 74 28 66 64 2c  R;.    fstat(fd,
4820: 20 26 73 62 75 66 29 3b 0a 0a 20 20 20 20 69 66   &sbuf);..    if
4830: 28 20 73 62 75 66 2e 73 74 5f 73 69 7a 65 3e 3d  ( sbuf.st_size>=
4840: 70 43 75 72 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a  pCur->nAlloc ){.
4850: 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d        int nNew =
4860: 20 73 62 75 66 2e 73 74 5f 73 69 7a 65 2a 32 3b   sbuf.st_size*2;
4870: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 65  .      char *zNe
4880: 77 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65  w;.      if( nNe
4890: 77 3c 31 30 32 34 20 29 20 6e 4e 65 77 20 3d 20  w<1024 ) nNew = 
48a0: 31 30 32 34 3b 0a 0a 20 20 20 20 20 20 7a 4e 65  1024;..      zNe
48b0: 77 20 3d 20 73 71 6c 69 74 65 33 52 65 61 6c 6c  w = sqlite3Reall
48c0: 6f 63 28 70 43 75 72 2d 3e 7a 42 75 66 2c 20 6e  oc(pCur->zBuf, n
48d0: 4e 65 77 29 3b 0a 20 20 20 20 20 20 69 66 28 20  New);.      if( 
48e0: 7a 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20  zNew==0 ){.     
48f0: 20 20 20 63 6c 6f 73 65 28 66 64 29 3b 0a 20 20     close(fd);.  
4900: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
4910: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
4920: 20 7d 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 7a   }.      pCur->z
4930: 42 75 66 20 3d 20 7a 4e 65 77 3b 0a 20 20 20 20  Buf = zNew;.    
4940: 20 20 70 43 75 72 2d 3e 6e 41 6c 6c 6f 63 20 3d    pCur->nAlloc =
4950: 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20   nNew;.    }..  
4960: 20 20 6e 20 3d 20 28 69 6e 74 29 72 65 61 64 28    n = (int)read(
4970: 66 64 2c 20 70 43 75 72 2d 3e 7a 42 75 66 2c 20  fd, pCur->zBuf, 
4980: 73 62 75 66 2e 73 74 5f 73 69 7a 65 29 3b 0a 20  sbuf.st_size);. 
4990: 20 20 20 63 6c 6f 73 65 28 66 64 29 3b 0a 20 20     close(fd);.  
49a0: 20 20 69 66 28 20 6e 21 3d 73 62 75 66 2e 73 74    if( n!=sbuf.st
49b0: 5f 73 69 7a 65 20 29 20 72 65 74 75 72 6e 20 53  _size ) return S
49c0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
49d0: 20 70 43 75 72 2d 3e 6e 42 75 66 20 3d 20 73 62   pCur->nBuf = sb
49e0: 75 66 2e 73 74 5f 73 69 7a 65 3b 0a 20 20 20 20  uf.st_size;.    
49f0: 70 43 75 72 2d 3e 7a 42 75 66 5b 70 43 75 72 2d  pCur->zBuf[pCur-
4a00: 3e 6e 42 75 66 5d 20 3d 20 27 5c 30 27 3b 0a 0a  >nBuf] = '\0';..
4a10: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
4a20: 6c 74 5f 74 65 78 74 28 63 74 78 2c 20 70 43 75  lt_text(ctx, pCu
4a30: 72 2d 3e 7a 42 75 66 2c 20 2d 31 2c 20 53 51 4c  r->zBuf, -1, SQL
4a40: 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a  ITE_TRANSIENT);.
4a50: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
4a60: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69  ITE_OK;.}..stati
4a70: 63 20 69 6e 74 20 66 73 52 6f 77 69 64 28 73 71  c int fsRowid(sq
4a80: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4a90: 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 5f 69  r *cur, sqlite_i
4aa0: 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20  nt64 *pRowid){. 
4ab0: 20 66 73 5f 63 75 72 73 6f 72 20 2a 70 43 75 72   fs_cursor *pCur
4ac0: 20 3d 20 28 66 73 5f 63 75 72 73 6f 72 2a 29 63   = (fs_cursor*)c
4ad0: 75 72 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20  ur;.  *pRowid = 
4ae0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69  sqlite3_column_i
4af0: 6e 74 36 34 28 70 43 75 72 2d 3e 70 53 74 6d 74  nt64(pCur->pStmt
4b00: 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  , 0);.  return S
4b10: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  QLITE_OK;.}..sta
4b20: 74 69 63 20 69 6e 74 20 66 73 45 6f 66 28 73 71  tic int fsEof(sq
4b30: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4b40: 72 20 2a 63 75 72 29 7b 0a 20 20 66 73 5f 63 75  r *cur){.  fs_cu
4b50: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73  rsor *pCur = (fs
4b60: 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20  _cursor*)cur;.  
4b70: 72 65 74 75 72 6e 20 28 73 71 6c 69 74 65 33 5f  return (sqlite3_
4b80: 64 61 74 61 5f 63 6f 75 6e 74 28 70 43 75 72 2d  data_count(pCur-
4b90: 3e 70 53 74 6d 74 29 3d 3d 30 29 3b 0a 7d 0a 0a  >pStmt)==0);.}..
4ba0: 73 74 61 74 69 63 20 69 6e 74 20 66 73 42 65 73  static int fsBes
4bb0: 74 49 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76  tIndex(sqlite3_v
4bc0: 74 61 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65  tab *tab, sqlite
4bd0: 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49  3_index_info *pI
4be0: 64 78 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69  dxInfo){.  int i
4bf0: 69 3b 0a 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20  i;..  for(ii=0; 
4c00: 69 69 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f  ii<pIdxInfo->nCo
4c10: 6e 73 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b  nstraint; ii++){
4c20: 0a 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69  .    struct sqli
4c30: 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72  te3_index_constr
4c40: 61 69 6e 74 20 63 6f 6e 73 74 20 2a 70 43 6f 6e  aint const *pCon
4c50: 73 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61  s = &pIdxInfo->a
4c60: 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d 3b 0a  Constraint[ii];.
4c70: 20 20 20 20 69 66 28 20 70 43 6f 6e 73 2d 3e 69      if( pCons->i
4c80: 43 6f 6c 75 6d 6e 3c 30 20 26 26 20 70 43 6f 6e  Column<0 && pCon
4c90: 73 2d 3e 75 73 61 62 6c 65 0a 20 20 20 20 20 20  s->usable.      
4ca0: 20 20 20 20 20 26 26 20 70 43 6f 6e 73 2d 3e 6f       && pCons->o
4cb0: 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  p==SQLITE_INDEX_
4cc0: 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51 20 29 7b  CONSTRAINT_EQ ){
4cd0: 0a 20 20 20 20 20 20 73 74 72 75 63 74 20 73 71  .      struct sq
4ce0: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73  lite3_index_cons
4cf0: 74 72 61 69 6e 74 5f 75 73 61 67 65 20 2a 70 55  traint_usage *pU
4d00: 73 61 67 65 3b 0a 20 20 20 20 20 20 70 55 73 61  sage;.      pUsa
4d10: 67 65 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e  ge = &pIdxInfo->
4d20: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
4d30: 5b 69 69 5d 3b 0a 20 20 20 20 20 20 70 55 73 61  [ii];.      pUsa
4d40: 67 65 2d 3e 6f 6d 69 74 20 3d 20 30 3b 0a 20 20  ge->omit = 0;.  
4d50: 20 20 20 20 70 55 73 61 67 65 2d 3e 61 72 67 76      pUsage->argv
4d60: 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 20  Index = 1;.     
4d70: 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75   pIdxInfo->idxNu
4d80: 6d 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49 64  m = 1;.      pId
4d90: 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  xInfo->estimated
4da0: 43 6f 73 74 20 3d 20 31 2e 30 3b 0a 20 20 20 20  Cost = 1.0;.    
4db0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
4dc0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
4dd0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
4de0: 20 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65   A virtual table
4df0: 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 70 72 6f   module that pro
4e00: 76 69 64 65 73 20 72 65 61 64 2d 6f 6e 6c 79 20  vides read-only 
4e10: 61 63 63 65 73 73 20 74 6f 20 61 0a 2a 2a 20 54  access to a.** T
4e20: 63 6c 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  cl global variab
4e30: 6c 65 20 6e 61 6d 65 73 70 61 63 65 2e 0a 2a 2f  le namespace..*/
4e40: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
4e50: 6d 6f 64 75 6c 65 20 66 73 4d 6f 64 75 6c 65 20  module fsModule 
4e60: 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20 20 20  = {.  0,        
4e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e80: 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a   /* iVersion */.
4e90: 20 20 66 73 43 6f 6e 6e 65 63 74 2c 0a 20 20 66    fsConnect,.  f
4ea0: 73 43 6f 6e 6e 65 63 74 2c 0a 20 20 66 73 42 65  sConnect,.  fsBe
4eb0: 73 74 49 6e 64 65 78 2c 0a 20 20 66 73 44 69 73  stIndex,.  fsDis
4ec0: 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 66 73 44 69  connect, .  fsDi
4ed0: 73 63 6f 6e 6e 65 63 74 2c 0a 20 20 66 73 4f 70  sconnect,.  fsOp
4ee0: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
4ef0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65           /* xOpe
4f00: 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f  n - open a curso
4f10: 72 20 2a 2f 0a 20 20 66 73 43 6c 6f 73 65 2c 20  r */.  fsClose, 
4f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4f30: 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20      /* xClose - 
4f40: 63 6c 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a  close a cursor *
4f50: 2f 0a 20 20 66 73 46 69 6c 74 65 72 2c 20 20 20  /.  fsFilter,   
4f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4f70: 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f   /* xFilter - co
4f80: 6e 66 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e  nfigure scan con
4f90: 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 66 73  straints */.  fs
4fa0: 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20  Next,           
4fb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e             /* xN
4fc0: 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20  ext - advance a 
4fd0: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66 73 45 6f  cursor */.  fsEo
4fe0: 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f,              
4ff0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66           /* xEof
5000: 20 2d 20 63 68 65 63 6b 20 66 6f 72 20 65 6e 64   - check for end
5010: 20 6f 66 20 73 63 61 6e 20 2a 2f 0a 20 20 66 73   of scan */.  fs
5020: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
5030: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
5040: 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74  olumn - read dat
5050: 61 20 2a 2f 0a 20 20 66 73 52 6f 77 69 64 2c 20  a */.  fsRowid, 
5060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5070: 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20      /* xRowid - 
5080: 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 30  read data */.  0
5090: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
50a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
50b0: 55 70 64 61 74 65 20 2a 2f 0a 20 20 30 2c 20 20  Update */.  0,  
50c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
50e0: 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  in */.  0,      
50f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5100: 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f       /* xSync */
5110: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
5120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5130: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20  /* xCommit */.  
5140: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
5150: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5160: 78 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 30  xRollback */.  0
5170: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5180: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5190: 46 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a 20 20  FindMethod */.  
51a0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
51b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
51c0: 78 52 65 6e 61 6d 65 20 2a 2f 0a 7d 3b 0a 0a 73  xRename */.};..s
51d0: 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 6d 6f  tatic sqlite3_mo
51e0: 64 75 6c 65 20 66 73 64 69 72 4d 6f 64 75 6c 65  dule fsdirModule
51f0: 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20 20   = {.  0,       
5200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5210: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
5220: 6f 6e 20 2a 2f 0a 20 20 66 73 64 69 72 43 6f 6e  on */.  fsdirCon
5230: 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20  nect,           
5240: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61          /* xCrea
5250: 74 65 20 2a 2f 0a 20 20 66 73 64 69 72 43 6f 6e  te */.  fsdirCon
5260: 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20  nect,           
5270: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e          /* xConn
5280: 65 63 74 20 2a 2f 0a 20 20 66 73 64 69 72 42 65  ect */.  fsdirBe
5290: 73 74 49 6e 64 65 78 2c 20 20 20 20 20 20 20 20  stIndex,        
52a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 73           /* xBes
52b0: 74 49 6e 64 65 78 20 2a 2f 0a 20 20 66 73 64 69  tIndex */.  fsdi
52c0: 72 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20  rDisconnect,    
52d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
52e0: 44 69 73 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20  Disconnect */.  
52f0: 66 73 64 69 72 44 69 73 63 6f 6e 6e 65 63 74 2c  fsdirDisconnect,
5300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5310: 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20  /* xDestroy */. 
5320: 20 66 73 64 69 72 4f 70 65 6e 2c 20 20 20 20 20   fsdirOpen,     
5330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5340: 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e   /* xOpen - open
5350: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66   a cursor */.  f
5360: 73 64 69 72 43 6c 6f 73 65 2c 20 20 20 20 20 20  sdirClose,      
5370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5380: 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65  * xClose - close
5390: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66   a cursor */.  f
53a0: 73 64 69 72 46 69 6c 74 65 72 2c 20 20 20 20 20  sdirFilter,     
53b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
53c0: 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66  * xFilter - conf
53d0: 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74  igure scan const
53e0: 72 61 69 6e 74 73 20 2a 2f 0a 20 20 66 73 64 69  raints */.  fsdi
53f0: 72 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20 20  rNext,          
5400: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5410: 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61  Next - advance a
5420: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66 73 64   cursor */.  fsd
5430: 69 72 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20  irEof,          
5440: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5450: 78 45 6f 66 20 2d 20 63 68 65 63 6b 20 66 6f 72  xEof - check for
5460: 20 65 6e 64 20 6f 66 20 73 63 61 6e 20 2a 2f 0a   end of scan */.
5470: 20 20 66 73 64 69 72 43 6f 6c 75 6d 6e 2c 20 20    fsdirColumn,  
5480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5490: 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72    /* xColumn - r
54a0: 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 66 73  ead data */.  fs
54b0: 64 69 72 52 6f 77 69 64 2c 20 20 20 20 20 20 20  dirRowid,       
54c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
54d0: 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64   xRowid - read d
54e0: 61 74 61 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ata */.  0,     
54f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5500: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64           /* xUpd
5510: 61 74 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ate */.  0,     
5520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5530: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
5540: 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  in */.  0,      
5550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5560: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63          /* xSync
5570: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
5580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5590: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74        /* xCommit
55a0: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
55b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55c0: 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61        /* xRollba
55d0: 63 6b 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  ck */.  0,      
55e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55f0: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64          /* xFind
5600: 4d 65 74 68 6f 64 20 2a 2f 0a 20 20 30 2c 20 20  Method */.  0,  
5610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5620: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5630: 52 65 6e 61 6d 65 20 2a 2f 0a 7d 3b 0a 0a 73 74  Rename */.};..st
5640: 61 74 69 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64  atic sqlite3_mod
5650: 75 6c 65 20 66 73 74 72 65 65 4d 6f 64 75 6c 65  ule fstreeModule
5660: 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20 20   = {.  0,       
5670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5680: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
5690: 6f 6e 20 2a 2f 0a 20 20 66 73 74 72 65 65 43 6f  on */.  fstreeCo
56a0: 6e 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20  nnect,          
56b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61          /* xCrea
56c0: 74 65 20 2a 2f 0a 20 20 66 73 74 72 65 65 43 6f  te */.  fstreeCo
56d0: 6e 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20  nnect,          
56e0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e          /* xConn
56f0: 65 63 74 20 2a 2f 0a 20 20 66 73 74 72 65 65 42  ect */.  fstreeB
5700: 65 73 74 49 6e 64 65 78 2c 20 20 20 20 20 20 20  estIndex,       
5710: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 73           /* xBes
5720: 74 49 6e 64 65 78 20 2a 2f 0a 20 20 66 73 74 72  tIndex */.  fstr
5730: 65 65 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20  eeDisconnect,   
5740: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5750: 44 69 73 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20  Disconnect */.  
5760: 66 73 74 72 65 65 44 69 73 63 6f 6e 6e 65 63 74  fstreeDisconnect
5770: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5780: 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20  /* xDestroy */. 
5790: 20 66 73 74 72 65 65 4f 70 65 6e 2c 20 20 20 20   fstreeOpen,    
57a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57b0: 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e   /* xOpen - open
57c0: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66   a cursor */.  f
57d0: 73 74 72 65 65 43 6c 6f 73 65 2c 20 20 20 20 20  streeClose,     
57e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
57f0: 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65  * xClose - close
5800: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66   a cursor */.  f
5810: 73 74 72 65 65 46 69 6c 74 65 72 2c 20 20 20 20  streeFilter,    
5820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5830: 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66  * xFilter - conf
5840: 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74  igure scan const
5850: 72 61 69 6e 74 73 20 2a 2f 0a 20 20 66 73 74 72  raints */.  fstr
5860: 65 65 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20  eeNext,         
5870: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5880: 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61  Next - advance a
5890: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66 73 74   cursor */.  fst
58a0: 72 65 65 45 6f 66 2c 20 20 20 20 20 20 20 20 20  reeEof,         
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
58c0: 78 45 6f 66 20 2d 20 63 68 65 63 6b 20 66 6f 72  xEof - check for
58d0: 20 65 6e 64 20 6f 66 20 73 63 61 6e 20 2a 2f 0a   end of scan */.
58e0: 20 20 66 73 74 72 65 65 43 6f 6c 75 6d 6e 2c 20    fstreeColumn, 
58f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5900: 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72    /* xColumn - r
5910: 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 66 73  ead data */.  fs
5920: 74 72 65 65 52 6f 77 69 64 2c 20 20 20 20 20 20  treeRowid,      
5930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5940: 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64   xRowid - read d
5950: 61 74 61 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ata */.  0,     
5960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5970: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64           /* xUpd
5980: 61 74 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ate */.  0,     
5990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
59b0: 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  in */.  0,      
59c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59d0: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63          /* xSync
59e0: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
59f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a00: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74        /* xCommit
5a10: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
5a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a30: 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61        /* xRollba
5a40: 63 6b 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  ck */.  0,      
5a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a60: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64          /* xFind
5a70: 4d 65 74 68 6f 64 20 2a 2f 0a 20 20 30 2c 20 20  Method */.  0,  
5a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5aa0: 52 65 6e 61 6d 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  Rename */.};../*
5ab0: 0a 2a 2a 20 44 65 63 6f 64 65 20 61 20 70 6f 69  .** Decode a poi
5ac0: 6e 74 65 72 20 74 6f 20 61 6e 20 73 71 6c 69 74  nter to an sqlit
5ad0: 65 33 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 65 78  e3 object..*/.ex
5ae0: 74 65 72 6e 20 69 6e 74 20 67 65 74 44 62 50 6f  tern int getDbPo
5af0: 69 6e 74 65 72 28 54 63 6c 5f 49 6e 74 65 72 70  inter(Tcl_Interp
5b00: 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20   *interp, const 
5b10: 63 68 61 72 20 2a 7a 41 2c 20 73 71 6c 69 74 65  char *zA, sqlite
5b20: 33 20 2a 2a 70 70 44 62 29 3b 0a 0a 2f 2a 0a 2a  3 **ppDb);../*.*
5b30: 2a 20 52 65 67 69 73 74 65 72 20 74 68 65 20 65  * Register the e
5b40: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
5b50: 65 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61  e module..*/.sta
5b60: 74 69 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54  tic int SQLITE_T
5b70: 43 4c 41 50 49 20 72 65 67 69 73 74 65 72 5f 66  CLAPI register_f
5b80: 73 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65  s_module(.  Clie
5b90: 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74  ntData clientDat
5ba0: 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f  a, /* Pointer to
5bb0: 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f   sqlite3_enable_
5bc0: 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  XXX function */.
5bd0: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
5be0: 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20  terp,    /* The 
5bf0: 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20  TCL interpreter 
5c00: 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69  that invoked thi
5c10: 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69  s command */.  i
5c20: 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20  nt objc,        
5c30: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
5c40: 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  of arguments */.
5c50: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
5c60: 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d   objv[]  /* Comm
5c70: 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  and arguments */
5c80: 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  .){.  sqlite3 *d
5c90: 62 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32  b;.  if( objc!=2
5ca0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e   ){.    Tcl_Wron
5cb0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
5cc0: 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 22 29 3b   1, objv, "DB");
5cd0: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
5ce0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28  ERROR;.  }.  if(
5cf0: 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69 6e   getDbPointer(in
5d00: 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72  terp, Tcl_GetStr
5d10: 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 64  ing(objv[1]), &d
5d20: 62 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  b) ) return TCL_
5d30: 45 52 52 4f 52 3b 0a 23 69 66 6e 64 65 66 20 53  ERROR;.#ifndef S
5d40: 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55  QLITE_OMIT_VIRTU
5d50: 41 4c 54 41 42 4c 45 0a 20 20 73 71 6c 69 74 65  ALTABLE.  sqlite
5d60: 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28  3_create_module(
5d70: 64 62 2c 20 22 66 73 22 2c 20 26 66 73 4d 6f 64  db, "fs", &fsMod
5d80: 75 6c 65 2c 20 28 76 6f 69 64 20 2a 29 69 6e 74  ule, (void *)int
5d90: 65 72 70 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  erp);.  sqlite3_
5da0: 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62  create_module(db
5db0: 2c 20 22 66 73 64 69 72 22 2c 20 26 66 73 64 69  , "fsdir", &fsdi
5dc0: 72 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a 20 20 73  rModule, 0);.  s
5dd0: 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f  qlite3_create_mo
5de0: 64 75 6c 65 28 64 62 2c 20 22 66 73 74 72 65 65  dule(db, "fstree
5df0: 22 2c 20 26 66 73 74 72 65 65 4d 6f 64 75 6c 65  ", &fstreeModule
5e00: 2c 20 30 29 3b 0a 23 65 6e 64 69 66 0a 20 20 72  , 0);.#endif.  r
5e10: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
5e20: 0a 23 65 6e 64 69 66 0a 0a 0a 2f 2a 0a 2a 2a 20  .#endif.../*.** 
5e30: 52 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64  Register command
5e40: 73 20 77 69 74 68 20 74 68 65 20 54 43 4c 20 69  s with the TCL i
5e50: 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69  nterpreter..*/.i
5e60: 6e 74 20 53 71 6c 69 74 65 74 65 73 74 66 73 5f  nt Sqlitetestfs_
5e70: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
5e80: 2a 69 6e 74 65 72 70 29 7b 0a 23 69 66 6e 64 65  *interp){.#ifnde
5e90: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49  f SQLITE_OMIT_VI
5ea0: 52 54 55 41 4c 54 41 42 4c 45 0a 20 20 73 74 61  RTUALTABLE.  sta
5eb0: 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20  tic struct {.   
5ec0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
5ed0: 20 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72      Tcl_ObjCmdPr
5ee0: 6f 63 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20  oc *xProc;.     
5ef0: 76 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61 74 61  void *clientData
5f00: 3b 0a 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20  ;.  } aObjCmd[] 
5f10: 3d 20 7b 0a 20 20 20 20 20 7b 20 22 72 65 67 69  = {.     { "regi
5f20: 73 74 65 72 5f 66 73 5f 6d 6f 64 75 6c 65 22 2c  ster_fs_module",
5f30: 20 20 20 72 65 67 69 73 74 65 72 5f 66 73 5f 6d     register_fs_m
5f40: 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a 20 20 7d 3b  odule, 0 },.  };
5f50: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28  .  int i;.  for(
5f60: 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 4f  i=0; i<sizeof(aO
5f70: 62 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 4f  bjCmd)/sizeof(aO
5f80: 62 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b  bjCmd[0]); i++){
5f90: 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  .    Tcl_CreateO
5fa0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
5fb0: 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61  , aObjCmd[i].zNa
5fc0: 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f 62  me, .        aOb
5fd0: 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 61  jCmd[i].xProc, a
5fe0: 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74  ObjCmd[i].client
5ff0: 44 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 23 65  Data, 0);.  }.#e
6000: 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20 54 43  ndif.  return TC
6010: 4c 5f 4f 4b 3b 0a 7d 0a                          L_OK;.}.