0000: 2f 2a 0a 2a 2a 20 32 30 31 34 2d 30 36 2d 31 33 /*.** 2014-06-13
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 urce code. In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67 lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20 al notice, here
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20 *.** May you
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 do good and not
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20 evil..** May
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65 you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20 hers..** May
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79 you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76 ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 ****.**.** This
0180: 53 51 4c 69 74 65 20 65 78 74 65 6e 73 69 6f 6e SQLite extension
0190: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 53 51 4c 20 implements SQL
01a0: 66 75 6e 63 74 69 6f 6e 73 20 72 65 61 64 66 69 functions readfi
01b0: 6c 65 28 29 20 61 6e 64 0a 2a 2a 20 77 72 69 74 le() and.** writ
01c0: 65 66 69 6c 65 28 29 2c 20 61 6e 64 20 65 70 6f efile(), and epo
01d0: 6e 79 6d 6f 75 73 20 76 69 72 74 75 61 6c 20 74 nymous virtual t
01e0: 79 70 65 20 22 66 73 64 69 72 22 2e 0a 2a 2a 0a ype "fsdir"..**.
01f0: 2a 2a 20 57 52 49 54 45 46 49 4c 45 28 46 49 4c ** WRITEFILE(FIL
0200: 45 2c 20 44 41 54 41 20 5b 2c 20 4d 4f 44 45 20 E, DATA [, MODE
0210: 5b 2c 20 4d 54 49 4d 45 5d 5d 29 3a 0a 2a 2a 0a [, MTIME]]):.**.
0220: 2a 2a 20 20 20 49 66 20 6e 65 69 74 68 65 72 20 ** If neither
0230: 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c 20 of the optional
0240: 61 72 67 75 6d 65 6e 74 73 20 69 73 20 70 72 65 arguments is pre
0250: 73 65 6e 74 2c 20 74 68 65 6e 20 74 68 69 73 20 sent, then this
0260: 55 44 46 0a 2a 2a 20 20 20 66 75 6e 63 74 69 6f UDF.** functio
0270: 6e 20 77 72 69 74 65 73 20 62 6c 6f 62 20 44 41 n writes blob DA
0280: 54 41 20 74 6f 20 66 69 6c 65 20 46 49 4c 45 2e TA to file FILE.
0290: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 If successful,
02a0: 74 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 20 20 the number.**
02b0: 6f 66 20 62 79 74 65 73 20 77 72 69 74 74 65 6e of bytes written
02c0: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66 is returned. If
02d0: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 an error occurs
02e0: 2c 20 4e 55 4c 4c 20 69 73 20 72 65 74 75 72 6e , NULL is return
02f0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 74 ed..**.** If t
0300: 68 65 20 66 69 72 73 74 20 6f 70 74 69 6f 6e 20 he first option
0310: 61 72 67 75 6d 65 6e 74 20 2d 20 4d 4f 44 45 20 argument - MODE
0320: 2d 20 69 73 20 70 72 65 73 65 6e 74 2c 20 74 68 - is present, th
0330: 65 6e 20 69 74 20 6d 75 73 74 0a 2a 2a 20 20 20 en it must.**
0340: 62 65 20 70 61 73 73 65 64 20 61 6e 20 69 6e 74 be passed an int
0350: 65 67 65 72 20 76 61 6c 75 65 20 74 68 61 74 20 eger value that
0360: 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 61 corresponds to a
0370: 20 50 4f 53 49 58 20 6d 6f 64 65 0a 2a 2a 20 20 POSIX mode.**
0380: 20 76 61 6c 75 65 20 28 66 69 6c 65 20 74 79 70 value (file typ
0390: 65 20 2b 20 70 65 72 6d 69 73 73 69 6f 6e 73 2c e + permissions,
03a0: 20 61 73 20 72 65 74 75 72 6e 65 64 20 69 6e 20 as returned in
03b0: 74 68 65 20 73 74 61 74 2e 73 74 5f 6d 6f 64 65 the stat.st_mode
03c0: 0a 2a 2a 20 20 20 66 69 65 6c 64 20 62 79 20 74 .** field by t
03d0: 68 65 20 73 74 61 74 28 29 20 73 79 73 74 65 6d he stat() system
03e0: 20 63 61 6c 6c 29 2e 20 54 68 72 65 65 20 74 79 call). Three ty
03f0: 70 65 73 20 6f 66 20 66 69 6c 65 73 20 6d 61 79 pes of files may
0400: 0a 2a 2a 20 20 20 62 65 20 77 72 69 74 74 65 6e .** be written
0410: 2f 63 72 65 61 74 65 64 3a 0a 2a 2a 0a 2a 2a 20 /created:.**.**
0420: 20 20 20 20 72 65 67 75 6c 61 72 20 66 69 6c 65 regular file
0430: 73 3a 20 20 28 6d 6f 64 65 20 26 20 30 31 37 30 s: (mode & 0170
0440: 30 30 30 29 3d 3d 30 31 30 30 30 30 30 0a 2a 2a 000)==0100000.**
0450: 20 20 20 20 20 73 79 6d 62 6f 6c 69 63 20 6c 69 symbolic li
0460: 6e 6b 73 3a 20 28 6d 6f 64 65 20 26 20 30 31 37 nks: (mode & 017
0470: 30 30 30 30 29 3d 3d 30 31 32 30 30 30 30 0a 2a 0000)==0120000.*
0480: 2a 20 20 20 20 20 64 69 72 65 63 74 6f 72 69 65 * directorie
0490: 73 3a 20 20 20 20 28 6d 6f 64 65 20 26 20 30 31 s: (mode & 01
04a0: 37 30 30 30 30 29 3d 3d 30 30 34 30 30 30 30 0a 70000)==0040000.
04b0: 2a 2a 0a 2a 2a 20 20 20 46 6f 72 20 61 20 64 69 **.** For a di
04c0: 72 65 63 74 6f 72 79 2c 20 74 68 65 20 44 41 54 rectory, the DAT
04d0: 41 20 69 73 20 69 67 6e 6f 72 65 64 2e 20 46 6f A is ignored. Fo
04e0: 72 20 61 20 73 79 6d 62 6f 6c 69 63 20 6c 69 6e r a symbolic lin
04f0: 6b 2c 20 69 74 20 69 73 0a 2a 2a 20 20 20 69 6e k, it is.** in
0500: 74 65 72 70 72 65 74 65 64 20 61 73 20 74 65 78 terpreted as tex
0510: 74 20 61 6e 64 20 75 73 65 64 20 61 73 20 74 68 t and used as th
0520: 65 20 74 61 72 67 65 74 20 6f 66 20 74 68 65 20 e target of the
0530: 6c 69 6e 6b 2e 20 46 6f 72 20 61 0a 2a 2a 20 20 link. For a.**
0540: 20 72 65 67 75 6c 61 72 20 66 69 6c 65 2c 20 69 regular file, i
0550: 74 20 69 73 20 69 6e 74 65 72 70 72 65 74 65 64 t is interpreted
0560: 20 61 73 20 61 20 62 6c 6f 62 20 61 6e 64 20 77 as a blob and w
0570: 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 0a ritten into the.
0580: 2a 2a 20 20 20 6e 61 6d 65 64 20 66 69 6c 65 2e ** named file.
0590: 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66 20 74 Regardless of t
05a0: 68 65 20 74 79 70 65 20 6f 66 20 66 69 6c 65 2c he type of file,
05b0: 20 69 74 73 20 70 65 72 6d 69 73 73 69 6f 6e 73 its permissions
05c0: 20 61 72 65 0a 2a 2a 20 20 20 73 65 74 20 74 6f are.** set to
05d0: 20 28 6d 6f 64 65 20 26 20 30 37 37 37 29 20 62 (mode & 0777) b
05e0: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e efore returning.
05f0: 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 74 68 65 20 .**.** If the
0600: 6f 70 74 69 6f 6e 61 6c 20 4d 54 49 4d 45 20 61 optional MTIME a
0610: 72 67 75 6d 65 6e 74 20 69 73 20 70 72 65 73 65 rgument is prese
0620: 6e 74 2c 20 74 68 65 6e 20 69 74 20 69 73 20 69 nt, then it is i
0630: 6e 74 65 72 70 72 65 74 65 64 0a 2a 2a 20 20 20 nterpreted.**
0640: 61 73 20 61 6e 20 69 6e 74 65 67 65 72 20 2d 20 as an integer -
0650: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 73 65 the number of se
0660: 63 6f 6e 64 73 20 73 69 6e 63 65 20 74 68 65 20 conds since the
0670: 75 6e 69 78 20 65 70 6f 63 68 2e 20 54 68 65 0a unix epoch. The.
0680: 2a 2a 20 20 20 6d 6f 64 69 66 69 63 61 74 69 6f ** modificatio
0690: 6e 2d 74 69 6d 65 20 6f 66 20 74 68 65 20 74 61 n-time of the ta
06a0: 72 67 65 74 20 66 69 6c 65 20 69 73 20 73 65 74 rget file is set
06b0: 20 74 6f 20 74 68 69 73 20 76 61 6c 75 65 20 62 to this value b
06c0: 65 66 6f 72 65 0a 2a 2a 20 20 20 72 65 74 75 72 efore.** retur
06d0: 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66 ning..**.** If
06e0: 20 74 68 72 65 65 20 6f 72 20 6d 6f 72 65 20 61 three or more a
06f0: 72 67 75 6d 65 6e 74 73 20 61 72 65 20 70 61 73 rguments are pas
0700: 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e 63 sed to this func
0710: 74 69 6f 6e 20 61 6e 64 20 61 6e 0a 2a 2a 20 20 tion and an.**
0720: 20 65 72 72 6f 72 20 69 73 20 65 6e 63 6f 75 6e error is encoun
0730: 74 65 72 65 64 2c 20 61 6e 20 65 78 63 65 70 74 tered, an except
0740: 69 6f 6e 20 69 73 20 72 61 69 73 65 64 2e 0a 2a ion is raised..*
0750: 2a 0a 2a 2a 20 52 45 41 44 46 49 4c 45 28 46 49 *.** READFILE(FI
0760: 4c 45 29 3a 0a 2a 2a 0a 2a 2a 20 20 20 52 65 61 LE):.**.** Rea
0770: 64 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65 d and return the
0780: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 66 69 6c contents of fil
0790: 65 20 46 49 4c 45 20 28 74 79 70 65 20 62 6c 6f e FILE (type blo
07a0: 62 29 20 66 72 6f 6d 20 64 69 73 6b 2e 0a 2a 2a b) from disk..**
07b0: 0a 2a 2a 20 46 53 44 49 52 3a 0a 2a 2a 0a 2a 2a .** FSDIR:.**.**
07c0: 20 20 20 55 73 65 64 20 61 73 20 66 6f 6c 6c 6f Used as follo
07d0: 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 53 45 ws:.**.** SE
07e0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 66 73 64 69 LECT * FROM fsdi
07f0: 72 28 24 70 61 74 68 20 5b 2c 20 24 64 69 72 5d r($path [, $dir]
0800: 29 3b 0a 2a 2a 0a 2a 2a 20 20 20 50 61 72 61 6d );.**.** Param
0810: 65 74 65 72 20 24 70 61 74 68 20 69 73 20 61 6e eter $path is an
0820: 20 61 62 73 6f 6c 75 74 65 20 6f 72 20 72 65 6c absolute or rel
0830: 61 74 69 76 65 20 70 61 74 68 6e 61 6d 65 2e 20 ative pathname.
0840: 49 66 20 74 68 65 20 66 69 6c 65 20 74 68 61 74 If the file that
0850: 20 69 74 0a 2a 2a 20 20 20 72 65 66 65 72 73 20 it.** refers
0860: 74 6f 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 to does not exis
0870: 74 2c 20 69 74 20 69 73 20 61 6e 20 65 72 72 6f t, it is an erro
0880: 72 2e 20 49 66 20 74 68 65 20 70 61 74 68 20 72 r. If the path r
0890: 65 66 65 72 73 20 74 6f 20 61 20 72 65 67 75 6c efers to a regul
08a0: 61 72 0a 2a 2a 20 20 20 66 69 6c 65 20 6f 72 20 ar.** file or
08b0: 73 79 6d 62 6f 6c 69 63 20 6c 69 6e 6b 2c 20 69 symbolic link, i
08c0: 74 20 72 65 74 75 72 6e 73 20 61 20 73 69 6e 67 t returns a sing
08d0: 6c 65 20 72 6f 77 2e 20 4f 72 2c 20 69 66 20 74 le row. Or, if t
08e0: 68 65 20 70 61 74 68 20 72 65 66 65 72 73 0a 2a he path refers.*
08f0: 2a 20 20 20 74 6f 20 61 20 64 69 72 65 63 74 6f * to a directo
0900: 72 79 2c 20 69 74 20 72 65 74 75 72 6e 73 20 6f ry, it returns o
0910: 6e 65 20 72 6f 77 20 66 6f 72 20 74 68 65 20 64 ne row for the d
0920: 69 72 65 63 74 6f 72 79 2c 20 61 6e 64 20 6f 6e irectory, and on
0930: 65 20 72 6f 77 20 66 6f 72 20 65 61 63 68 0a 2a e row for each.*
0940: 2a 20 20 20 66 69 6c 65 20 77 69 74 68 69 6e 20 * file within
0950: 74 68 65 20 68 69 65 72 61 72 63 68 79 20 72 6f the hierarchy ro
0960: 6f 74 65 64 20 61 74 20 24 70 61 74 68 2e 0a 2a oted at $path..*
0970: 2a 0a 2a 2a 20 20 20 45 61 63 68 20 72 6f 77 20 *.** Each row
0980: 68 61 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e has the followin
0990: 67 20 63 6f 6c 75 6d 6e 73 3a 0a 2a 2a 0a 2a 2a g columns:.**.**
09a0: 20 20 20 20 20 6e 61 6d 65 3a 20 20 50 61 74 68 name: Path
09b0: 20 74 6f 20 66 69 6c 65 20 6f 72 20 64 69 72 65 to file or dire
09c0: 63 74 6f 72 79 20 28 74 65 78 74 20 76 61 6c 75 ctory (text valu
09d0: 65 29 2e 0a 2a 2a 20 20 20 20 20 6d 6f 64 65 3a e)..** mode:
09e0: 20 20 56 61 6c 75 65 20 6f 66 20 73 74 61 74 2e Value of stat.
09f0: 73 74 5f 6d 6f 64 65 20 66 6f 72 20 64 69 72 65 st_mode for dire
0a00: 63 74 6f 72 79 20 65 6e 74 72 79 20 28 61 6e 20 ctory entry (an
0a10: 69 6e 74 65 67 65 72 29 2e 0a 2a 2a 20 20 20 20 integer)..**
0a20: 20 6d 74 69 6d 65 3a 20 56 61 6c 75 65 20 6f 66 mtime: Value of
0a30: 20 73 74 61 74 2e 73 74 5f 6d 74 69 6d 65 20 66 stat.st_mtime f
0a40: 6f 72 20 64 69 72 65 63 74 6f 72 79 20 65 6e 74 or directory ent
0a50: 72 79 20 28 61 6e 20 69 6e 74 65 67 65 72 29 2e ry (an integer).
0a60: 0a 2a 2a 20 20 20 20 20 64 61 74 61 3a 20 20 46 .** data: F
0a70: 6f 72 20 61 20 72 65 67 75 6c 61 72 20 66 69 6c or a regular fil
0a80: 65 2c 20 61 20 62 6c 6f 62 20 63 6f 6e 74 61 69 e, a blob contai
0a90: 6e 69 6e 67 20 74 68 65 20 66 69 6c 65 20 64 61 ning the file da
0aa0: 74 61 2e 20 46 6f 72 20 61 0a 2a 2a 20 20 20 20 ta. For a.**
0ab0: 20 20 20 20 20 20 20 20 73 79 6d 6c 69 6e 6b 2c symlink,
0ac0: 20 61 20 74 65 78 74 20 76 61 6c 75 65 20 63 6f a text value co
0ad0: 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 74 65 78 ntaining the tex
0ae0: 74 20 6f 66 20 74 68 65 20 6c 69 6e 6b 2e 20 46 t of the link. F
0af0: 6f 72 20 61 0a 2a 2a 20 20 20 20 20 20 20 20 20 or a.**
0b00: 20 20 20 64 69 72 65 63 74 6f 72 79 2c 20 4e 55 directory, NU
0b10: 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 61 LL..**.** If a
0b20: 20 6e 6f 6e 2d 4e 55 4c 4c 20 76 61 6c 75 65 20 non-NULL value
0b30: 69 73 20 73 70 65 63 69 66 69 65 64 20 66 6f 72 is specified for
0b40: 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c 20 24 64 the optional $d
0b50: 69 72 20 70 61 72 61 6d 65 74 65 72 20 61 6e 64 ir parameter and
0b60: 0a 2a 2a 20 20 20 24 70 61 74 68 20 69 73 20 61 .** $path is a
0b70: 20 72 65 6c 61 74 69 76 65 20 70 61 74 68 2c 20 relative path,
0b80: 74 68 65 6e 20 24 70 61 74 68 20 69 73 20 69 6e then $path is in
0b90: 74 65 72 70 72 65 74 65 64 20 72 65 6c 61 74 69 terpreted relati
0ba0: 76 65 20 74 6f 20 24 64 69 72 2e 20 0a 2a 2a 20 ve to $dir. .**
0bb0: 20 20 41 6e 64 20 74 68 65 20 70 61 74 68 73 20 And the paths
0bc0: 72 65 74 75 72 6e 65 64 20 69 6e 20 74 68 65 20 returned in the
0bd0: 22 6e 61 6d 65 22 20 63 6f 6c 75 6d 6e 20 6f 66 "name" column of
0be0: 20 74 68 65 20 74 61 62 6c 65 20 61 72 65 20 61 the table are a
0bf0: 6c 73 6f 20 0a 2a 2a 20 20 20 72 65 6c 61 74 69 lso .** relati
0c00: 76 65 20 74 6f 20 64 69 72 65 63 74 6f 72 79 20 ve to directory
0c10: 24 64 69 72 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 $dir..*/.#includ
0c20: 65 20 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22 e "sqlite3ext.h"
0c30: 0a 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f .SQLITE_EXTENSIO
0c40: 4e 5f 49 4e 49 54 31 0a 23 69 6e 63 6c 75 64 65 N_INIT1.#include
0c50: 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c <stdio.h>.#incl
0c60: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 ude <string.h>.#
0c70: 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e include <assert.
0c80: 68 3e 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 h>..#include <sy
0c90: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c s/types.h>.#incl
0ca0: 75 64 65 20 3c 73 79 73 2f 73 74 61 74 2e 68 3e ude <sys/stat.h>
0cb0: 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c .#include <fcntl
0cc0: 2e 68 3e 0a 23 69 66 20 21 64 65 66 69 6e 65 64 .h>.#if !defined
0cd0: 28 5f 57 49 4e 33 32 29 20 26 26 20 21 64 65 66 (_WIN32) && !def
0ce0: 69 6e 65 64 28 57 49 4e 33 32 29 0a 23 20 20 69 ined(WIN32).# i
0cf0: 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 nclude <unistd.h
0d00: 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 64 69 >.# include <di
0d10: 72 65 6e 74 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 rent.h>.# inclu
0d20: 64 65 20 3c 75 74 69 6d 65 2e 68 3e 0a 23 20 20 de <utime.h>.#
0d30: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d include <sys/tim
0d40: 65 2e 68 3e 0a 23 65 6c 73 65 0a 23 20 20 69 6e e.h>.#else.# in
0d50: 63 6c 75 64 65 20 22 77 69 6e 64 6f 77 73 2e 68 clude "windows.h
0d60: 22 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 69 6f ".# include <io
0d70: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c .h>.# include <
0d80: 64 69 72 65 63 74 2e 68 3e 0a 23 20 20 69 6e 63 direct.h>.# inc
0d90: 6c 75 64 65 20 22 74 65 73 74 5f 77 69 6e 64 69 lude "test_windi
0da0: 72 65 6e 74 2e 68 22 0a 23 20 20 64 65 66 69 6e rent.h".# defin
0db0: 65 20 64 69 72 65 6e 74 20 44 49 52 45 4e 54 0a e dirent DIRENT.
0dc0: 23 20 20 69 66 6e 64 65 66 20 63 68 6d 6f 64 0a # ifndef chmod.
0dd0: 23 20 20 20 20 64 65 66 69 6e 65 20 63 68 6d 6f # define chmo
0de0: 64 20 5f 63 68 6d 6f 64 0a 23 20 20 65 6e 64 69 d _chmod.# endi
0df0: 66 0a 23 20 20 69 66 6e 64 65 66 20 73 74 61 74 f.# ifndef stat
0e00: 0a 23 20 20 20 20 64 65 66 69 6e 65 20 73 74 61 .# define sta
0e10: 74 20 5f 73 74 61 74 0a 23 20 20 65 6e 64 69 66 t _stat.# endif
0e20: 0a 23 20 20 64 65 66 69 6e 65 20 6d 6b 64 69 72 .# define mkdir
0e30: 28 70 61 74 68 2c 6d 6f 64 65 29 20 5f 6d 6b 64 (path,mode) _mkd
0e40: 69 72 28 70 61 74 68 29 0a 23 20 20 64 65 66 69 ir(path).# defi
0e50: 6e 65 20 6c 73 74 61 74 28 70 61 74 68 2c 62 75 ne lstat(path,bu
0e60: 66 29 20 73 74 61 74 28 70 61 74 68 2c 62 75 66 f) stat(path,buf
0e70: 29 0a 23 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64 ).#endif.#includ
0e80: 65 20 3c 74 69 6d 65 2e 68 3e 0a 23 69 6e 63 6c e <time.h>.#incl
0e90: 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 0a 0a ude <errno.h>...
0ea0: 2f 2a 0a 2a 2a 20 53 74 72 75 63 74 75 72 65 20 /*.** Structure
0eb0: 6f 66 20 74 68 65 20 66 73 64 69 72 28 29 20 74 of the fsdir() t
0ec0: 61 62 6c 65 2d 76 61 6c 75 65 64 20 66 75 6e 63 able-valued func
0ed0: 74 69 6f 6e 0a 2a 2f 0a 20 20 20 20 20 20 20 20 tion.*/.
0ee0: 20 20 20 20 20 20 20 20 20 2f 2a 20 20 20 20 30 /* 0
0ef0: 20 20 20 20 31 20 20 20 20 32 20 20 20 20 20 33 1 2 3
0f00: 20 20 20 20 34 20 20 20 20 20 20 20 20 20 20 20 4
0f10: 35 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 2f 5 */
0f20: 0a 23 64 65 66 69 6e 65 20 46 53 44 49 52 5f 53 .#define FSDIR_S
0f30: 43 48 45 4d 41 20 22 28 6e 61 6d 65 2c 6d 6f 64 CHEMA "(name,mod
0f40: 65 2c 6d 74 69 6d 65 2c 64 61 74 61 2c 70 61 74 e,mtime,data,pat
0f50: 68 20 48 49 44 44 45 4e 2c 64 69 72 20 48 49 44 h HIDDEN,dir HID
0f60: 44 45 4e 29 22 0a 23 64 65 66 69 6e 65 20 46 53 DEN)".#define FS
0f70: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4e 41 4d 45 20 DIR_COLUMN_NAME
0f80: 20 20 20 20 30 20 20 20 20 20 2f 2a 20 4e 61 6d 0 /* Nam
0f90: 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 2a 2f e of the file */
0fa0: 0a 23 64 65 66 69 6e 65 20 46 53 44 49 52 5f 43 .#define FSDIR_C
0fb0: 4f 4c 55 4d 4e 5f 4d 4f 44 45 20 20 20 20 20 31 OLUMN_MODE 1
0fc0: 20 20 20 20 20 2f 2a 20 41 63 63 65 73 73 20 6d /* Access m
0fd0: 6f 64 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 ode */.#define F
0fe0: 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4d 54 49 4d SDIR_COLUMN_MTIM
0ff0: 45 20 20 20 20 32 20 20 20 20 20 2f 2a 20 4c 61 E 2 /* La
1000: 73 74 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 20 st modification
1010: 74 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20 time */.#define
1020: 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 41 54 FSDIR_COLUMN_DAT
1030: 41 20 20 20 20 20 33 20 20 20 20 20 2f 2a 20 46 A 3 /* F
1040: 69 6c 65 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 23 ile content */.#
1050: 64 65 66 69 6e 65 20 46 53 44 49 52 5f 43 4f 4c define FSDIR_COL
1060: 55 4d 4e 5f 50 41 54 48 20 20 20 20 20 34 20 20 UMN_PATH 4
1070: 20 20 20 2f 2a 20 50 61 74 68 20 74 6f 20 74 6f /* Path to to
1080: 70 20 6f 66 20 73 65 61 72 63 68 20 2a 2f 0a 23 p of search */.#
1090: 64 65 66 69 6e 65 20 46 53 44 49 52 5f 43 4f 4c define FSDIR_COL
10a0: 55 4d 4e 5f 44 49 52 20 20 20 20 20 20 35 20 20 UMN_DIR 5
10b0: 20 20 20 2f 2a 20 50 61 74 68 20 69 73 20 72 65 /* Path is re
10c0: 6c 61 74 69 76 65 20 74 6f 20 74 68 69 73 20 64 lative to this d
10d0: 69 72 65 63 74 6f 72 79 20 2a 2f 0a 0a 0a 2f 2a irectory */.../*
10e0: 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 73 75 .** Set the resu
10f0: 6c 74 20 73 74 6f 72 65 64 20 62 79 20 63 6f 6e lt stored by con
1100: 74 65 78 74 20 63 74 78 20 74 6f 20 61 20 62 6c text ctx to a bl
1110: 6f 62 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 ob containing th
1120: 65 20 0a 2a 2a 20 63 6f 6e 74 65 6e 74 73 20 6f e .** contents o
1130: 66 20 66 69 6c 65 20 7a 4e 61 6d 65 2e 0a 2a 2f f file zName..*/
1140: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 72 65 61 .static void rea
1150: 64 46 69 6c 65 43 6f 6e 74 65 6e 74 73 28 73 71 dFileContents(sq
1160: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 lite3_context *c
1170: 74 78 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a tx, const char *
1180: 7a 4e 61 6d 65 29 7b 0a 20 20 46 49 4c 45 20 2a zName){. FILE *
1190: 69 6e 3b 0a 20 20 6c 6f 6e 67 20 6e 49 6e 3b 0a in;. long nIn;.
11a0: 20 20 76 6f 69 64 20 2a 70 42 75 66 3b 0a 0a 20 void *pBuf;..
11b0: 20 69 6e 20 3d 20 66 6f 70 65 6e 28 7a 4e 61 6d in = fopen(zNam
11c0: 65 2c 20 22 72 62 22 29 3b 0a 20 20 69 66 28 20 e, "rb");. if(
11d0: 69 6e 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a in==0 ) return;.
11e0: 20 20 66 73 65 65 6b 28 69 6e 2c 20 30 2c 20 53 fseek(in, 0, S
11f0: 45 45 4b 5f 45 4e 44 29 3b 0a 20 20 6e 49 6e 20 EEK_END);. nIn
1200: 3d 20 66 74 65 6c 6c 28 69 6e 29 3b 0a 20 20 72 = ftell(in);. r
1210: 65 77 69 6e 64 28 69 6e 29 3b 0a 20 20 70 42 75 ewind(in);. pBu
1220: 66 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c f = sqlite3_mall
1230: 6f 63 28 20 6e 49 6e 20 29 3b 0a 20 20 69 66 28 oc( nIn );. if(
1240: 20 70 42 75 66 20 26 26 20 31 3d 3d 66 72 65 61 pBuf && 1==frea
1250: 64 28 70 42 75 66 2c 20 6e 49 6e 2c 20 31 2c 20 d(pBuf, nIn, 1,
1260: 69 6e 29 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 in) ){. sqlit
1270: 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 63 e3_result_blob(c
1280: 74 78 2c 20 70 42 75 66 2c 20 6e 49 6e 2c 20 73 tx, pBuf, nIn, s
1290: 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 qlite3_free);.
12a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 }else{. sqlit
12b0: 65 33 5f 66 72 65 65 28 70 42 75 66 29 3b 0a 20 e3_free(pBuf);.
12c0: 20 7d 0a 20 20 66 63 6c 6f 73 65 28 69 6e 29 3b }. fclose(in);
12d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d .}../*.** Implem
12e0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 entation of the
12f0: 22 72 65 61 64 66 69 6c 65 28 58 29 22 20 53 51 "readfile(X)" SQ
1300: 4c 20 66 75 6e 63 74 69 6f 6e 2e 20 20 54 68 65 L function. The
1310: 20 65 6e 74 69 72 65 20 63 6f 6e 74 65 6e 74 0a entire content.
1320: 2a 2a 20 6f 66 20 74 68 65 20 66 69 6c 65 20 6e ** of the file n
1330: 61 6d 65 64 20 58 20 69 73 20 72 65 61 64 20 61 amed X is read a
1340: 6e 64 20 72 65 74 75 72 6e 65 64 20 61 73 20 61 nd returned as a
1350: 20 42 4c 4f 42 2e 20 20 4e 55 4c 4c 20 69 73 20 BLOB. NULL is
1360: 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 66 20 74 returned.** if t
1370: 68 65 20 66 69 6c 65 20 64 6f 65 73 20 6e 6f 74 he file does not
1380: 20 65 78 69 73 74 20 6f 72 20 69 73 20 75 6e 72 exist or is unr
1390: 65 61 64 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 eadable..*/.stat
13a0: 69 63 20 76 6f 69 64 20 72 65 61 64 66 69 6c 65 ic void readfile
13b0: 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f Func(. sqlite3_
13c0: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 context *context
13d0: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 ,. int argc,.
13e0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a sqlite3_value **
13f0: 61 72 67 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 argv.){. const
1400: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 28 char *zName;. (
1410: 76 6f 69 64 29 28 61 72 67 63 29 3b 20 20 2f 2a void)(argc); /*
1420: 20 55 6e 75 73 65 64 20 70 61 72 61 6d 65 74 65 Unused paramete
1430: 72 20 2a 2f 0a 20 20 7a 4e 61 6d 65 20 3d 20 28 r */. zName = (
1440: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 const char*)sqli
1450: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 te3_value_text(a
1460: 72 67 76 5b 30 5d 29 3b 0a 20 20 69 66 28 20 7a rgv[0]);. if( z
1470: 4e 61 6d 65 3d 3d 30 20 29 20 72 65 74 75 72 6e Name==0 ) return
1480: 3b 0a 20 20 72 65 61 64 46 69 6c 65 43 6f 6e 74 ;. readFileCont
1490: 65 6e 74 73 28 63 6f 6e 74 65 78 74 2c 20 7a 4e ents(context, zN
14a0: 61 6d 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 ame);.}../*.** S
14b0: 65 74 20 74 68 65 20 65 72 72 6f 72 20 6d 65 73 et the error mes
14c0: 73 61 67 65 20 63 6f 6e 74 61 69 6e 65 64 20 69 sage contained i
14d0: 6e 20 63 6f 6e 74 65 78 74 20 63 74 78 20 74 6f n context ctx to
14e0: 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 0a the results of.
14f0: 2a 2a 20 76 70 72 69 6e 74 66 28 7a 46 6d 74 2c ** vprintf(zFmt,
1500: 20 2e 2e 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 ...)..*/.static
1510: 20 76 6f 69 64 20 63 74 78 45 72 72 6f 72 4d 73 void ctxErrorMs
1520: 67 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 g(sqlite3_contex
1530: 74 20 2a 63 74 78 2c 20 63 6f 6e 73 74 20 63 68 t *ctx, const ch
1540: 61 72 20 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a ar *zFmt, ...){.
1550: 20 20 63 68 61 72 20 2a 7a 4d 73 67 20 3d 20 30 char *zMsg = 0
1560: 3b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a ;. va_list ap;.
1570: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a va_start(ap, z
1580: 46 6d 74 29 3b 0a 20 20 7a 4d 73 67 20 3d 20 73 Fmt);. zMsg = s
1590: 71 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 qlite3_vmprintf(
15a0: 7a 46 6d 74 2c 20 61 70 29 3b 0a 20 20 73 71 6c zFmt, ap);. sql
15b0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f ite3_result_erro
15c0: 72 28 63 74 78 2c 20 7a 4d 73 67 2c 20 2d 31 29 r(ctx, zMsg, -1)
15d0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 ;. sqlite3_free
15e0: 28 7a 4d 73 67 29 3b 0a 20 20 76 61 5f 65 6e 64 (zMsg);. va_end
15f0: 28 61 70 29 3b 0a 7d 0a 0a 23 69 66 20 64 65 66 (ap);.}..#if def
1600: 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 2f 2a 0a ined(_WIN32)./*.
1610: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e ** This function
1620: 20 69 73 20 64 65 73 69 67 6e 65 64 20 74 6f 20 is designed to
1630: 63 6f 6e 76 65 72 74 20 61 20 57 69 6e 33 32 20 convert a Win32
1640: 46 49 4c 45 54 49 4d 45 20 73 74 72 75 63 74 75 FILETIME structu
1650: 72 65 20 69 6e 74 6f 20 74 68 65 0a 2a 2a 20 6e re into the.** n
1660: 75 6d 62 65 72 20 6f 66 20 73 65 63 6f 6e 64 73 umber of seconds
1670: 20 73 69 6e 63 65 20 74 68 65 20 55 6e 69 78 20 since the Unix
1680: 45 70 6f 63 68 20 28 31 39 37 30 2d 30 31 2d 30 Epoch (1970-01-0
1690: 31 20 30 30 3a 30 30 3a 30 30 20 55 54 43 29 2e 1 00:00:00 UTC).
16a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 .*/.static sqlit
16b0: 65 33 5f 75 69 6e 74 36 34 20 66 69 6c 65 54 69 e3_uint64 fileTi
16c0: 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 0a 20 20 meToUnixTime(.
16d0: 4c 50 46 49 4c 45 54 49 4d 45 20 70 46 69 6c 65 LPFILETIME pFile
16e0: 54 69 6d 65 0a 29 7b 0a 20 20 53 59 53 54 45 4d Time.){. SYSTEM
16f0: 54 49 4d 45 20 65 70 6f 63 68 53 79 73 74 65 6d TIME epochSystem
1700: 54 69 6d 65 3b 0a 20 20 55 4c 41 52 47 45 5f 49 Time;. ULARGE_I
1710: 4e 54 45 47 45 52 20 65 70 6f 63 68 49 6e 74 65 NTEGER epochInte
1720: 72 76 61 6c 73 3b 0a 20 20 46 49 4c 45 54 49 4d rvals;. FILETIM
1730: 45 20 65 70 6f 63 68 46 69 6c 65 54 69 6d 65 3b E epochFileTime;
1740: 0a 20 20 55 4c 41 52 47 45 5f 49 4e 54 45 47 45 . ULARGE_INTEGE
1750: 52 20 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 3b R fileIntervals;
1760: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 65 70 6f 63 .. memset(&epoc
1770: 68 53 79 73 74 65 6d 54 69 6d 65 2c 20 30 2c 20 hSystemTime, 0,
1780: 73 69 7a 65 6f 66 28 53 59 53 54 45 4d 54 49 4d sizeof(SYSTEMTIM
1790: 45 29 29 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 E));. epochSyst
17a0: 65 6d 54 69 6d 65 2e 77 59 65 61 72 20 3d 20 31 emTime.wYear = 1
17b0: 39 37 30 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 970;. epochSyst
17c0: 65 6d 54 69 6d 65 2e 77 4d 6f 6e 74 68 20 3d 20 emTime.wMonth =
17d0: 31 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 65 6d 1;. epochSystem
17e0: 54 69 6d 65 2e 77 44 61 79 20 3d 20 31 3b 0a 20 Time.wDay = 1;.
17f0: 20 53 79 73 74 65 6d 54 69 6d 65 54 6f 46 69 6c SystemTimeToFil
1800: 65 54 69 6d 65 28 26 65 70 6f 63 68 53 79 73 74 eTime(&epochSyst
1810: 65 6d 54 69 6d 65 2c 20 26 65 70 6f 63 68 46 69 emTime, &epochFi
1820: 6c 65 54 69 6d 65 29 3b 0a 20 20 65 70 6f 63 68 leTime);. epoch
1830: 49 6e 74 65 72 76 61 6c 73 2e 4c 6f 77 50 61 72 Intervals.LowPar
1840: 74 20 3d 20 65 70 6f 63 68 46 69 6c 65 54 69 6d t = epochFileTim
1850: 65 2e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65 3b e.dwLowDateTime;
1860: 0a 20 20 65 70 6f 63 68 49 6e 74 65 72 76 61 6c . epochInterval
1870: 73 2e 48 69 67 68 50 61 72 74 20 3d 20 65 70 6f s.HighPart = epo
1880: 63 68 46 69 6c 65 54 69 6d 65 2e 64 77 48 69 67 chFileTime.dwHig
1890: 68 44 61 74 65 54 69 6d 65 3b 0a 0a 20 20 66 69 hDateTime;.. fi
18a0: 6c 65 49 6e 74 65 72 76 61 6c 73 2e 4c 6f 77 50 leIntervals.LowP
18b0: 61 72 74 20 3d 20 70 46 69 6c 65 54 69 6d 65 2d art = pFileTime-
18c0: 3e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65 3b 0a >dwLowDateTime;.
18d0: 20 20 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e fileIntervals.
18e0: 48 69 67 68 50 61 72 74 20 3d 20 70 46 69 6c 65 HighPart = pFile
18f0: 54 69 6d 65 2d 3e 64 77 48 69 67 68 44 61 74 65 Time->dwHighDate
1900: 54 69 6d 65 3b 0a 0a 20 20 72 65 74 75 72 6e 20 Time;.. return
1910: 28 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e 51 (fileIntervals.Q
1920: 75 61 64 50 61 72 74 20 2d 20 65 70 6f 63 68 49 uadPart - epochI
1930: 6e 74 65 72 76 61 6c 73 2e 51 75 61 64 50 61 72 ntervals.QuadPar
1940: 74 29 20 2f 20 31 30 30 30 30 30 30 30 3b 0a 7d t) / 10000000;.}
1950: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e ../*.** This fun
1960: 63 74 69 6f 6e 20 61 74 74 65 6d 70 74 73 20 74 ction attempts t
1970: 6f 20 6e 6f 72 6d 61 6c 69 7a 65 20 74 68 65 20 o normalize the
1980: 74 69 6d 65 20 76 61 6c 75 65 73 20 66 6f 75 6e time values foun
1990: 64 20 69 6e 20 74 68 65 20 73 74 61 74 28 29 0a d in the stat().
19a0: 2a 2a 20 62 75 66 66 65 72 20 74 6f 20 55 54 43 ** buffer to UTC
19b0: 2e 20 20 54 68 69 73 20 69 73 20 6e 65 63 65 73 . This is neces
19c0: 73 61 72 79 20 6f 6e 20 57 69 6e 33 32 2c 20 77 sary on Win32, w
19d0: 68 65 72 65 20 74 68 65 20 72 75 6e 74 69 6d 65 here the runtime
19e0: 20 6c 69 62 72 61 72 79 0a 2a 2a 20 61 70 70 65 library.** appe
19f0: 61 72 73 20 74 6f 20 72 65 74 75 72 6e 20 74 68 ars to return th
1a00: 65 73 65 20 76 61 6c 75 65 73 20 61 73 20 6c 6f ese values as lo
1a10: 63 61 6c 20 74 69 6d 65 73 2e 0a 2a 2f 0a 73 74 cal times..*/.st
1a20: 61 74 69 63 20 76 6f 69 64 20 73 74 61 74 54 69 atic void statTi
1a30: 6d 65 73 54 6f 55 74 63 28 0a 20 20 63 6f 6e 73 mesToUtc(. cons
1a40: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 0a 20 t char *zPath,.
1a50: 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 70 53 struct stat *pS
1a60: 74 61 74 42 75 66 0a 29 7b 0a 20 20 48 41 4e 44 tatBuf.){. HAND
1a70: 4c 45 20 68 46 69 6e 64 46 69 6c 65 3b 0a 20 20 LE hFindFile;.
1a80: 57 49 4e 33 32 5f 46 49 4e 44 5f 44 41 54 41 57 WIN32_FIND_DATAW
1a90: 20 66 64 3b 0a 20 20 4c 50 57 53 54 52 20 7a 55 fd;. LPWSTR zU
1aa0: 6e 69 63 6f 64 65 4e 61 6d 65 3b 0a 20 20 65 78 nicodeName;. ex
1ab0: 74 65 72 6e 20 4c 50 57 53 54 52 20 73 71 6c 69 tern LPWSTR sqli
1ac0: 74 65 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 te3_win32_utf8_t
1ad0: 6f 5f 75 6e 69 63 6f 64 65 28 63 6f 6e 73 74 20 o_unicode(const
1ae0: 63 68 61 72 2a 29 3b 0a 20 20 7a 55 6e 69 63 6f char*);. zUnico
1af0: 64 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 deName = sqlite3
1b00: 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 75 _win32_utf8_to_u
1b10: 6e 69 63 6f 64 65 28 7a 50 61 74 68 29 3b 0a 20 nicode(zPath);.
1b20: 20 69 66 28 20 7a 55 6e 69 63 6f 64 65 4e 61 6d if( zUnicodeNam
1b30: 65 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 e ){. memset(
1b40: 26 66 64 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57 &fd, 0, sizeof(W
1b50: 49 4e 33 32 5f 46 49 4e 44 5f 44 41 54 41 57 29 IN32_FIND_DATAW)
1b60: 29 3b 0a 20 20 20 20 68 46 69 6e 64 46 69 6c 65 );. hFindFile
1b70: 20 3d 20 46 69 6e 64 46 69 72 73 74 46 69 6c 65 = FindFirstFile
1b80: 57 28 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 2c 20 W(zUnicodeName,
1b90: 26 66 64 29 3b 0a 20 20 20 20 69 66 28 20 68 46 &fd);. if( hF
1ba0: 69 6e 64 46 69 6c 65 21 3d 4e 55 4c 4c 20 29 7b indFile!=NULL ){
1bb0: 0a 20 20 20 20 20 20 70 53 74 61 74 42 75 66 2d . pStatBuf-
1bc0: 3e 73 74 5f 63 74 69 6d 65 20 3d 20 28 74 69 6d >st_ctime = (tim
1bd0: 65 5f 74 29 66 69 6c 65 54 69 6d 65 54 6f 55 6e e_t)fileTimeToUn
1be0: 69 78 54 69 6d 65 28 26 66 64 2e 66 74 43 72 65 ixTime(&fd.ftCre
1bf0: 61 74 69 6f 6e 54 69 6d 65 29 3b 0a 20 20 20 20 ationTime);.
1c00: 20 20 70 53 74 61 74 42 75 66 2d 3e 73 74 5f 61 pStatBuf->st_a
1c10: 74 69 6d 65 20 3d 20 28 74 69 6d 65 5f 74 29 66 time = (time_t)f
1c20: 69 6c 65 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d ileTimeToUnixTim
1c30: 65 28 26 66 64 2e 66 74 4c 61 73 74 41 63 63 65 e(&fd.ftLastAcce
1c40: 73 73 54 69 6d 65 29 3b 0a 20 20 20 20 20 20 70 ssTime);. p
1c50: 53 74 61 74 42 75 66 2d 3e 73 74 5f 6d 74 69 6d StatBuf->st_mtim
1c60: 65 20 3d 20 28 74 69 6d 65 5f 74 29 66 69 6c 65 e = (time_t)file
1c70: 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 26 TimeToUnixTime(&
1c80: 66 64 2e 66 74 4c 61 73 74 57 72 69 74 65 54 69 fd.ftLastWriteTi
1c90: 6d 65 29 3b 0a 20 20 20 20 20 20 46 69 6e 64 43 me);. FindC
1ca0: 6c 6f 73 65 28 68 46 69 6e 64 46 69 6c 65 29 3b lose(hFindFile);
1cb0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 . }. sqlit
1cc0: 65 33 5f 66 72 65 65 28 7a 55 6e 69 63 6f 64 65 e3_free(zUnicode
1cd0: 4e 61 6d 65 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e Name);. }.}.#en
1ce0: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 dif../*.** This
1cf0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 function is used
1d00: 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 73 74 61 in place of sta
1d10: 74 28 29 2e 20 20 4f 6e 20 57 69 6e 64 6f 77 73 t(). On Windows
1d20: 2c 20 73 70 65 63 69 61 6c 20 68 61 6e 64 6c 69 , special handli
1d30: 6e 67 0a 2a 2a 20 69 73 20 72 65 71 75 69 72 65 ng.** is require
1d40: 64 20 69 6e 20 6f 72 64 65 72 20 66 6f 72 20 74 d in order for t
1d50: 68 65 20 69 6e 63 6c 75 64 65 64 20 74 69 6d 65 he included time
1d60: 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65 64 20 to be returned
1d70: 61 73 20 55 54 43 2e 20 20 4f 6e 20 61 6c 6c 0a as UTC. On all.
1d80: 2a 2a 20 6f 74 68 65 72 20 73 79 73 74 65 6d 73 ** other systems
1d90: 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 , this function
1da0: 73 69 6d 70 6c 79 20 63 61 6c 6c 73 20 73 74 61 simply calls sta
1db0: 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 t()..*/.static i
1dc0: 6e 74 20 66 69 6c 65 53 74 61 74 28 0a 20 20 63 nt fileStat(. c
1dd0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 onst char *zPath
1de0: 2c 0a 20 20 73 74 72 75 63 74 20 73 74 61 74 20 ,. struct stat
1df0: 2a 70 53 74 61 74 42 75 66 0a 29 7b 0a 23 69 66 *pStatBuf.){.#if
1e00: 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 defined(_WIN32)
1e10: 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 74 61 74 . int rc = stat
1e20: 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66 (zPath, pStatBuf
1e30: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30 20 29 );. if( rc==0 )
1e40: 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74 63 28 statTimesToUtc(
1e50: 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66 29 zPath, pStatBuf)
1e60: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 23 ;. return rc;.#
1e70: 65 6c 73 65 0a 20 20 72 65 74 75 72 6e 20 73 74 else. return st
1e80: 61 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 at(zPath, pStatB
1e90: 75 66 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f uf);.#endif.}../
1ea0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 *.** This functi
1eb0: 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 20 70 6c on is used in pl
1ec0: 61 63 65 20 6f 66 20 6c 73 74 61 74 28 29 2e 20 ace of lstat().
1ed0: 20 4f 6e 20 57 69 6e 64 6f 77 73 2c 20 73 70 65 On Windows, spe
1ee0: 63 69 61 6c 20 68 61 6e 64 6c 69 6e 67 0a 2a 2a cial handling.**
1ef0: 20 69 73 20 72 65 71 75 69 72 65 64 20 69 6e 20 is required in
1f00: 6f 72 64 65 72 20 66 6f 72 20 74 68 65 20 69 6e order for the in
1f10: 63 6c 75 64 65 64 20 74 69 6d 65 20 74 6f 20 62 cluded time to b
1f20: 65 20 72 65 74 75 72 6e 65 64 20 61 73 20 55 54 e returned as UT
1f30: 43 2e 20 20 4f 6e 20 61 6c 6c 0a 2a 2a 20 6f 74 C. On all.** ot
1f40: 68 65 72 20 73 79 73 74 65 6d 73 2c 20 74 68 69 her systems, thi
1f50: 73 20 66 75 6e 63 74 69 6f 6e 20 73 69 6d 70 6c s function simpl
1f60: 79 20 63 61 6c 6c 73 20 6c 73 74 61 74 28 29 2e y calls lstat().
1f70: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 .*/.static int f
1f80: 69 6c 65 4c 69 6e 6b 53 74 61 74 28 0a 20 20 63 ileLinkStat(. c
1f90: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 onst char *zPath
1fa0: 2c 0a 20 20 73 74 72 75 63 74 20 73 74 61 74 20 ,. struct stat
1fb0: 2a 70 53 74 61 74 42 75 66 0a 29 7b 0a 23 69 66 *pStatBuf.){.#if
1fc0: 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 defined(_WIN32)
1fd0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 6c 73 74 61 . int rc = lsta
1fe0: 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 t(zPath, pStatBu
1ff0: 66 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30 20 f);. if( rc==0
2000: 29 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74 63 ) statTimesToUtc
2010: 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66 (zPath, pStatBuf
2020: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a );. return rc;.
2030: 23 65 6c 73 65 0a 20 20 72 65 74 75 72 6e 20 6c #else. return l
2040: 73 74 61 74 28 7a 50 61 74 68 2c 20 70 53 74 61 stat(zPath, pSta
2050: 74 42 75 66 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a tBuf);.#endif.}.
2060: 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 ./*.** Argument
2070: 7a 46 69 6c 65 20 69 73 20 74 68 65 20 6e 61 6d zFile is the nam
2080: 65 20 6f 66 20 61 20 66 69 6c 65 20 74 68 61 74 e of a file that
2090: 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 will be created
20a0: 20 61 6e 64 2f 6f 72 20 77 72 69 74 74 65 6e 0a and/or written.
20b0: 2a 2a 20 62 79 20 53 51 4c 20 66 75 6e 63 74 69 ** by SQL functi
20c0: 6f 6e 20 77 72 69 74 65 66 69 6c 65 28 29 2e 20 on writefile().
20d0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e This function en
20e0: 73 75 72 65 73 20 74 68 61 74 20 74 68 65 20 64 sures that the d
20f0: 69 72 65 63 74 6f 72 79 0a 2a 2a 20 7a 46 69 6c irectory.** zFil
2100: 65 20 77 69 6c 6c 20 62 65 20 77 72 69 74 74 65 e will be writte
2110: 6e 20 74 6f 20 65 78 69 73 74 73 2c 20 63 72 65 n to exists, cre
2120: 61 74 69 6e 67 20 69 74 20 69 66 20 72 65 71 75 ating it if requ
2130: 69 72 65 64 2e 20 54 68 65 20 70 65 72 6d 69 73 ired. The permis
2140: 73 69 6f 6e 73 0a 2a 2a 20 66 6f 72 20 61 6e 79 sions.** for any
2150: 20 70 61 74 68 20 63 6f 6d 70 6f 6e 65 6e 74 73 path components
2160: 20 63 72 65 61 74 65 64 20 62 79 20 74 68 69 73 created by this
2170: 20 66 75 6e 63 74 69 6f 6e 20 61 72 65 20 73 65 function are se
2180: 74 20 74 6f 20 28 6d 6f 64 65 26 30 37 37 37 29 t to (mode&0777)
2190: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f ..**.** If an OO
21a0: 4d 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73 20 65 M condition is e
21b0: 6e 63 6f 75 6e 74 65 72 65 64 2c 20 53 51 4c 49 ncountered, SQLI
21c0: 54 45 5f 4e 4f 4d 45 4d 20 69 73 20 72 65 74 75 TE_NOMEM is retu
21d0: 72 6e 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c rned. Otherwise,
21e0: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 .** SQLITE_OK is
21f0: 20 72 65 74 75 72 6e 65 64 20 69 66 20 74 68 65 returned if the
2200: 20 64 69 72 65 63 74 6f 72 79 20 69 73 20 73 75 directory is su
2210: 63 63 65 73 73 66 75 6c 6c 79 20 63 72 65 61 74 ccessfully creat
2220: 65 64 2c 20 6f 72 0a 2a 2a 20 53 51 4c 49 54 45 ed, or.** SQLITE
2230: 5f 45 52 52 4f 52 20 6f 74 68 65 72 77 69 73 65 _ERROR otherwise
2240: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
2250: 6d 61 6b 65 44 69 72 65 63 74 6f 72 79 28 0a 20 makeDirectory(.
2260: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 const char *zFi
2270: 6c 65 2c 0a 20 20 6d 6f 64 65 5f 74 20 6d 6f 64 le,. mode_t mod
2280: 65 0a 29 7b 0a 20 20 63 68 61 72 20 2a 7a 43 6f e.){. char *zCo
2290: 70 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 py = sqlite3_mpr
22a0: 69 6e 74 66 28 22 25 73 22 2c 20 7a 46 69 6c 65 intf("%s", zFile
22b0: 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 );. int rc = SQ
22c0: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 LITE_OK;.. if(
22d0: 7a 43 6f 70 79 3d 3d 30 20 29 7b 0a 20 20 20 20 zCopy==0 ){.
22e0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 rc = SQLITE_NOME
22f0: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 M;. }else{.
2300: 69 6e 74 20 6e 43 6f 70 79 20 3d 20 28 69 6e 74 int nCopy = (int
2310: 29 73 74 72 6c 65 6e 28 7a 43 6f 70 79 29 3b 0a )strlen(zCopy);.
2320: 20 20 20 20 69 6e 74 20 69 20 3d 20 31 3b 0a 0a int i = 1;..
2330: 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 while( rc==S
2340: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 QLITE_OK ){.
2350: 20 20 73 74 72 75 63 74 20 73 74 61 74 20 73 53 struct stat sS
2360: 74 61 74 3b 0a 20 20 20 20 20 20 69 6e 74 20 72 tat;. int r
2370: 63 32 3b 0a 0a 20 20 20 20 20 20 66 6f 72 28 3b c2;.. for(;
2380: 20 7a 43 6f 70 79 5b 69 5d 21 3d 27 2f 27 20 26 zCopy[i]!='/' &
2390: 26 20 69 3c 6e 43 6f 70 79 3b 20 69 2b 2b 29 3b & i<nCopy; i++);
23a0: 0a 20 20 20 20 20 20 69 66 28 20 69 3d 3d 6e 43 . if( i==nC
23b0: 6f 70 79 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 opy ) break;.
23c0: 20 20 20 7a 43 6f 70 79 5b 69 5d 20 3d 20 27 5c zCopy[i] = '\
23d0: 30 27 3b 0a 0a 20 20 20 20 20 20 72 63 32 20 3d 0';.. rc2 =
23e0: 20 66 69 6c 65 53 74 61 74 28 7a 43 6f 70 79 2c fileStat(zCopy,
23f0: 20 26 73 53 74 61 74 29 3b 0a 20 20 20 20 20 20 &sStat);.
2400: 69 66 28 20 72 63 32 21 3d 30 20 29 7b 0a 20 20 if( rc2!=0 ){.
2410: 20 20 20 20 20 20 69 66 28 20 6d 6b 64 69 72 28 if( mkdir(
2420: 7a 43 6f 70 79 2c 20 6d 6f 64 65 20 26 20 30 37 zCopy, mode & 07
2430: 37 37 29 20 29 20 72 63 20 3d 20 53 51 4c 49 54 77) ) rc = SQLIT
2440: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d E_ERROR;. }
2450: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 66 else{. if
2460: 28 20 21 53 5f 49 53 44 49 52 28 73 53 74 61 74 ( !S_ISDIR(sStat
2470: 2e 73 74 5f 6d 6f 64 65 29 20 29 20 72 63 20 3d .st_mode) ) rc =
2480: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 SQLITE_ERROR;.
2490: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 43 6f }. zCo
24a0: 70 79 5b 69 5d 20 3d 20 27 2f 27 3b 0a 20 20 20 py[i] = '/';.
24b0: 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 i++;. }..
24c0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 sqlite3_free(
24d0: 7a 43 6f 70 79 29 3b 0a 20 20 7d 0a 0a 20 20 72 zCopy);. }.. r
24e0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a eturn rc;.}../*.
24f0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e ** This function
2500: 20 64 6f 65 73 20 74 68 65 20 77 6f 72 6b 20 66 does the work f
2510: 6f 72 20 74 68 65 20 77 72 69 74 65 66 69 6c 65 or the writefile
2520: 28 29 20 55 44 46 2e 20 52 65 66 65 72 20 74 6f () UDF. Refer to
2530: 20 0a 2a 2a 20 68 65 61 64 65 72 20 63 6f 6d 6d .** header comm
2540: 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f 70 20 ents at the top
2550: 6f 66 20 74 68 69 73 20 66 69 6c 65 20 66 6f 72 of this file for
2560: 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 61 details..*/.sta
2570: 74 69 63 20 69 6e 74 20 77 72 69 74 65 46 69 6c tic int writeFil
2580: 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e e(. sqlite3_con
2590: 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20 20 text *pCtx,
25a0: 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 /* Context
25b0: 74 6f 20 72 65 74 75 72 6e 20 62 79 74 65 73 20 to return bytes
25c0: 77 72 69 74 74 65 6e 20 69 6e 20 2a 2f 0a 20 20 written in */.
25d0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c const char *zFil
25e0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 e,
25f0: 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65 /* File to write
2600: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 */. sqlite3_va
2610: 6c 75 65 20 2a 70 44 61 74 61 2c 20 20 20 20 20 lue *pData,
2620: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 20 74 6f /* Data to
2630: 20 77 72 69 74 65 20 2a 2f 0a 20 20 6d 6f 64 65 write */. mode
2640: 5f 74 20 6d 6f 64 65 2c 20 20 20 20 20 20 20 20 _t mode,
2650: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d /* M
2660: 4f 44 45 20 70 61 72 61 6d 65 74 65 72 20 70 61 ODE parameter pa
2670: 73 73 65 64 20 74 6f 20 77 72 69 74 65 66 69 6c ssed to writefil
2680: 65 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 e() */. sqlite3
2690: 5f 69 6e 74 36 34 20 6d 74 69 6d 65 20 20 20 20 _int64 mtime
26a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 54 49 4d /* MTIM
26b0: 45 20 70 61 72 61 6d 65 74 65 72 20 28 6f 72 20 E parameter (or
26c0: 2d 31 20 74 6f 20 6e 6f 74 20 73 65 74 20 74 69 -1 to not set ti
26d0: 6d 65 29 20 2a 2f 0a 29 7b 0a 23 69 66 20 21 64 me) */.){.#if !d
26e0: 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 20 26 efined(_WIN32) &
26f0: 26 20 21 64 65 66 69 6e 65 64 28 57 49 4e 33 32 & !defined(WIN32
2700: 29 0a 20 20 69 66 28 20 53 5f 49 53 4c 4e 4b 28 ). if( S_ISLNK(
2710: 6d 6f 64 65 29 20 29 7b 0a 20 20 20 20 63 6f 6e mode) ){. con
2720: 73 74 20 63 68 61 72 20 2a 7a 54 6f 20 3d 20 28 st char *zTo = (
2730: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 const char*)sqli
2740: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 te3_value_text(p
2750: 44 61 74 61 29 3b 0a 20 20 20 20 69 66 28 20 73 Data);. if( s
2760: 79 6d 6c 69 6e 6b 28 7a 54 6f 2c 20 7a 46 69 6c ymlink(zTo, zFil
2770: 65 29 3c 30 20 29 20 72 65 74 75 72 6e 20 31 3b e)<0 ) return 1;
2780: 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a . }else.#endif.
2790: 20 20 7b 0a 20 20 20 20 69 66 28 20 53 5f 49 53 {. if( S_IS
27a0: 44 49 52 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20 DIR(mode) ){.
27b0: 20 20 20 69 66 28 20 6d 6b 64 69 72 28 7a 46 69 if( mkdir(zFi
27c0: 6c 65 2c 20 6d 6f 64 65 29 20 29 7b 0a 20 20 20 le, mode) ){.
27d0: 20 20 20 20 20 2f 2a 20 54 68 65 20 6d 6b 64 69 /* The mkdi
27e0: 72 28 29 20 63 61 6c 6c 20 74 6f 20 63 72 65 61 r() call to crea
27f0: 74 65 20 74 68 65 20 64 69 72 65 63 74 6f 72 79 te the directory
2800: 20 66 61 69 6c 65 64 2e 20 54 68 69 73 20 6d 69 failed. This mi
2810: 67 68 74 20 6e 6f 74 0a 20 20 20 20 20 20 20 20 ght not.
2820: 2a 2a 20 62 65 20 61 6e 20 65 72 72 6f 72 20 74 ** be an error t
2830: 68 6f 75 67 68 20 2d 20 69 66 20 74 68 65 72 65 hough - if there
2840: 20 69 73 20 61 6c 72 65 61 64 79 20 61 20 64 69 is already a di
2850: 72 65 63 74 6f 72 79 20 61 74 20 74 68 65 20 73 rectory at the s
2860: 61 6d 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 70 ame. ** p
2870: 61 74 68 20 61 6e 64 20 65 69 74 68 65 72 20 74 ath and either t
2880: 68 65 20 70 65 72 6d 69 73 73 69 6f 6e 73 20 61 he permissions a
2890: 6c 72 65 61 64 79 20 6d 61 74 63 68 20 6f 72 20 lready match or
28a0: 63 61 6e 20 62 65 20 63 68 61 6e 67 65 64 0a 20 can be changed.
28b0: 20 20 20 20 20 20 20 2a 2a 20 74 6f 20 64 6f 20 ** to do
28c0: 73 6f 20 75 73 69 6e 67 20 63 68 6d 6f 64 28 29 so using chmod()
28d0: 2c 20 69 74 20 69 73 20 6e 6f 74 20 61 6e 20 65 , it is not an e
28e0: 72 72 6f 72 2e 20 20 2a 2f 0a 20 20 20 20 20 20 rror. */.
28f0: 20 20 73 74 72 75 63 74 20 73 74 61 74 20 73 53 struct stat sS
2900: 74 61 74 3b 0a 20 20 20 20 20 20 20 20 69 66 28 tat;. if(
2910: 20 65 72 72 6e 6f 21 3d 45 45 58 49 53 54 0a 20 errno!=EEXIST.
2920: 20 20 20 20 20 20 20 20 7c 7c 20 30 21 3d 66 69 || 0!=fi
2930: 6c 65 53 74 61 74 28 7a 46 69 6c 65 2c 20 26 73 leStat(zFile, &s
2940: 53 74 61 74 29 0a 20 20 20 20 20 20 20 20 20 7c Stat). |
2950: 7c 20 21 53 5f 49 53 44 49 52 28 73 53 74 61 74 | !S_ISDIR(sStat
2960: 2e 73 74 5f 6d 6f 64 65 29 0a 20 20 20 20 20 20 .st_mode).
2970: 20 20 20 7c 7c 20 28 28 73 53 74 61 74 2e 73 74 || ((sStat.st
2980: 5f 6d 6f 64 65 26 30 37 37 37 29 21 3d 28 6d 6f _mode&0777)!=(mo
2990: 64 65 26 30 37 37 37 29 20 26 26 20 30 21 3d 63 de&0777) && 0!=c
29a0: 68 6d 6f 64 28 7a 46 69 6c 65 2c 20 6d 6f 64 65 hmod(zFile, mode
29b0: 26 30 37 37 37 29 29 0a 20 20 20 20 20 20 20 20 &0777)).
29c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 ){. ret
29d0: 75 72 6e 20 31 3b 0a 20 20 20 20 20 20 20 20 7d urn 1;. }
29e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c . }. }el
29f0: 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 se{. sqlite
2a00: 33 5f 69 6e 74 36 34 20 6e 57 72 69 74 65 20 3d 3_int64 nWrite =
2a10: 20 30 3b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 0;. const
2a20: 63 68 61 72 20 2a 7a 3b 0a 20 20 20 20 20 20 69 char *z;. i
2a30: 6e 74 20 72 63 20 3d 20 30 3b 0a 20 20 20 20 20 nt rc = 0;.
2a40: 20 46 49 4c 45 20 2a 6f 75 74 20 3d 20 66 6f 70 FILE *out = fop
2a50: 65 6e 28 7a 46 69 6c 65 2c 20 22 77 62 22 29 3b en(zFile, "wb");
2a60: 0a 20 20 20 20 20 20 69 66 28 20 6f 75 74 3d 3d . if( out==
2a70: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 0 ) return 1;.
2a80: 20 20 20 20 7a 20 3d 20 28 63 6f 6e 73 74 20 63 z = (const c
2a90: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c har*)sqlite3_val
2aa0: 75 65 5f 62 6c 6f 62 28 70 44 61 74 61 29 3b 0a ue_blob(pData);.
2ab0: 20 20 20 20 20 20 69 66 28 20 7a 20 29 7b 0a 20 if( z ){.
2ac0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 sqlite3_i
2ad0: 6e 74 36 34 20 6e 20 3d 20 66 77 72 69 74 65 28 nt64 n = fwrite(
2ae0: 7a 2c 20 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 z, 1, sqlite3_va
2af0: 6c 75 65 5f 62 79 74 65 73 28 70 44 61 74 61 29 lue_bytes(pData)
2b00: 2c 20 6f 75 74 29 3b 0a 20 20 20 20 20 20 20 20 , out);.
2b10: 6e 57 72 69 74 65 20 3d 20 73 71 6c 69 74 65 33 nWrite = sqlite3
2b20: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 44 61 _value_bytes(pDa
2b30: 74 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 ta);. if(
2b40: 20 6e 57 72 69 74 65 21 3d 6e 20 29 7b 0a 20 20 nWrite!=n ){.
2b50: 20 20 20 20 20 20 20 20 72 63 20 3d 20 31 3b 0a rc = 1;.
2b60: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 }.
2b70: 7d 0a 20 20 20 20 20 20 66 63 6c 6f 73 65 28 6f }. fclose(o
2b80: 75 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 ut);. if( r
2b90: 63 3d 3d 30 20 26 26 20 6d 6f 64 65 20 26 26 20 c==0 && mode &&
2ba0: 63 68 6d 6f 64 28 7a 46 69 6c 65 2c 20 6d 6f 64 chmod(zFile, mod
2bb0: 65 20 26 20 30 37 37 37 29 20 29 7b 0a 20 20 20 e & 0777) ){.
2bc0: 20 20 20 20 20 72 63 20 3d 20 31 3b 0a 20 20 20 rc = 1;.
2bd0: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 }. if( r
2be0: 63 20 29 20 72 65 74 75 72 6e 20 32 3b 0a 20 20 c ) return 2;.
2bf0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 sqlite3_resu
2c00: 6c 74 5f 69 6e 74 36 34 28 70 43 74 78 2c 20 6e lt_int64(pCtx, n
2c10: 57 72 69 74 65 29 3b 0a 20 20 20 20 7d 0a 20 20 Write);. }.
2c20: 7d 0a 0a 20 20 69 66 28 20 6d 74 69 6d 65 3e 3d }.. if( mtime>=
2c30: 30 20 29 7b 0a 23 69 66 20 64 65 66 69 6e 65 64 0 ){.#if defined
2c40: 28 5f 57 49 4e 33 32 29 0a 20 20 20 20 2f 2a 20 (_WIN32). /*
2c50: 57 69 6e 64 6f 77 73 20 2a 2f 0a 20 20 20 20 46 Windows */. F
2c60: 49 4c 45 54 49 4d 45 20 6c 61 73 74 41 63 63 65 ILETIME lastAcce
2c70: 73 73 3b 0a 20 20 20 20 46 49 4c 45 54 49 4d 45 ss;. FILETIME
2c80: 20 6c 61 73 74 57 72 69 74 65 3b 0a 20 20 20 20 lastWrite;.
2c90: 53 59 53 54 45 4d 54 49 4d 45 20 63 75 72 72 65 SYSTEMTIME curre
2ca0: 6e 74 54 69 6d 65 3b 0a 20 20 20 20 4c 4f 4e 47 ntTime;. LONG
2cb0: 4c 4f 4e 47 20 69 6e 74 65 72 76 61 6c 73 3b 0a LONG intervals;.
2cc0: 20 20 20 20 48 41 4e 44 4c 45 20 68 46 69 6c 65 HANDLE hFile
2cd0: 3b 0a 20 20 20 20 4c 50 57 53 54 52 20 7a 55 6e ;. LPWSTR zUn
2ce0: 69 63 6f 64 65 4e 61 6d 65 3b 0a 20 20 20 20 65 icodeName;. e
2cf0: 78 74 65 72 6e 20 4c 50 57 53 54 52 20 73 71 6c xtern LPWSTR sql
2d00: 69 74 65 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f ite3_win32_utf8_
2d10: 74 6f 5f 75 6e 69 63 6f 64 65 28 63 6f 6e 73 74 to_unicode(const
2d20: 20 63 68 61 72 2a 29 3b 0a 0a 20 20 20 20 47 65 char*);.. Ge
2d30: 74 53 79 73 74 65 6d 54 69 6d 65 28 26 63 75 72 tSystemTime(&cur
2d40: 72 65 6e 74 54 69 6d 65 29 3b 0a 20 20 20 20 53 rentTime);. S
2d50: 79 73 74 65 6d 54 69 6d 65 54 6f 46 69 6c 65 54 ystemTimeToFileT
2d60: 69 6d 65 28 26 63 75 72 72 65 6e 74 54 69 6d 65 ime(¤tTime
2d70: 2c 20 26 6c 61 73 74 41 63 63 65 73 73 29 3b 0a , &lastAccess);.
2d80: 20 20 20 20 69 6e 74 65 72 76 61 6c 73 20 3d 20 intervals =
2d90: 49 6e 74 33 32 78 33 32 54 6f 36 34 28 6d 74 69 Int32x32To64(mti
2da0: 6d 65 2c 20 31 30 30 30 30 30 30 30 29 20 2b 20 me, 10000000) +
2db0: 31 31 36 34 34 34 37 33 36 30 30 30 30 30 30 30 1164447360000000
2dc0: 30 30 3b 0a 20 20 20 20 6c 61 73 74 57 72 69 74 00;. lastWrit
2dd0: 65 2e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65 20 e.dwLowDateTime
2de0: 3d 20 28 44 57 4f 52 44 29 69 6e 74 65 72 76 61 = (DWORD)interva
2df0: 6c 73 3b 0a 20 20 20 20 6c 61 73 74 57 72 69 74 ls;. lastWrit
2e00: 65 2e 64 77 48 69 67 68 44 61 74 65 54 69 6d 65 e.dwHighDateTime
2e10: 20 3d 20 69 6e 74 65 72 76 61 6c 73 20 3e 3e 20 = intervals >>
2e20: 33 32 3b 0a 20 20 20 20 7a 55 6e 69 63 6f 64 65 32;. zUnicode
2e30: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 77 Name = sqlite3_w
2e40: 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 75 6e 69 in32_utf8_to_uni
2e50: 63 6f 64 65 28 7a 46 69 6c 65 29 3b 0a 20 20 20 code(zFile);.
2e60: 20 69 66 28 20 7a 55 6e 69 63 6f 64 65 4e 61 6d if( zUnicodeNam
2e70: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 65 e==0 ){. re
2e80: 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 turn 1;. }.
2e90: 20 20 68 46 69 6c 65 20 3d 20 43 72 65 61 74 65 hFile = Create
2ea0: 46 69 6c 65 57 28 0a 20 20 20 20 20 20 7a 55 6e FileW(. zUn
2eb0: 69 63 6f 64 65 4e 61 6d 65 2c 20 46 49 4c 45 5f icodeName, FILE_
2ec0: 57 52 49 54 45 5f 41 54 54 52 49 42 55 54 45 53 WRITE_ATTRIBUTES
2ed0: 2c 20 30 2c 20 4e 55 4c 4c 2c 20 4f 50 45 4e 5f , 0, NULL, OPEN_
2ee0: 45 58 49 53 54 49 4e 47 2c 0a 20 20 20 20 20 20 EXISTING,.
2ef0: 46 49 4c 45 5f 46 4c 41 47 5f 42 41 43 4b 55 50 FILE_FLAG_BACKUP
2f00: 5f 53 45 4d 41 4e 54 49 43 53 2c 20 4e 55 4c 4c _SEMANTICS, NULL
2f10: 0a 20 20 20 20 29 3b 0a 20 20 20 20 73 71 6c 69 . );. sqli
2f20: 74 65 33 5f 66 72 65 65 28 7a 55 6e 69 63 6f 64 te3_free(zUnicod
2f30: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 eName);. if(
2f40: 68 46 69 6c 65 21 3d 49 4e 56 41 4c 49 44 5f 48 hFile!=INVALID_H
2f50: 41 4e 44 4c 45 5f 56 41 4c 55 45 20 29 7b 0a 20 ANDLE_VALUE ){.
2f60: 20 20 20 20 20 42 4f 4f 4c 20 62 52 65 73 75 6c BOOL bResul
2f70: 74 20 3d 20 53 65 74 46 69 6c 65 54 69 6d 65 28 t = SetFileTime(
2f80: 68 46 69 6c 65 2c 20 4e 55 4c 4c 2c 20 26 6c 61 hFile, NULL, &la
2f90: 73 74 41 63 63 65 73 73 2c 20 26 6c 61 73 74 57 stAccess, &lastW
2fa0: 72 69 74 65 29 3b 0a 20 20 20 20 20 20 43 6c 6f rite);. Clo
2fb0: 73 65 48 61 6e 64 6c 65 28 68 46 69 6c 65 29 3b seHandle(hFile);
2fc0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 21 62 . return !b
2fd0: 52 65 73 75 6c 74 3b 0a 20 20 20 20 7d 65 6c 73 Result;. }els
2fe0: 65 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 e{. return
2ff0: 31 3b 0a 20 20 20 20 7d 0a 23 65 6c 69 66 20 64 1;. }.#elif d
3000: 65 66 69 6e 65 64 28 41 54 5f 46 44 43 57 44 29 efined(AT_FDCWD)
3010: 20 26 26 20 30 20 2f 2a 20 75 74 69 6d 65 6e 73 && 0 /* utimens
3020: 61 74 28 29 20 69 73 20 6e 6f 74 20 75 6e 69 76 at() is not univ
3030: 65 72 73 61 6c 6c 79 20 61 76 61 69 6c 61 62 6c ersally availabl
3040: 65 20 2a 2f 0a 20 20 20 20 2f 2a 20 52 65 63 65 e */. /* Rece
3050: 6e 74 20 75 6e 69 78 20 2a 2f 0a 20 20 20 20 73 nt unix */. s
3060: 74 72 75 63 74 20 74 69 6d 65 73 70 65 63 20 74 truct timespec t
3070: 69 6d 65 73 5b 32 5d 3b 0a 20 20 20 20 74 69 6d imes[2];. tim
3080: 65 73 5b 30 5d 2e 74 76 5f 6e 73 65 63 20 3d 20 es[0].tv_nsec =
3090: 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 6e 73 65 63 times[1].tv_nsec
30a0: 20 3d 20 30 3b 0a 20 20 20 20 74 69 6d 65 73 5b = 0;. times[
30b0: 30 5d 2e 74 76 5f 73 65 63 20 3d 20 74 69 6d 65 0].tv_sec = time
30c0: 28 30 29 3b 0a 20 20 20 20 74 69 6d 65 73 5b 31 (0);. times[1
30d0: 5d 2e 74 76 5f 73 65 63 20 3d 20 6d 74 69 6d 65 ].tv_sec = mtime
30e0: 3b 0a 20 20 20 20 69 66 28 20 75 74 69 6d 65 6e ;. if( utimen
30f0: 73 61 74 28 41 54 5f 46 44 43 57 44 2c 20 7a 46 sat(AT_FDCWD, zF
3100: 69 6c 65 2c 20 74 69 6d 65 73 2c 20 41 54 5f 53 ile, times, AT_S
3110: 59 4d 4c 49 4e 4b 5f 4e 4f 46 4f 4c 4c 4f 57 29 YMLINK_NOFOLLOW)
3120: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e ){. return
3130: 20 31 3b 0a 20 20 20 20 7d 0a 23 65 6c 73 65 0a 1;. }.#else.
3140: 20 20 20 20 2f 2a 20 4c 65 67 61 63 79 20 75 6e /* Legacy un
3150: 69 78 20 2a 2f 0a 20 20 20 20 73 74 72 75 63 74 ix */. struct
3160: 20 74 69 6d 65 76 61 6c 20 74 69 6d 65 73 5b 32 timeval times[2
3170: 5d 3b 0a 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e ];. times[0].
3180: 74 76 5f 75 73 65 63 20 3d 20 74 69 6d 65 73 5b tv_usec = times[
3190: 31 5d 2e 74 76 5f 75 73 65 63 20 3d 20 30 3b 0a 1].tv_usec = 0;.
31a0: 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e 74 76 5f times[0].tv_
31b0: 73 65 63 20 3d 20 74 69 6d 65 28 30 29 3b 0a 20 sec = time(0);.
31c0: 20 20 20 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 73 times[1].tv_s
31d0: 65 63 20 3d 20 6d 74 69 6d 65 3b 0a 20 20 20 20 ec = mtime;.
31e0: 69 66 28 20 75 74 69 6d 65 73 28 7a 46 69 6c 65 if( utimes(zFile
31f0: 2c 20 74 69 6d 65 73 29 20 29 7b 0a 20 20 20 20 , times) ){.
3200: 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 return 1;.
3210: 7d 0a 23 65 6e 64 69 66 0a 20 20 7d 0a 0a 20 20 }.#endif. }..
3220: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a return 0;.}../*.
3230: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f ** Implementatio
3240: 6e 20 6f 66 20 74 68 65 20 22 77 72 69 74 65 66 n of the "writef
3250: 69 6c 65 28 57 2c 58 5b 2c 59 5b 2c 5a 5d 5d 5d ile(W,X[,Y[,Z]]]
3260: 29 22 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 2e )" SQL function.
3270: 20 20 0a 2a 2a 20 52 65 66 65 72 20 74 6f 20 68 .** Refer to h
3280: 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74 73 20 61 eader comments a
3290: 74 20 74 68 65 20 74 6f 70 20 6f 66 20 74 68 69 t the top of thi
32a0: 73 20 66 69 6c 65 20 66 6f 72 20 64 65 74 61 69 s file for detai
32b0: 6c 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f ls..*/.static vo
32c0: 69 64 20 77 72 69 74 65 66 69 6c 65 46 75 6e 63 id writefileFunc
32d0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 (. sqlite3_cont
32e0: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 ext *context,.
32f0: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 int argc,. sqli
3300: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 te3_value **argv
3310: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 .){. const char
3320: 20 2a 7a 46 69 6c 65 3b 0a 20 20 6d 6f 64 65 5f *zFile;. mode_
3330: 74 20 6d 6f 64 65 20 3d 20 30 3b 0a 20 20 69 6e t mode = 0;. in
3340: 74 20 72 65 73 3b 0a 20 20 73 71 6c 69 74 65 33 t res;. sqlite3
3350: 5f 69 6e 74 36 34 20 6d 74 69 6d 65 20 3d 20 2d _int64 mtime = -
3360: 31 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 3c 32 1;.. if( argc<2
3370: 20 7c 7c 20 61 72 67 63 3e 34 20 29 7b 0a 20 20 || argc>4 ){.
3380: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 sqlite3_result
3390: 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c 20 _error(context,
33a0: 0a 20 20 20 20 20 20 20 20 22 77 72 6f 6e 67 20 . "wrong
33b0: 6e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 number of argume
33c0: 6e 74 73 20 74 6f 20 66 75 6e 63 74 69 6f 6e 20 nts to function
33d0: 77 72 69 74 65 66 69 6c 65 28 29 22 2c 20 2d 31 writefile()", -1
33e0: 0a 20 20 20 20 29 3b 0a 20 20 20 20 72 65 74 75 . );. retu
33f0: 72 6e 3b 0a 20 20 7d 0a 0a 20 20 7a 46 69 6c 65 rn;. }.. zFile
3400: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 = (const char*)
3410: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 sqlite3_value_te
3420: 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 69 xt(argv[0]);. i
3430: 66 28 20 7a 46 69 6c 65 3d 3d 30 20 29 20 72 65 f( zFile==0 ) re
3440: 74 75 72 6e 3b 0a 20 20 69 66 28 20 61 72 67 63 turn;. if( argc
3450: 3e 3d 33 20 29 7b 0a 20 20 20 20 6d 6f 64 65 20 >=3 ){. mode
3460: 3d 20 28 6d 6f 64 65 5f 74 29 73 71 6c 69 74 65 = (mode_t)sqlite
3470: 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 3_value_int(argv
3480: 5b 32 5d 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 [2]);. }. if(
3490: 61 72 67 63 3d 3d 34 20 29 7b 0a 20 20 20 20 6d argc==4 ){. m
34a0: 74 69 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 76 time = sqlite3_v
34b0: 61 6c 75 65 5f 69 6e 74 36 34 28 61 72 67 76 5b alue_int64(argv[
34c0: 33 5d 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 73 20 3]);. }.. res
34d0: 3d 20 77 72 69 74 65 46 69 6c 65 28 63 6f 6e 74 = writeFile(cont
34e0: 65 78 74 2c 20 7a 46 69 6c 65 2c 20 61 72 67 76 ext, zFile, argv
34f0: 5b 31 5d 2c 20 6d 6f 64 65 2c 20 6d 74 69 6d 65 [1], mode, mtime
3500: 29 3b 0a 20 20 69 66 28 20 72 65 73 3d 3d 31 20 );. if( res==1
3510: 26 26 20 65 72 72 6e 6f 3d 3d 45 4e 4f 45 4e 54 && errno==ENOENT
3520: 20 29 7b 0a 20 20 20 20 69 66 28 20 6d 61 6b 65 ){. if( make
3530: 44 69 72 65 63 74 6f 72 79 28 7a 46 69 6c 65 2c Directory(zFile,
3540: 20 6d 6f 64 65 29 3d 3d 53 51 4c 49 54 45 5f 4f mode)==SQLITE_O
3550: 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 73 20 3d K ){. res =
3560: 20 77 72 69 74 65 46 69 6c 65 28 63 6f 6e 74 65 writeFile(conte
3570: 78 74 2c 20 7a 46 69 6c 65 2c 20 61 72 67 76 5b xt, zFile, argv[
3580: 31 5d 2c 20 6d 6f 64 65 2c 20 6d 74 69 6d 65 29 1], mode, mtime)
3590: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 ;. }. }.. i
35a0: 66 28 20 61 72 67 63 3e 32 20 26 26 20 72 65 73 f( argc>2 && res
35b0: 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 53 !=0 ){. if( S
35c0: 5f 49 53 4c 4e 4b 28 6d 6f 64 65 29 20 29 7b 0a _ISLNK(mode) ){.
35d0: 20 20 20 20 20 20 63 74 78 45 72 72 6f 72 4d 73 ctxErrorMs
35e0: 67 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c g(context, "fail
35f0: 65 64 20 74 6f 20 63 72 65 61 74 65 20 73 79 6d ed to create sym
3600: 6c 69 6e 6b 3a 20 25 73 22 2c 20 7a 46 69 6c 65 link: %s", zFile
3610: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 );. }else if(
3620: 20 53 5f 49 53 44 49 52 28 6d 6f 64 65 29 20 29 S_ISDIR(mode) )
3630: 7b 0a 20 20 20 20 20 20 63 74 78 45 72 72 6f 72 {. ctxError
3640: 4d 73 67 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 Msg(context, "fa
3650: 69 6c 65 64 20 74 6f 20 63 72 65 61 74 65 20 64 iled to create d
3660: 69 72 65 63 74 6f 72 79 3a 20 25 73 22 2c 20 7a irectory: %s", z
3670: 46 69 6c 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 File);. }else
3680: 7b 0a 20 20 20 20 20 20 63 74 78 45 72 72 6f 72 {. ctxError
3690: 4d 73 67 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 Msg(context, "fa
36a0: 69 6c 65 64 20 74 6f 20 77 72 69 74 65 20 66 69 iled to write fi
36b0: 6c 65 3a 20 25 73 22 2c 20 7a 46 69 6c 65 29 3b le: %s", zFile);
36c0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a . }. }.}../*
36d0: 0a 2a 2a 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e .** SQL function
36e0: 3a 20 20 20 6c 73 6d 6f 64 65 28 4d 4f 44 45 29 : lsmode(MODE)
36f0: 0a 2a 2a 0a 2a 2a 20 47 69 76 65 6e 20 61 20 6e .**.** Given a n
3700: 75 6d 62 65 72 69 63 20 73 74 5f 6d 6f 64 65 20 umberic st_mode
3710: 66 72 6f 6d 20 73 74 61 74 28 29 2c 20 63 6f 6e from stat(), con
3720: 76 65 72 74 20 69 74 20 69 6e 74 6f 20 61 20 68 vert it into a h
3730: 75 6d 61 6e 2d 72 65 61 64 61 62 6c 65 0a 2a 2a uman-readable.**
3740: 20 74 65 78 74 20 73 74 72 69 6e 67 20 69 6e 20 text string in
3750: 74 68 65 20 73 74 79 6c 65 20 6f 66 20 22 6c 73 the style of "ls
3760: 20 2d 6c 22 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 -l"..*/.static
3770: 76 6f 69 64 20 6c 73 4d 6f 64 65 46 75 6e 63 28 void lsModeFunc(
3780: 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 . sqlite3_conte
3790: 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 xt *context,. i
37a0: 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 nt argc,. sqlit
37b0: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a e3_value **argv.
37c0: 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e ){. int i;. in
37d0: 74 20 69 4d 6f 64 65 20 3d 20 73 71 6c 69 74 65 t iMode = sqlite
37e0: 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 3_value_int(argv
37f0: 5b 30 5d 29 3b 0a 20 20 63 68 61 72 20 7a 5b 31 [0]);. char z[1
3800: 36 5d 3b 0a 20 20 28 76 6f 69 64 29 61 72 67 63 6];. (void)argc
3810: 3b 0a 20 20 69 66 28 20 53 5f 49 53 4c 4e 4b 28 ;. if( S_ISLNK(
3820: 69 4d 6f 64 65 29 20 29 7b 0a 20 20 20 20 7a 5b iMode) ){. z[
3830: 30 5d 20 3d 20 27 6c 27 3b 0a 20 20 7d 65 6c 73 0] = 'l';. }els
3840: 65 20 69 66 28 20 53 5f 49 53 52 45 47 28 69 4d e if( S_ISREG(iM
3850: 6f 64 65 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d ode) ){. z[0]
3860: 20 3d 20 27 2d 27 3b 0a 20 20 7d 65 6c 73 65 20 = '-';. }else
3870: 69 66 28 20 53 5f 49 53 44 49 52 28 69 4d 6f 64 if( S_ISDIR(iMod
3880: 65 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d 20 3d e) ){. z[0] =
3890: 20 27 64 27 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 'd';. }else{.
38a0: 20 20 20 7a 5b 30 5d 20 3d 20 27 3f 27 3b 0a 20 z[0] = '?';.
38b0: 20 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c }. for(i=0; i<
38c0: 33 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 3; i++){. int
38d0: 20 6d 20 3d 20 28 69 4d 6f 64 65 20 3e 3e 20 28 m = (iMode >> (
38e0: 28 32 2d 69 29 2a 33 29 29 3b 0a 20 20 20 20 63 (2-i)*3));. c
38f0: 68 61 72 20 2a 61 20 3d 20 26 7a 5b 31 20 2b 20 har *a = &z[1 +
3900: 69 2a 33 5d 3b 0a 20 20 20 20 61 5b 30 5d 20 3d i*3];. a[0] =
3910: 20 28 6d 20 26 20 30 78 34 29 20 3f 20 27 72 27 (m & 0x4) ? 'r'
3920: 20 3a 20 27 2d 27 3b 0a 20 20 20 20 61 5b 31 5d : '-';. a[1]
3930: 20 3d 20 28 6d 20 26 20 30 78 32 29 20 3f 20 27 = (m & 0x2) ? '
3940: 77 27 20 3a 20 27 2d 27 3b 0a 20 20 20 20 61 5b w' : '-';. a[
3950: 32 5d 20 3d 20 28 6d 20 26 20 30 78 31 29 20 3f 2] = (m & 0x1) ?
3960: 20 27 78 27 20 3a 20 27 2d 27 3b 0a 20 20 7d 0a 'x' : '-';. }.
3970: 20 20 7a 5b 31 30 5d 20 3d 20 27 5c 30 27 3b 0a z[10] = '\0';.
3980: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 sqlite3_result
3990: 5f 74 65 78 74 28 63 6f 6e 74 65 78 74 2c 20 7a _text(context, z
39a0: 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 , -1, SQLITE_TRA
39b0: 4e 53 49 45 4e 54 29 3b 0a 7d 0a 0a 23 69 66 6e NSIENT);.}..#ifn
39c0: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f def SQLITE_OMIT_
39d0: 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 0a 2f 2a VIRTUALTABLE../*
39e0: 20 0a 2a 2a 20 43 75 72 73 6f 72 20 74 79 70 65 .** Cursor type
39f0: 20 66 6f 72 20 72 65 63 75 72 73 69 76 65 6c 79 for recursively
3a00: 20 69 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75 iterating throu
3a10: 67 68 20 61 20 64 69 72 65 63 74 6f 72 79 20 73 gh a directory s
3a20: 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 tructure..*/.typ
3a30: 65 64 65 66 20 73 74 72 75 63 74 20 66 73 64 69 edef struct fsdi
3a40: 72 5f 63 75 72 73 6f 72 20 66 73 64 69 72 5f 63 r_cursor fsdir_c
3a50: 75 72 73 6f 72 3b 0a 74 79 70 65 64 65 66 20 73 ursor;.typedef s
3a60: 74 72 75 63 74 20 46 73 64 69 72 4c 65 76 65 6c truct FsdirLevel
3a70: 20 46 73 64 69 72 4c 65 76 65 6c 3b 0a 0a 73 74 FsdirLevel;..st
3a80: 72 75 63 74 20 46 73 64 69 72 4c 65 76 65 6c 20 ruct FsdirLevel
3a90: 7b 0a 20 20 44 49 52 20 2a 70 44 69 72 3b 20 20 {. DIR *pDir;
3aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
3ab0: 2a 20 46 72 6f 6d 20 6f 70 65 6e 64 69 72 28 29 * From opendir()
3ac0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 44 69 72 */. char *zDir
3ad0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ;
3ae0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 64 69 72 65 /* Name of dire
3af0: 63 74 6f 72 79 20 28 6e 75 6c 2d 74 65 72 6d 69 ctory (nul-termi
3b00: 6e 61 74 65 64 29 20 2a 2f 0a 7d 3b 0a 0a 73 74 nated) */.};..st
3b10: 72 75 63 74 20 66 73 64 69 72 5f 63 75 72 73 6f ruct fsdir_curso
3b20: 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 r {. sqlite3_vt
3b30: 61 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 20 ab_cursor base;
3b40: 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d /* Base class -
3b50: 20 6d 75 73 74 20 62 65 20 66 69 72 73 74 20 2a must be first *
3b60: 2f 0a 0a 20 20 69 6e 74 20 6e 4c 76 6c 3b 20 20 /.. int nLvl;
3b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
3b80: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 /* Number of ent
3b90: 72 69 65 73 20 69 6e 20 61 4c 76 6c 5b 5d 20 61 ries in aLvl[] a
3ba0: 72 72 61 79 20 2a 2f 0a 20 20 69 6e 74 20 69 4c rray */. int iL
3bb0: 76 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 vl;
3bc0: 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 /* Index of
3bd0: 20 63 75 72 72 65 6e 74 20 65 6e 74 72 79 20 2a current entry *
3be0: 2f 0a 20 20 46 73 64 69 72 4c 65 76 65 6c 20 2a /. FsdirLevel *
3bf0: 61 4c 76 6c 3b 20 20 20 20 20 20 20 20 20 20 2f aLvl; /
3c00: 2a 20 48 69 65 72 61 72 63 68 79 20 6f 66 20 64 * Hierarchy of d
3c10: 69 72 65 63 74 6f 72 69 65 73 20 62 65 69 6e 67 irectories being
3c20: 20 74 72 61 76 65 72 73 65 64 20 2a 2f 0a 0a 20 traversed */..
3c30: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 42 61 const char *zBa
3c40: 73 65 3b 0a 20 20 69 6e 74 20 6e 42 61 73 65 3b se;. int nBase;
3c50: 0a 0a 20 20 73 74 72 75 63 74 20 73 74 61 74 20 .. struct stat
3c60: 73 53 74 61 74 3b 20 20 20 20 20 20 20 20 20 2f sStat; /
3c70: 2a 20 43 75 72 72 65 6e 74 20 6c 73 74 61 74 28 * Current lstat(
3c80: 29 20 72 65 73 75 6c 74 73 20 2a 2f 0a 20 20 63 ) results */. c
3c90: 68 61 72 20 2a 7a 50 61 74 68 3b 20 20 20 20 20 har *zPath;
3ca0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 74 /* Pat
3cb0: 68 20 74 6f 20 63 75 72 72 65 6e 74 20 65 6e 74 h to current ent
3cc0: 72 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f ry */. sqlite3_
3cd0: 69 6e 74 36 34 20 69 52 6f 77 69 64 3b 20 20 20 int64 iRowid;
3ce0: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 6f /* Current ro
3cf0: 77 69 64 20 2a 2f 0a 7d 3b 0a 0a 74 79 70 65 64 wid */.};..typed
3d00: 65 66 20 73 74 72 75 63 74 20 66 73 64 69 72 5f ef struct fsdir_
3d10: 74 61 62 20 66 73 64 69 72 5f 74 61 62 3b 0a 73 tab fsdir_tab;.s
3d20: 74 72 75 63 74 20 66 73 64 69 72 5f 74 61 62 20 truct fsdir_tab
3d30: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 {. sqlite3_vtab
3d40: 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 2f base; /
3d50: 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d * Base class - m
3d60: 75 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a ust be first */.
3d70: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 };../*.** Constr
3d80: 75 63 74 20 61 20 6e 65 77 20 66 73 64 69 72 20 uct a new fsdir
3d90: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6f 62 virtual table ob
3da0: 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 ject..*/.static
3db0: 69 6e 74 20 66 73 64 69 72 43 6f 6e 6e 65 63 74 int fsdirConnect
3dc0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c (. sqlite3 *db,
3dd0: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 . void *pAux,.
3de0: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 int argc, const
3df0: 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 char *const*arg
3e00: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 v,. sqlite3_vta
3e10: 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 b **ppVtab,. ch
3e20: 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 ar **pzErr.){.
3e30: 66 73 64 69 72 5f 74 61 62 20 2a 70 4e 65 77 20 fsdir_tab *pNew
3e40: 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 = 0;. int rc;.
3e50: 20 28 76 6f 69 64 29 70 41 75 78 3b 0a 20 20 28 (void)pAux;. (
3e60: 76 6f 69 64 29 61 72 67 63 3b 0a 20 20 28 76 6f void)argc;. (vo
3e70: 69 64 29 61 72 67 76 3b 0a 20 20 28 76 6f 69 64 id)argv;. (void
3e80: 29 70 7a 45 72 72 3b 0a 20 20 72 63 20 3d 20 73 )pzErr;. rc = s
3e90: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 qlite3_declare_v
3ea0: 74 61 62 28 64 62 2c 20 22 43 52 45 41 54 45 20 tab(db, "CREATE
3eb0: 54 41 42 4c 45 20 78 22 20 46 53 44 49 52 5f 53 TABLE x" FSDIR_S
3ec0: 43 48 45 4d 41 29 3b 0a 20 20 69 66 28 20 72 63 CHEMA);. if( rc
3ed0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 ==SQLITE_OK ){.
3ee0: 20 20 20 70 4e 65 77 20 3d 20 28 66 73 64 69 72 pNew = (fsdir
3ef0: 5f 74 61 62 2a 29 73 71 6c 69 74 65 33 5f 6d 61 _tab*)sqlite3_ma
3f00: 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 4e lloc( sizeof(*pN
3f10: 65 77 29 20 29 3b 0a 20 20 20 20 69 66 28 20 70 ew) );. if( p
3f20: 4e 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 New==0 ) return
3f30: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 SQLITE_NOMEM;.
3f40: 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 memset(pNew, 0
3f50: 2c 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29 29 , sizeof(*pNew))
3f60: 3b 0a 20 20 7d 0a 20 20 2a 70 70 56 74 61 62 20 ;. }. *ppVtab
3f70: 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 2a = (sqlite3_vtab*
3f80: 29 70 4e 65 77 3b 0a 20 20 72 65 74 75 72 6e 20 )pNew;. return
3f90: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 rc;.}../*.** Thi
3fa0: 73 20 6d 65 74 68 6f 64 20 69 73 20 74 68 65 20 s method is the
3fb0: 64 65 73 74 72 75 63 74 6f 72 20 66 6f 72 20 66 destructor for f
3fc0: 73 64 69 72 20 76 74 61 62 20 6f 62 6a 65 63 74 sdir vtab object
3fd0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 s..*/.static int
3fe0: 20 66 73 64 69 72 44 69 73 63 6f 6e 6e 65 63 74 fsdirDisconnect
3ff0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 (sqlite3_vtab *p
4000: 56 74 61 62 29 7b 0a 20 20 73 71 6c 69 74 65 33 Vtab){. sqlite3
4010: 5f 66 72 65 65 28 70 56 74 61 62 29 3b 0a 20 20 _free(pVtab);.
4020: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b return SQLITE_OK
4030: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 ;.}../*.** Const
4040: 72 75 63 74 6f 72 20 66 6f 72 20 61 20 6e 65 77 ructor for a new
4050: 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 6f 62 fsdir_cursor ob
4060: 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 ject..*/.static
4070: 69 6e 74 20 66 73 64 69 72 4f 70 65 6e 28 73 71 int fsdirOpen(sq
4080: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 2c 20 73 lite3_vtab *p, s
4090: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 qlite3_vtab_curs
40a0: 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a or **ppCursor){.
40b0: 20 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a fsdir_cursor *
40c0: 70 43 75 72 3b 0a 20 20 28 76 6f 69 64 29 70 3b pCur;. (void)p;
40d0: 0a 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 . pCur = sqlite
40e0: 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 3_malloc( sizeof
40f0: 28 2a 70 43 75 72 29 20 29 3b 0a 20 20 69 66 28 (*pCur) );. if(
4100: 20 70 43 75 72 3d 3d 30 20 29 20 72 65 74 75 72 pCur==0 ) retur
4110: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a n SQLITE_NOMEM;.
4120: 20 20 6d 65 6d 73 65 74 28 70 43 75 72 2c 20 30 memset(pCur, 0
4130: 2c 20 73 69 7a 65 6f 66 28 2a 70 43 75 72 29 29 , sizeof(*pCur))
4140: 3b 0a 20 20 70 43 75 72 2d 3e 69 4c 76 6c 20 3d ;. pCur->iLvl =
4150: 20 2d 31 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 -1;. *ppCursor
4160: 20 3d 20 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a = &pCur->base;.
4170: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f return SQLITE_
4180: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 OK;.}../*.** Res
4190: 65 74 20 61 20 63 75 72 73 6f 72 20 62 61 63 6b et a cursor back
41a0: 20 74 6f 20 74 68 65 20 73 74 61 74 65 20 69 74 to the state it
41b0: 20 77 61 73 20 69 6e 20 77 68 65 6e 20 66 69 72 was in when fir
41c0: 73 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 62 st returned.** b
41d0: 79 20 66 73 64 69 72 4f 70 65 6e 28 29 2e 0a 2a y fsdirOpen()..*
41e0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 73 /.static void fs
41f0: 64 69 72 52 65 73 65 74 43 75 72 73 6f 72 28 66 dirResetCursor(f
4200: 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 sdir_cursor *pCu
4210: 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 r){. int i;. f
4220: 6f 72 28 69 3d 30 3b 20 69 3c 3d 70 43 75 72 2d or(i=0; i<=pCur-
4230: 3e 69 4c 76 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 >iLvl; i++){.
4240: 20 46 73 64 69 72 4c 65 76 65 6c 20 2a 70 4c 76 FsdirLevel *pLv
4250: 6c 20 3d 20 26 70 43 75 72 2d 3e 61 4c 76 6c 5b l = &pCur->aLvl[
4260: 69 5d 3b 0a 20 20 20 20 69 66 28 20 70 4c 76 6c i];. if( pLvl
4270: 2d 3e 70 44 69 72 20 29 20 63 6c 6f 73 65 64 69 ->pDir ) closedi
4280: 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 3b 0a 20 r(pLvl->pDir);.
4290: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 sqlite3_free(
42a0: 70 4c 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20 7d pLvl->zDir);. }
42b0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 . sqlite3_free(
42c0: 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 pCur->zPath);.
42d0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75 sqlite3_free(pCu
42e0: 72 2d 3e 61 4c 76 6c 29 3b 0a 20 20 70 43 75 72 r->aLvl);. pCur
42f0: 2d 3e 61 4c 76 6c 20 3d 20 30 3b 0a 20 20 70 43 ->aLvl = 0;. pC
4300: 75 72 2d 3e 7a 50 61 74 68 20 3d 20 30 3b 0a 20 ur->zPath = 0;.
4310: 20 70 43 75 72 2d 3e 7a 42 61 73 65 20 3d 20 30 pCur->zBase = 0
4320: 3b 0a 20 20 70 43 75 72 2d 3e 6e 42 61 73 65 20 ;. pCur->nBase
4330: 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e 6e 4c 76 = 0;. pCur->nLv
4340: 6c 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e 69 l = 0;. pCur->i
4350: 4c 76 6c 20 3d 20 2d 31 3b 0a 20 20 70 43 75 72 Lvl = -1;. pCur
4360: 2d 3e 69 52 6f 77 69 64 20 3d 20 31 3b 0a 7d 0a ->iRowid = 1;.}.
4370: 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72 75 63 74 6f ./*.** Destructo
4380: 72 20 66 6f 72 20 61 6e 20 66 73 64 69 72 5f 63 r for an fsdir_c
4390: 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 ursor..*/.static
43a0: 20 69 6e 74 20 66 73 64 69 72 43 6c 6f 73 65 28 int fsdirClose(
43b0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 sqlite3_vtab_cur
43c0: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 sor *cur){. fsd
43d0: 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 ir_cursor *pCur
43e0: 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a = (fsdir_cursor*
43f0: 29 63 75 72 3b 0a 0a 20 20 66 73 64 69 72 52 65 )cur;.. fsdirRe
4400: 73 65 74 43 75 72 73 6f 72 28 70 43 75 72 29 3b setCursor(pCur);
4410: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 . sqlite3_free(
4420: 70 43 75 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 pCur);. return
4430: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a SQLITE_OK;.}../*
4440: 0a 2a 2a 20 53 65 74 20 74 68 65 20 65 72 72 6f .** Set the erro
4450: 72 20 6d 65 73 73 61 67 65 20 66 6f 72 20 74 68 r message for th
4460: 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 e virtual table
4470: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 associated with
4480: 63 75 72 73 6f 72 0a 2a 2a 20 70 43 75 72 20 74 cursor.** pCur t
4490: 6f 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 o the results of
44a0: 20 76 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20 2e vprintf(zFmt, .
44b0: 2e 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 ..)..*/.static v
44c0: 6f 69 64 20 66 73 64 69 72 53 65 74 45 72 72 6d oid fsdirSetErrm
44d0: 73 67 28 66 73 64 69 72 5f 63 75 72 73 6f 72 20 sg(fsdir_cursor
44e0: 2a 70 43 75 72 2c 20 63 6f 6e 73 74 20 63 68 61 *pCur, const cha
44f0: 72 20 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a 20 r *zFmt, ...){.
4500: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 va_list ap;. v
4510: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6d 74 a_start(ap, zFmt
4520: 29 3b 0a 20 20 70 43 75 72 2d 3e 62 61 73 65 2e );. pCur->base.
4530: 70 56 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d pVtab->zErrMsg =
4540: 20 73 71 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 sqlite3_vmprint
4550: 66 28 7a 46 6d 74 2c 20 61 70 29 3b 0a 20 20 76 f(zFmt, ap);. v
4560: 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 0a 2f a_end(ap);.}.../
4570: 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 61 6e 20 *.** Advance an
4580: 66 73 64 69 72 5f 63 75 72 73 6f 72 20 74 6f 20 fsdir_cursor to
4590: 69 74 73 20 6e 65 78 74 20 72 6f 77 20 6f 66 20 its next row of
45a0: 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 output..*/.stati
45b0: 63 20 69 6e 74 20 66 73 64 69 72 4e 65 78 74 28 c int fsdirNext(
45c0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 sqlite3_vtab_cur
45d0: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 sor *cur){. fsd
45e0: 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 ir_cursor *pCur
45f0: 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a = (fsdir_cursor*
4600: 29 63 75 72 3b 0a 20 20 6d 6f 64 65 5f 74 20 6d )cur;. mode_t m
4610: 20 3d 20 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 = pCur->sStat.s
4620: 74 5f 6d 6f 64 65 3b 0a 0a 20 20 70 43 75 72 2d t_mode;.. pCur-
4630: 3e 69 52 6f 77 69 64 2b 2b 3b 0a 20 20 69 66 28 >iRowid++;. if(
4640: 20 53 5f 49 53 44 49 52 28 6d 29 20 29 7b 0a 20 S_ISDIR(m) ){.
4650: 20 20 20 2f 2a 20 44 65 73 63 65 6e 64 20 69 6e /* Descend in
4660: 74 6f 20 74 68 69 73 20 64 69 72 65 63 74 6f 72 to this director
4670: 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4e 65 y */. int iNe
4680: 77 20 3d 20 70 43 75 72 2d 3e 69 4c 76 6c 20 2b w = pCur->iLvl +
4690: 20 31 3b 0a 20 20 20 20 46 73 64 69 72 4c 65 76 1;. FsdirLev
46a0: 65 6c 20 2a 70 4c 76 6c 3b 0a 20 20 20 20 69 66 el *pLvl;. if
46b0: 28 20 69 4e 65 77 3e 3d 70 43 75 72 2d 3e 6e 4c ( iNew>=pCur->nL
46c0: 76 6c 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 vl ){. int
46d0: 6e 4e 65 77 20 3d 20 69 4e 65 77 2b 31 3b 0a 20 nNew = iNew+1;.
46e0: 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20 3d int nByte =
46f0: 20 6e 4e 65 77 2a 73 69 7a 65 6f 66 28 46 73 64 nNew*sizeof(Fsd
4700: 69 72 4c 65 76 65 6c 29 3b 0a 20 20 20 20 20 20 irLevel);.
4710: 46 73 64 69 72 4c 65 76 65 6c 20 2a 61 4e 65 77 FsdirLevel *aNew
4720: 20 3d 20 28 46 73 64 69 72 4c 65 76 65 6c 2a 29 = (FsdirLevel*)
4730: 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 sqlite3_realloc(
4740: 70 43 75 72 2d 3e 61 4c 76 6c 2c 20 6e 42 79 74 pCur->aLvl, nByt
4750: 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 61 4e e);. if( aN
4760: 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 ew==0 ) return S
4770: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 QLITE_NOMEM;.
4780: 20 20 20 6d 65 6d 73 65 74 28 26 61 4e 65 77 5b memset(&aNew[
4790: 70 43 75 72 2d 3e 6e 4c 76 6c 5d 2c 20 30 2c 20 pCur->nLvl], 0,
47a0: 73 69 7a 65 6f 66 28 46 73 64 69 72 4c 65 76 65 sizeof(FsdirLeve
47b0: 6c 29 2a 28 6e 4e 65 77 2d 70 43 75 72 2d 3e 6e l)*(nNew-pCur->n
47c0: 4c 76 6c 29 29 3b 0a 20 20 20 20 20 20 70 43 75 Lvl));. pCu
47d0: 72 2d 3e 61 4c 76 6c 20 3d 20 61 4e 65 77 3b 0a r->aLvl = aNew;.
47e0: 20 20 20 20 20 20 70 43 75 72 2d 3e 6e 4c 76 6c pCur->nLvl
47f0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 20 = nNew;. }.
4800: 20 20 20 70 43 75 72 2d 3e 69 4c 76 6c 20 3d 20 pCur->iLvl =
4810: 69 4e 65 77 3b 0a 20 20 20 20 70 4c 76 6c 20 3d iNew;. pLvl =
4820: 20 26 70 43 75 72 2d 3e 61 4c 76 6c 5b 69 4e 65 &pCur->aLvl[iNe
4830: 77 5d 3b 0a 20 20 20 20 0a 20 20 20 20 70 4c 76 w];. . pLv
4840: 6c 2d 3e 7a 44 69 72 20 3d 20 70 43 75 72 2d 3e l->zDir = pCur->
4850: 7a 50 61 74 68 3b 0a 20 20 20 20 70 43 75 72 2d zPath;. pCur-
4860: 3e 7a 50 61 74 68 20 3d 20 30 3b 0a 20 20 20 20 >zPath = 0;.
4870: 70 4c 76 6c 2d 3e 70 44 69 72 20 3d 20 6f 70 65 pLvl->pDir = ope
4880: 6e 64 69 72 28 70 4c 76 6c 2d 3e 7a 44 69 72 29 ndir(pLvl->zDir)
4890: 3b 0a 20 20 20 20 69 66 28 20 70 4c 76 6c 2d 3e ;. if( pLvl->
48a0: 70 44 69 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20 pDir==0 ){.
48b0: 20 66 73 64 69 72 53 65 74 45 72 72 6d 73 67 28 fsdirSetErrmsg(
48c0: 70 43 75 72 2c 20 22 63 61 6e 6e 6f 74 20 72 65 pCur, "cannot re
48d0: 61 64 20 64 69 72 65 63 74 6f 72 79 3a 20 25 73 ad directory: %s
48e0: 22 2c 20 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b ", pCur->zPath);
48f0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 . return SQ
4900: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 LITE_ERROR;.
4910: 7d 0a 20 20 7d 0a 0a 20 20 77 68 69 6c 65 28 20 }. }.. while(
4920: 70 43 75 72 2d 3e 69 4c 76 6c 3e 3d 30 20 29 7b pCur->iLvl>=0 ){
4930: 0a 20 20 20 20 46 73 64 69 72 4c 65 76 65 6c 20 . FsdirLevel
4940: 2a 70 4c 76 6c 20 3d 20 26 70 43 75 72 2d 3e 61 *pLvl = &pCur->a
4950: 4c 76 6c 5b 70 43 75 72 2d 3e 69 4c 76 6c 5d 3b Lvl[pCur->iLvl];
4960: 0a 20 20 20 20 73 74 72 75 63 74 20 64 69 72 65 . struct dire
4970: 6e 74 20 2a 70 45 6e 74 72 79 20 3d 20 72 65 61 nt *pEntry = rea
4980: 64 64 69 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 ddir(pLvl->pDir)
4990: 3b 0a 20 20 20 20 69 66 28 20 70 45 6e 74 72 79 ;. if( pEntry
49a0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 45 ){. if( pE
49b0: 6e 74 72 79 2d 3e 64 5f 6e 61 6d 65 5b 30 5d 3d ntry->d_name[0]=
49c0: 3d 27 2e 27 20 29 7b 0a 20 20 20 20 20 20 20 69 ='.' ){. i
49d0: 66 28 20 70 45 6e 74 72 79 2d 3e 64 5f 6e 61 6d f( pEntry->d_nam
49e0: 65 5b 31 5d 3d 3d 27 2e 27 20 26 26 20 70 45 6e e[1]=='.' && pEn
49f0: 74 72 79 2d 3e 64 5f 6e 61 6d 65 5b 32 5d 3d 3d try->d_name[2]==
4a00: 27 5c 30 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b '\0' ) continue;
4a10: 0a 20 20 20 20 20 20 20 69 66 28 20 70 45 6e 74 . if( pEnt
4a20: 72 79 2d 3e 64 5f 6e 61 6d 65 5b 31 5d 3d 3d 27 ry->d_name[1]=='
4a30: 5c 30 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a \0' ) continue;.
4a40: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 71 }. sq
4a50: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d lite3_free(pCur-
4a60: 3e 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 20 70 >zPath);. p
4a70: 43 75 72 2d 3e 7a 50 61 74 68 20 3d 20 73 71 6c Cur->zPath = sql
4a80: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 ite3_mprintf("%s
4a90: 2f 25 73 22 2c 20 70 4c 76 6c 2d 3e 7a 44 69 72 /%s", pLvl->zDir
4aa0: 2c 20 70 45 6e 74 72 79 2d 3e 64 5f 6e 61 6d 65 , pEntry->d_name
4ab0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 43 75 );. if( pCu
4ac0: 72 2d 3e 7a 50 61 74 68 3d 3d 30 20 29 20 72 65 r->zPath==0 ) re
4ad0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 turn SQLITE_NOME
4ae0: 4d 3b 0a 20 20 20 20 20 20 69 66 28 20 66 69 6c M;. if( fil
4af0: 65 4c 69 6e 6b 53 74 61 74 28 70 43 75 72 2d 3e eLinkStat(pCur->
4b00: 7a 50 61 74 68 2c 20 26 70 43 75 72 2d 3e 73 53 zPath, &pCur->sS
4b10: 74 61 74 29 20 29 7b 0a 20 20 20 20 20 20 20 20 tat) ){.
4b20: 66 73 64 69 72 53 65 74 45 72 72 6d 73 67 28 70 fsdirSetErrmsg(p
4b30: 43 75 72 2c 20 22 63 61 6e 6e 6f 74 20 73 74 61 Cur, "cannot sta
4b40: 74 20 66 69 6c 65 3a 20 25 73 22 2c 20 70 43 75 t file: %s", pCu
4b50: 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 r->zPath);.
4b60: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 return SQLITE
4b70: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a _ERROR;. }.
4b80: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c return SQL
4b90: 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 ITE_OK;. }.
4ba0: 20 20 63 6c 6f 73 65 64 69 72 28 70 4c 76 6c 2d closedir(pLvl-
4bb0: 3e 70 44 69 72 29 3b 0a 20 20 20 20 73 71 6c 69 >pDir);. sqli
4bc0: 74 65 33 5f 66 72 65 65 28 70 4c 76 6c 2d 3e 7a te3_free(pLvl->z
4bd0: 44 69 72 29 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e Dir);. pLvl->
4be0: 70 44 69 72 20 3d 20 30 3b 0a 20 20 20 20 70 4c pDir = 0;. pL
4bf0: 76 6c 2d 3e 7a 44 69 72 20 3d 20 30 3b 0a 20 20 vl->zDir = 0;.
4c00: 20 20 70 43 75 72 2d 3e 69 4c 76 6c 2d 2d 3b 0a pCur->iLvl--;.
4c10: 20 20 7d 0a 0a 20 20 2f 2a 20 45 4f 46 20 2a 2f }.. /* EOF */
4c20: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 . sqlite3_free(
4c30: 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 pCur->zPath);.
4c40: 70 43 75 72 2d 3e 7a 50 61 74 68 20 3d 20 30 3b pCur->zPath = 0;
4c50: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 . return SQLITE
4c60: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 _OK;.}../*.** Re
4c70: 74 75 72 6e 20 76 61 6c 75 65 73 20 6f 66 20 63 turn values of c
4c80: 6f 6c 75 6d 6e 73 20 66 6f 72 20 74 68 65 20 72 olumns for the r
4c90: 6f 77 20 61 74 20 77 68 69 63 68 20 74 68 65 20 ow at which the
4ca0: 73 65 72 69 65 73 5f 63 75 72 73 6f 72 0a 2a 2a series_cursor.**
4cb0: 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 70 6f is currently po
4cc0: 69 6e 74 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 inting..*/.stati
4cd0: 63 20 69 6e 74 20 66 73 64 69 72 43 6f 6c 75 6d c int fsdirColum
4ce0: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 n(. sqlite3_vta
4cf0: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 20 b_cursor *cur,
4d00: 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72 20 2a /* The cursor *
4d10: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 /. sqlite3_cont
4d20: 65 78 74 20 2a 63 74 78 2c 20 20 20 20 20 20 20 ext *ctx,
4d30: 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e /* First argumen
4d40: 74 20 74 6f 20 73 71 6c 69 74 65 33 5f 72 65 73 t to sqlite3_res
4d50: 75 6c 74 5f 2e 2e 2e 28 29 20 2a 2f 0a 20 20 69 ult_...() */. i
4d60: 6e 74 20 69 20 20 20 20 20 20 20 20 20 20 20 20 nt i
4d70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 68 /* Wh
4d80: 69 63 68 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 ich column to re
4d90: 74 75 72 6e 20 2a 2f 0a 29 7b 0a 20 20 66 73 64 turn */.){. fsd
4da0: 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 ir_cursor *pCur
4db0: 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a = (fsdir_cursor*
4dc0: 29 63 75 72 3b 0a 20 20 73 77 69 74 63 68 28 20 )cur;. switch(
4dd0: 69 20 29 7b 0a 20 20 20 20 63 61 73 65 20 46 53 i ){. case FS
4de0: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4e 41 4d 45 3a DIR_COLUMN_NAME:
4df0: 20 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 {. sqlite3
4e00: 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 63 74 78 _result_text(ctx
4e10: 2c 20 26 70 43 75 72 2d 3e 7a 50 61 74 68 5b 70 , &pCur->zPath[p
4e20: 43 75 72 2d 3e 6e 42 61 73 65 5d 2c 20 2d 31 2c Cur->nBase], -1,
4e30: 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e SQLITE_TRANSIEN
4e40: 54 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b T);. break;
4e50: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 . }.. case
4e60: 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4d 4f FSDIR_COLUMN_MO
4e70: 44 45 3a 0a 20 20 20 20 20 20 73 71 6c 69 74 65 DE:. sqlite
4e80: 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36 34 28 63 3_result_int64(c
4e90: 74 78 2c 20 70 43 75 72 2d 3e 73 53 74 61 74 2e tx, pCur->sStat.
4ea0: 73 74 5f 6d 6f 64 65 29 3b 0a 20 20 20 20 20 20 st_mode);.
4eb0: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 break;.. case
4ec0: 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4d 54 FSDIR_COLUMN_MT
4ed0: 49 4d 45 3a 0a 20 20 20 20 20 20 73 71 6c 69 74 IME:. sqlit
4ee0: 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36 34 28 e3_result_int64(
4ef0: 63 74 78 2c 20 70 43 75 72 2d 3e 73 53 74 61 74 ctx, pCur->sStat
4f00: 2e 73 74 5f 6d 74 69 6d 65 29 3b 0a 20 20 20 20 .st_mtime);.
4f10: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 break;.. ca
4f20: 73 65 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f se FSDIR_COLUMN_
4f30: 44 41 54 41 3a 20 7b 0a 20 20 20 20 20 20 6d 6f DATA: {. mo
4f40: 64 65 5f 74 20 6d 20 3d 20 70 43 75 72 2d 3e 73 de_t m = pCur->s
4f50: 53 74 61 74 2e 73 74 5f 6d 6f 64 65 3b 0a 20 20 Stat.st_mode;.
4f60: 20 20 20 20 69 66 28 20 53 5f 49 53 44 49 52 28 if( S_ISDIR(
4f70: 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 73 71 m) ){. sq
4f80: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c lite3_result_nul
4f90: 6c 28 63 74 78 29 3b 0a 23 69 66 20 21 64 65 66 l(ctx);.#if !def
4fa0: 69 6e 65 64 28 5f 57 49 4e 33 32 29 20 26 26 20 ined(_WIN32) &&
4fb0: 21 64 65 66 69 6e 65 64 28 57 49 4e 33 32 29 0a !defined(WIN32).
4fc0: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 }else if(
4fd0: 53 5f 49 53 4c 4e 4b 28 6d 29 20 29 7b 0a 20 20 S_ISLNK(m) ){.
4fe0: 20 20 20 20 20 20 63 68 61 72 20 61 53 74 61 74 char aStat
4ff0: 69 63 5b 36 34 5d 3b 0a 20 20 20 20 20 20 20 20 ic[64];.
5000: 63 68 61 72 20 2a 61 42 75 66 20 3d 20 61 53 74 char *aBuf = aSt
5010: 61 74 69 63 3b 0a 20 20 20 20 20 20 20 20 69 6e atic;. in
5020: 74 20 6e 42 75 66 20 3d 20 36 34 3b 0a 20 20 20 t nBuf = 64;.
5030: 20 20 20 20 20 69 6e 74 20 6e 3b 0a 0a 20 20 20 int n;..
5040: 20 20 20 20 20 77 68 69 6c 65 28 20 31 20 29 7b while( 1 ){
5050: 0a 20 20 20 20 20 20 20 20 20 20 6e 20 3d 20 72 . n = r
5060: 65 61 64 6c 69 6e 6b 28 70 43 75 72 2d 3e 7a 50 eadlink(pCur->zP
5070: 61 74 68 2c 20 61 42 75 66 2c 20 6e 42 75 66 29 ath, aBuf, nBuf)
5080: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 ;. if(
5090: 6e 3c 6e 42 75 66 20 29 20 62 72 65 61 6b 3b 0a n<nBuf ) break;.
50a0: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61 42 if( aB
50b0: 75 66 21 3d 61 53 74 61 74 69 63 20 29 20 73 71 uf!=aStatic ) sq
50c0: 6c 69 74 65 33 5f 66 72 65 65 28 61 42 75 66 29 lite3_free(aBuf)
50d0: 3b 0a 20 20 20 20 20 20 20 20 20 20 6e 42 75 66 ;. nBuf
50e0: 20 3d 20 6e 42 75 66 2a 32 3b 0a 20 20 20 20 20 = nBuf*2;.
50f0: 20 20 20 20 20 61 42 75 66 20 3d 20 73 71 6c 69 aBuf = sqli
5100: 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 75 66 29 te3_malloc(nBuf)
5110: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 ;. if(
5120: 61 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 aBuf==0 ){.
5130: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 sqlite3_r
5140: 65 73 75 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 esult_error_nome
5150: 6d 28 63 74 78 29 3b 0a 20 20 20 20 20 20 20 20 m(ctx);.
5160: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 return SQLIT
5170: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 E_NOMEM;.
5180: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 0a }. }..
5190: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f sqlite3_
51a0: 72 65 73 75 6c 74 5f 74 65 78 74 28 63 74 78 2c result_text(ctx,
51b0: 20 61 42 75 66 2c 20 6e 2c 20 53 51 4c 49 54 45 aBuf, n, SQLITE
51c0: 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 _TRANSIENT);.
51d0: 20 20 20 20 20 69 66 28 20 61 42 75 66 21 3d 61 if( aBuf!=a
51e0: 53 74 61 74 69 63 20 29 20 73 71 6c 69 74 65 33 Static ) sqlite3
51f0: 5f 66 72 65 65 28 61 42 75 66 29 3b 0a 23 65 6e _free(aBuf);.#en
5200: 64 69 66 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b dif. }else{
5210: 0a 20 20 20 20 20 20 20 20 72 65 61 64 46 69 6c . readFil
5220: 65 43 6f 6e 74 65 6e 74 73 28 63 74 78 2c 20 70 eContents(ctx, p
5230: 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 20 Cur->zPath);.
5240: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 63 }. }. c
5250: 61 73 65 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e ase FSDIR_COLUMN
5260: 5f 50 41 54 48 3a 0a 20 20 20 20 64 65 66 61 75 _PATH:. defau
5270: 6c 74 3a 20 7b 0a 20 20 20 20 20 20 2f 2a 20 54 lt: {. /* T
5280: 68 65 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f he FSDIR_COLUMN_
5290: 50 41 54 48 20 61 6e 64 20 46 53 44 49 52 5f 43 PATH and FSDIR_C
52a0: 4f 4c 55 4d 4e 5f 44 49 52 20 61 72 65 20 69 6e OLUMN_DIR are in
52b0: 70 75 74 20 70 61 72 61 6d 65 74 65 72 73 2e 0a put parameters..
52c0: 20 20 20 20 20 20 2a 2a 20 61 6c 77 61 79 73 20 ** always
52d0: 72 65 74 75 72 6e 20 74 68 65 69 72 20 76 61 6c return their val
52e0: 75 65 73 20 61 73 20 4e 55 4c 4c 20 2a 2f 0a 20 ues as NULL */.
52f0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 break;.
5300: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 }. }. return S
5310: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a QLITE_OK;.}../*.
5320: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 72 6f ** Return the ro
5330: 77 69 64 20 66 6f 72 20 74 68 65 20 63 75 72 72 wid for the curr
5340: 65 6e 74 20 72 6f 77 2e 20 49 6e 20 74 68 69 73 ent row. In this
5350: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2c implementation,
5360: 20 74 68 65 0a 2a 2a 20 66 69 72 73 74 20 72 6f the.** first ro
5370: 77 20 72 65 74 75 72 6e 65 64 20 69 73 20 61 73 w returned is as
5380: 73 69 67 6e 65 64 20 72 6f 77 69 64 20 76 61 6c signed rowid val
5390: 75 65 20 31 2c 20 61 6e 64 20 65 61 63 68 20 73 ue 1, and each s
53a0: 75 62 73 65 71 75 65 6e 74 0a 2a 2a 20 72 6f 77 ubsequent.** row
53b0: 20 61 20 76 61 6c 75 65 20 31 20 6d 6f 72 65 20 a value 1 more
53c0: 74 68 61 6e 20 74 68 61 74 20 6f 66 20 74 68 65 than that of the
53d0: 20 70 72 65 76 69 6f 75 73 2e 0a 2a 2f 0a 73 74 previous..*/.st
53e0: 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 52 6f atic int fsdirRo
53f0: 77 69 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 wid(sqlite3_vtab
5400: 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 _cursor *cur, sq
5410: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 lite_int64 *pRow
5420: 69 64 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 id){. fsdir_cur
5430: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 sor *pCur = (fsd
5440: 69 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a ir_cursor*)cur;.
5450: 20 20 2a 70 52 6f 77 69 64 20 3d 20 70 43 75 72 *pRowid = pCur
5460: 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 72 65 74 75 ->iRowid;. retu
5470: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a rn SQLITE_OK;.}.
5480: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52 ./*.** Return TR
5490: 55 45 20 69 66 20 74 68 65 20 63 75 72 73 6f 72 UE if the cursor
54a0: 20 68 61 73 20 62 65 65 6e 20 6d 6f 76 65 64 20 has been moved
54b0: 6f 66 66 20 6f 66 20 74 68 65 20 6c 61 73 74 0a off of the last.
54c0: 2a 2a 20 72 6f 77 20 6f 66 20 6f 75 74 70 75 74 ** row of output
54d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
54e0: 66 73 64 69 72 45 6f 66 28 73 71 6c 69 74 65 33 fsdirEof(sqlite3
54f0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 _vtab_cursor *cu
5500: 72 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73 r){. fsdir_curs
5510: 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69 or *pCur = (fsdi
5520: 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 r_cursor*)cur;.
5530: 20 72 65 74 75 72 6e 20 28 70 43 75 72 2d 3e 7a return (pCur->z
5540: 50 61 74 68 3d 3d 30 29 3b 0a 7d 0a 0a 2f 2a 0a Path==0);.}../*.
5550: 2a 2a 20 78 46 69 6c 74 65 72 20 63 61 6c 6c 62 ** xFilter callb
5560: 61 63 6b 2e 0a 2a 2a 0a 2a 2a 20 69 64 78 4e 75 ack..**.** idxNu
5570: 6d 3d 3d 31 20 20 20 50 41 54 48 20 70 61 72 61 m==1 PATH para
5580: 6d 65 74 65 72 20 6f 6e 6c 79 0a 2a 2a 20 69 64 meter only.** id
5590: 78 4e 75 6d 3d 3d 32 20 20 20 42 6f 74 68 20 50 xNum==2 Both P
55a0: 41 54 48 20 61 6e 64 20 44 49 52 20 73 75 70 70 ATH and DIR supp
55b0: 6c 69 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 69 lied.*/.static i
55c0: 6e 74 20 66 73 64 69 72 46 69 6c 74 65 72 28 0a nt fsdirFilter(.
55d0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 sqlite3_vtab_c
55e0: 75 72 73 6f 72 20 2a 63 75 72 2c 20 0a 20 20 69 ursor *cur, . i
55f0: 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 nt idxNum, const
5600: 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c 0a 20 char *idxStr,.
5610: 20 69 6e 74 20 61 72 67 63 2c 20 73 71 6c 69 74 int argc, sqlit
5620: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a e3_value **argv.
5630: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 ){. const char
5640: 2a 7a 44 69 72 20 3d 20 30 3b 0a 20 20 66 73 64 *zDir = 0;. fsd
5650: 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 ir_cursor *pCur
5660: 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a = (fsdir_cursor*
5670: 29 63 75 72 3b 0a 20 20 28 76 6f 69 64 29 69 64 )cur;. (void)id
5680: 78 53 74 72 3b 0a 20 20 66 73 64 69 72 52 65 73 xStr;. fsdirRes
5690: 65 74 43 75 72 73 6f 72 28 70 43 75 72 29 3b 0a etCursor(pCur);.
56a0: 0a 20 20 69 66 28 20 69 64 78 4e 75 6d 3d 3d 30 . if( idxNum==0
56b0: 20 29 7b 0a 20 20 20 20 66 73 64 69 72 53 65 74 ){. fsdirSet
56c0: 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 74 61 Errmsg(pCur, "ta
56d0: 62 6c 65 20 66 75 6e 63 74 69 6f 6e 20 66 73 64 ble function fsd
56e0: 69 72 20 72 65 71 75 69 72 65 73 20 61 6e 20 61 ir requires an a
56f0: 72 67 75 6d 65 6e 74 22 29 3b 0a 20 20 20 20 72 rgument");. r
5700: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 eturn SQLITE_ERR
5710: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 OR;. }.. asser
5720: 74 28 20 61 72 67 63 3d 3d 69 64 78 4e 75 6d 20 t( argc==idxNum
5730: 26 26 20 28 61 72 67 63 3d 3d 31 20 7c 7c 20 61 && (argc==1 || a
5740: 72 67 63 3d 3d 32 29 20 29 3b 0a 20 20 7a 44 69 rgc==2) );. zDi
5750: 72 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a r = (const char*
5760: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 )sqlite3_value_t
5770: 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 ext(argv[0]);.
5780: 69 66 28 20 7a 44 69 72 3d 3d 30 20 29 7b 0a 20 if( zDir==0 ){.
5790: 20 20 20 66 73 64 69 72 53 65 74 45 72 72 6d 73 fsdirSetErrms
57a0: 67 28 70 43 75 72 2c 20 22 74 61 62 6c 65 20 66 g(pCur, "table f
57b0: 75 6e 63 74 69 6f 6e 20 66 73 64 69 72 20 72 65 unction fsdir re
57c0: 71 75 69 72 65 73 20 61 20 6e 6f 6e 2d 4e 55 4c quires a non-NUL
57d0: 4c 20 61 72 67 75 6d 65 6e 74 22 29 3b 0a 20 20 L argument");.
57e0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f return SQLITE_
57f0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 ERROR;. }. if(
5800: 20 61 72 67 63 3d 3d 32 20 29 7b 0a 20 20 20 20 argc==2 ){.
5810: 70 43 75 72 2d 3e 7a 42 61 73 65 20 3d 20 28 63 pCur->zBase = (c
5820: 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 onst char*)sqlit
5830: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 e3_value_text(ar
5840: 67 76 5b 31 5d 29 3b 0a 20 20 7d 0a 20 20 69 66 gv[1]);. }. if
5850: 28 20 70 43 75 72 2d 3e 7a 42 61 73 65 20 29 7b ( pCur->zBase ){
5860: 0a 20 20 20 20 70 43 75 72 2d 3e 6e 42 61 73 65 . pCur->nBase
5870: 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 70 = (int)strlen(p
5880: 43 75 72 2d 3e 7a 42 61 73 65 29 2b 31 3b 0a 20 Cur->zBase)+1;.
5890: 20 20 20 70 43 75 72 2d 3e 7a 50 61 74 68 20 3d pCur->zPath =
58a0: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 sqlite3_mprintf
58b0: 28 22 25 73 2f 25 73 22 2c 20 70 43 75 72 2d 3e ("%s/%s", pCur->
58c0: 7a 42 61 73 65 2c 20 7a 44 69 72 29 3b 0a 20 20 zBase, zDir);.
58d0: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 43 75 72 2d }else{. pCur-
58e0: 3e 7a 50 61 74 68 20 3d 20 73 71 6c 69 74 65 33 >zPath = sqlite3
58f0: 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a _mprintf("%s", z
5900: 44 69 72 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 Dir);. }.. if(
5910: 20 70 43 75 72 2d 3e 7a 50 61 74 68 3d 3d 30 20 pCur->zPath==0
5920: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 ){. return SQ
5930: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a LITE_NOMEM;. }.
5940: 20 20 69 66 28 20 66 69 6c 65 4c 69 6e 6b 53 74 if( fileLinkSt
5950: 61 74 28 70 43 75 72 2d 3e 7a 50 61 74 68 2c 20 at(pCur->zPath,
5960: 26 70 43 75 72 2d 3e 73 53 74 61 74 29 20 29 7b &pCur->sStat) ){
5970: 0a 20 20 20 20 66 73 64 69 72 53 65 74 45 72 72 . fsdirSetErr
5980: 6d 73 67 28 70 43 75 72 2c 20 22 63 61 6e 6e 6f msg(pCur, "canno
5990: 74 20 73 74 61 74 20 66 69 6c 65 3a 20 25 73 22 t stat file: %s"
59a0: 2c 20 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a , pCur->zPath);.
59b0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 return SQLIT
59c0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 E_ERROR;. }..
59d0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b return SQLITE_OK
59e0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 51 4c 69 74 ;.}../*.** SQLit
59f0: 65 20 77 69 6c 6c 20 69 6e 76 6f 6b 65 20 74 68 e will invoke th
5a00: 69 73 20 6d 65 74 68 6f 64 20 6f 6e 65 20 6f 72 is method one or
5a10: 20 6d 6f 72 65 20 74 69 6d 65 73 20 77 68 69 6c more times whil
5a20: 65 20 70 6c 61 6e 6e 69 6e 67 20 61 20 71 75 65 e planning a que
5a30: 72 79 0a 2a 2a 20 74 68 61 74 20 75 73 65 73 20 ry.** that uses
5a40: 74 68 65 20 67 65 6e 65 72 61 74 65 5f 73 65 72 the generate_ser
5a50: 69 65 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c ies virtual tabl
5a60: 65 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 e. This routine
5a70: 20 6e 65 65 64 73 20 74 6f 20 63 72 65 61 74 65 needs to create
5a80: 0a 2a 2a 20 61 20 71 75 65 72 79 20 70 6c 61 6e .** a query plan
5a90: 20 66 6f 72 20 65 61 63 68 20 69 6e 76 6f 63 61 for each invoca
5aa0: 74 69 6f 6e 20 61 6e 64 20 63 6f 6d 70 75 74 65 tion and compute
5ab0: 20 61 6e 20 65 73 74 69 6d 61 74 65 64 20 63 6f an estimated co
5ac0: 73 74 20 66 6f 72 20 74 68 61 74 0a 2a 2a 20 70 st for that.** p
5ad0: 6c 61 6e 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 74 68 lan..**.** In th
5ae0: 69 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f is implementatio
5af0: 6e 20 69 64 78 4e 75 6d 20 69 73 20 75 73 65 64 n idxNum is used
5b00: 20 74 6f 20 72 65 70 72 65 73 65 6e 74 20 74 68 to represent th
5b10: 65 0a 2a 2a 20 71 75 65 72 79 20 70 6c 61 6e 2e e.** query plan.
5b20: 20 20 69 64 78 53 74 72 20 69 73 20 75 6e 75 73 idxStr is unus
5b30: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 71 75 ed..**.** The qu
5b40: 65 72 79 20 70 6c 61 6e 20 69 73 20 72 65 70 72 ery plan is repr
5b50: 65 73 65 6e 74 65 64 20 62 79 20 76 61 6c 75 65 esented by value
5b60: 73 20 6f 66 20 69 64 78 4e 75 6d 3a 0a 2a 2a 0a s of idxNum:.**.
5b70: 2a 2a 20 20 28 31 29 20 20 54 68 65 20 70 61 74 ** (1) The pat
5b80: 68 20 76 61 6c 75 65 20 69 73 20 73 75 70 70 6c h value is suppl
5b90: 69 65 64 20 62 79 20 61 72 67 76 5b 30 5d 0a 2a ied by argv[0].*
5ba0: 2a 20 20 28 32 29 20 20 50 61 74 68 20 69 73 20 * (2) Path is
5bb0: 69 6e 20 61 72 67 76 5b 30 5d 20 61 6e 64 20 64 in argv[0] and d
5bc0: 69 72 20 69 73 20 69 6e 20 61 72 67 76 5b 31 5d ir is in argv[1]
5bd0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 .*/.static int f
5be0: 73 64 69 72 42 65 73 74 49 6e 64 65 78 28 0a 20 sdirBestIndex(.
5bf0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 sqlite3_vtab *t
5c00: 61 62 2c 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e ab,. sqlite3_in
5c10: 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e dex_info *pIdxIn
5c20: 66 6f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 20 20 fo.){. int i;
5c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
5c40: 2a 20 4c 6f 6f 70 20 6f 76 65 72 20 63 6f 6e 73 * Loop over cons
5c50: 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 69 6e 74 traints */. int
5c60: 20 69 64 78 50 61 74 68 20 3d 20 2d 31 3b 20 20 idxPath = -1;
5c70: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 20 /* Index in
5c80: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 pIdxInfo->aConst
5c90: 72 61 69 6e 74 20 6f 66 20 50 41 54 48 3d 20 2a raint of PATH= *
5ca0: 2f 0a 20 20 69 6e 74 20 69 64 78 44 69 72 20 3d /. int idxDir =
5cb0: 20 2d 31 3b 20 20 20 20 20 20 20 2f 2a 20 49 6e -1; /* In
5cc0: 64 65 78 20 69 6e 20 70 49 64 78 49 6e 66 6f 2d dex in pIdxInfo-
5cd0: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 20 6f 66 20 >aConstraint of
5ce0: 44 49 52 3d 20 2a 2f 0a 20 20 69 6e 74 20 73 65 DIR= */. int se
5cf0: 65 6e 50 61 74 68 20 3d 20 30 3b 20 20 20 20 20 enPath = 0;
5d00: 20 2f 2a 20 54 72 75 65 20 69 66 20 61 6e 20 75 /* True if an u
5d10: 6e 75 73 61 62 6c 65 20 50 41 54 48 3d 20 63 6f nusable PATH= co
5d20: 6e 73 74 72 61 69 6e 74 20 69 73 20 73 65 65 6e nstraint is seen
5d30: 20 2a 2f 0a 20 20 69 6e 74 20 73 65 65 6e 44 69 */. int seenDi
5d40: 72 20 3d 20 30 3b 20 20 20 20 20 20 20 2f 2a 20 r = 0; /*
5d50: 54 72 75 65 20 69 66 20 61 6e 20 75 6e 75 73 61 True if an unusa
5d60: 62 6c 65 20 44 49 52 3d 20 63 6f 6e 73 74 72 61 ble DIR= constra
5d70: 69 6e 74 20 69 73 20 73 65 65 6e 20 2a 2f 0a 20 int is seen */.
5d80: 20 63 6f 6e 73 74 20 73 74 72 75 63 74 20 73 71 const struct sq
5d90: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 lite3_index_cons
5da0: 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 traint *pConstra
5db0: 69 6e 74 3b 0a 0a 20 20 28 76 6f 69 64 29 74 61 int;.. (void)ta
5dc0: 62 3b 0a 20 20 70 43 6f 6e 73 74 72 61 69 6e 74 b;. pConstraint
5dd0: 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f = pIdxInfo->aCo
5de0: 6e 73 74 72 61 69 6e 74 3b 0a 20 20 66 6f 72 28 nstraint;. for(
5df0: 69 3d 30 3b 20 69 3c 70 49 64 78 49 6e 66 6f 2d i=0; i<pIdxInfo-
5e00: 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20 69 2b >nConstraint; i+
5e10: 2b 2c 20 70 43 6f 6e 73 74 72 61 69 6e 74 2b 2b +, pConstraint++
5e20: 29 7b 0a 20 20 20 20 69 66 28 20 70 43 6f 6e 73 ){. if( pCons
5e30: 74 72 61 69 6e 74 2d 3e 6f 70 21 3d 53 51 4c 49 traint->op!=SQLI
5e40: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 TE_INDEX_CONSTRA
5e50: 49 4e 54 5f 45 51 20 29 20 63 6f 6e 74 69 6e 75 INT_EQ ) continu
5e60: 65 3b 0a 20 20 20 20 73 77 69 74 63 68 28 20 70 e;. switch( p
5e70: 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f 6c Constraint->iCol
5e80: 75 6d 6e 20 29 7b 0a 20 20 20 20 20 20 63 61 73 umn ){. cas
5e90: 65 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 50 e FSDIR_COLUMN_P
5ea0: 41 54 48 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 ATH: {. i
5eb0: 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e f( pConstraint->
5ec0: 75 73 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 usable ){.
5ed0: 20 20 20 20 69 64 78 50 61 74 68 20 3d 20 69 3b idxPath = i;
5ee0: 0a 20 20 20 20 20 20 20 20 20 20 73 65 65 6e 50 . seenP
5ef0: 61 74 68 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 ath = 0;.
5f00: 20 7d 65 6c 73 65 20 69 66 28 20 69 64 78 50 61 }else if( idxPa
5f10: 74 68 3c 30 20 29 7b 0a 20 20 20 20 20 20 20 20 th<0 ){.
5f20: 20 20 73 65 65 6e 50 61 74 68 20 3d 20 31 3b 0a seenPath = 1;.
5f30: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 }.
5f40: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d break;. }
5f50: 0a 20 20 20 20 20 20 63 61 73 65 20 46 53 44 49 . case FSDI
5f60: 52 5f 43 4f 4c 55 4d 4e 5f 44 49 52 3a 20 7b 0a R_COLUMN_DIR: {.
5f70: 20 20 20 20 20 20 20 20 69 66 28 20 70 43 6f 6e if( pCon
5f80: 73 74 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65 20 straint->usable
5f90: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 64 78 ){. idx
5fa0: 44 69 72 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 Dir = i;.
5fb0: 20 20 20 73 65 65 6e 44 69 72 20 3d 20 30 3b 0a seenDir = 0;.
5fc0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 }else if
5fd0: 28 20 69 64 78 44 69 72 3c 30 20 29 7b 0a 20 20 ( idxDir<0 ){.
5fe0: 20 20 20 20 20 20 20 20 73 65 65 6e 44 69 72 20 seenDir
5ff0: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 = 1;. }.
6000: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 break;.
6010: 20 20 20 20 7d 0a 20 20 20 20 7d 20 0a 20 20 7d }. } . }
6020: 0a 20 20 69 66 28 20 73 65 65 6e 50 61 74 68 20 . if( seenPath
6030: 7c 7c 20 73 65 65 6e 44 69 72 20 29 7b 0a 20 20 || seenDir ){.
6040: 20 20 2f 2a 20 49 66 20 69 6e 70 75 74 20 70 61 /* If input pa
6050: 72 61 6d 65 74 65 72 73 20 61 72 65 20 75 6e 75 rameters are unu
6060: 73 61 62 6c 65 2c 20 64 69 73 61 6c 6c 6f 77 20 sable, disallow
6070: 74 68 69 73 20 70 6c 61 6e 20 2a 2f 0a 20 20 20 this plan */.
6080: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 return SQLITE_C
6090: 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20 7d 0a 0a ONSTRAINT;. }..
60a0: 20 20 69 66 28 20 69 64 78 50 61 74 68 3c 30 20 if( idxPath<0
60b0: 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d ){. pIdxInfo-
60c0: 3e 69 64 78 4e 75 6d 20 3d 20 30 3b 0a 20 20 20 >idxNum = 0;.
60d0: 20 2f 2a 20 54 68 65 20 70 49 64 78 49 6e 66 6f /* The pIdxInfo
60e0: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 ->estimatedCost
60f0: 73 68 6f 75 6c 64 20 68 61 76 65 20 62 65 65 6e should have been
6100: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 74 6f 20 initialized to
6110: 61 20 68 75 67 65 0a 20 20 20 20 2a 2a 20 6e 75 a huge. ** nu
6120: 6d 62 65 72 2e 20 20 4c 65 61 76 65 20 69 74 20 mber. Leave it
6130: 75 6e 63 68 61 6e 67 65 64 2e 20 2a 2f 0a 20 20 unchanged. */.
6140: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 pIdxInfo->esti
6150: 6d 61 74 65 64 52 6f 77 73 20 3d 20 30 78 37 66 matedRows = 0x7f
6160: 66 66 66 66 66 66 3b 0a 20 20 7d 65 6c 73 65 7b ffffff;. }else{
6170: 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 . pIdxInfo->a
6180: 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b ConstraintUsage[
6190: 69 64 78 50 61 74 68 5d 2e 6f 6d 69 74 20 3d 20 idxPath].omit =
61a0: 31 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 1;. pIdxInfo-
61b0: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 >aConstraintUsag
61c0: 65 5b 69 64 78 50 61 74 68 5d 2e 61 72 67 76 49 e[idxPath].argvI
61d0: 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 69 66 ndex = 1;. if
61e0: 28 20 69 64 78 44 69 72 3e 3d 30 20 29 7b 0a 20 ( idxDir>=0 ){.
61f0: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 pIdxInfo->a
6200: 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b ConstraintUsage[
6210: 69 64 78 44 69 72 5d 2e 6f 6d 69 74 20 3d 20 31 idxDir].omit = 1
6220: 3b 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f ;. pIdxInfo
6230: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 ->aConstraintUsa
6240: 67 65 5b 69 64 78 44 69 72 5d 2e 61 72 67 76 49 ge[idxDir].argvI
6250: 6e 64 65 78 20 3d 20 32 3b 0a 20 20 20 20 20 20 ndex = 2;.
6260: 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d pIdxInfo->idxNum
6270: 20 3d 20 32 3b 0a 20 20 20 20 20 20 70 49 64 78 = 2;. pIdx
6280: 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 Info->estimatedC
6290: 6f 73 74 20 3d 20 31 30 2e 30 3b 0a 20 20 20 20 ost = 10.0;.
62a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 49 64 }else{. pId
62b0: 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 xInfo->idxNum =
62c0: 31 3b 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66 1;. pIdxInf
62d0: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 o->estimatedCost
62e0: 20 3d 20 31 30 30 2e 30 3b 0a 20 20 20 20 7d 0a = 100.0;. }.
62f0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 }.. return SQ
6300: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a LITE_OK;.}../*.*
6310: 2a 20 52 65 67 69 73 74 65 72 20 74 68 65 20 22 * Register the "
6320: 66 73 64 69 72 22 20 76 69 72 74 75 61 6c 20 74 fsdir" virtual t
6330: 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 able..*/.static
6340: 69 6e 74 20 66 73 64 69 72 52 65 67 69 73 74 65 int fsdirRegiste
6350: 72 28 73 71 6c 69 74 65 33 20 2a 64 62 29 7b 0a r(sqlite3 *db){.
6360: 20 20 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 static sqlite3
6370: 5f 6d 6f 64 75 6c 65 20 66 73 64 69 72 4d 6f 64 _module fsdirMod
6380: 75 6c 65 20 3d 20 7b 0a 20 20 20 20 30 2c 20 20 ule = {. 0,
6390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
63a0: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 /* iVersi
63b0: 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 on */. 0,
63c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
63d0: 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20 /* xCreate
63e0: 2a 2f 0a 20 20 20 20 66 73 64 69 72 43 6f 6e 6e */. fsdirConn
63f0: 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 ect,
6400: 20 20 2f 2a 20 78 43 6f 6e 6e 65 63 74 20 2a 2f /* xConnect */
6410: 0a 20 20 20 20 66 73 64 69 72 42 65 73 74 49 6e . fsdirBestIn
6420: 64 65 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 dex,
6430: 2f 2a 20 78 42 65 73 74 49 6e 64 65 78 20 2a 2f /* xBestIndex */
6440: 0a 20 20 20 20 66 73 64 69 72 44 69 73 63 6f 6e . fsdirDiscon
6450: 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 nect,
6460: 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74 20 2a /* xDisconnect *
6470: 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 /. 0,
6480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6490: 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a /* xDestroy */.
64a0: 20 20 20 20 66 73 64 69 72 4f 70 65 6e 2c 20 20 fsdirOpen,
64b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
64c0: 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e 20 61 * xOpen - open a
64d0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 20 20 66 cursor */. f
64e0: 73 64 69 72 43 6c 6f 73 65 2c 20 20 20 20 20 20 sdirClose,
64f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c /* xCl
6500: 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 ose - close a cu
6510: 72 73 6f 72 20 2a 2f 0a 20 20 20 20 66 73 64 69 rsor */. fsdi
6520: 72 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20 rFilter,
6530: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 74 65 /* xFilte
6540: 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20 73 63 r - configure sc
6550: 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a an constraints *
6560: 2f 0a 20 20 20 20 66 73 64 69 72 4e 65 78 74 2c /. fsdirNext,
6570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6580: 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61 /* xNext - adva
6590: 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a nce a cursor */.
65a0: 20 20 20 20 66 73 64 69 72 45 6f 66 2c 20 20 20 fsdirEof,
65b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
65c0: 2a 20 78 45 6f 66 20 2d 20 63 68 65 63 6b 20 66 * xEof - check f
65d0: 6f 72 20 65 6e 64 20 6f 66 20 73 63 61 6e 20 2a or end of scan *
65e0: 2f 0a 20 20 20 20 66 73 64 69 72 43 6f 6c 75 6d /. fsdirColum
65f0: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 n,
6600: 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 /* xColumn - re
6610: 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 66 ad data */. f
6620: 73 64 69 72 52 6f 77 69 64 2c 20 20 20 20 20 20 sdirRowid,
6630: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f /* xRo
6640: 77 69 64 20 2d 20 72 65 61 64 20 64 61 74 61 20 wid - read data
6650: 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 */. 0,
6660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6670: 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2a 2f 0a /* xUpdate */.
6680: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 0,
6690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
66a0: 2a 20 78 42 65 67 69 6e 20 2a 2f 0a 20 20 20 20 * xBegin */.
66b0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0,
66c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 /* xS
66d0: 79 6e 63 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 ync */. 0,
66e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
66f0: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 /* xCommit
6700: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 */. 0,
6710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6720: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 /* xRollback
6730: 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 */. 0,
6740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6750: 20 20 2f 2a 20 78 46 69 6e 64 4d 65 74 68 6f 64 /* xFindMethod
6760: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 */. 0,
6770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6780: 20 20 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2a 2f /* xRename */
6790: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 . 0,
67a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
67b0: 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74 20 2a 2f /* xSavepoint */
67c0: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 . 0,
67d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
67e0: 2f 2a 20 78 52 65 6c 65 61 73 65 20 2a 2f 0a 20 /* xRelease */.
67f0: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 0,
6800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
6810: 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 2a 2f 0a xRollbackTo */.
6820: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 0,
6830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
6840: 2a 20 78 53 68 61 64 6f 77 4e 61 6d 65 20 2a 2f * xShadowName */
6850: 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74 20 72 63 20 . };.. int rc
6860: 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 = sqlite3_create
6870: 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22 66 73 64 _module(db, "fsd
6880: 69 72 22 2c 20 26 66 73 64 69 72 4d 6f 64 75 6c ir", &fsdirModul
6890: 65 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 e, 0);. return
68a0: 72 63 3b 0a 7d 0a 23 65 6c 73 65 20 20 20 20 20 rc;.}.#else
68b0: 20 20 20 20 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d /* SQLITE_OM
68c0: 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 20 IT_VIRTUALTABLE
68d0: 2a 2f 0a 23 20 64 65 66 69 6e 65 20 66 73 64 69 */.# define fsdi
68e0: 72 52 65 67 69 73 74 65 72 28 78 29 20 53 51 4c rRegister(x) SQL
68f0: 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a 23 ITE_OK.#endif..#
6900: 69 66 64 65 66 20 5f 57 49 4e 33 32 0a 5f 5f 64 ifdef _WIN32.__d
6910: 65 63 6c 73 70 65 63 28 64 6c 6c 65 78 70 6f 72 eclspec(dllexpor
6920: 74 29 0a 23 65 6e 64 69 66 0a 69 6e 74 20 73 71 t).#endif.int sq
6930: 6c 69 74 65 33 5f 66 69 6c 65 69 6f 5f 69 6e 69 lite3_fileio_ini
6940: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 t(. sqlite3 *db
6950: 2c 20 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 , . char **pzEr
6960: 72 4d 73 67 2c 20 0a 20 20 63 6f 6e 73 74 20 73 rMsg, . const s
6970: 71 6c 69 74 65 33 5f 61 70 69 5f 72 6f 75 74 69 qlite3_api_routi
6980: 6e 65 73 20 2a 70 41 70 69 0a 29 7b 0a 20 20 69 nes *pApi.){. i
6990: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f nt rc = SQLITE_O
69a0: 4b 3b 0a 20 20 53 51 4c 49 54 45 5f 45 58 54 45 K;. SQLITE_EXTE
69b0: 4e 53 49 4f 4e 5f 49 4e 49 54 32 28 70 41 70 69 NSION_INIT2(pApi
69c0: 29 3b 0a 20 20 28 76 6f 69 64 29 70 7a 45 72 72 );. (void)pzErr
69d0: 4d 73 67 3b 20 20 2f 2a 20 55 6e 75 73 65 64 20 Msg; /* Unused
69e0: 70 61 72 61 6d 65 74 65 72 20 2a 2f 0a 20 20 72 parameter */. r
69f0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 c = sqlite3_crea
6a00: 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20 te_function(db,
6a10: 22 72 65 61 64 66 69 6c 65 22 2c 20 31 2c 20 53 "readfile", 1, S
6a20: 51 4c 49 54 45 5f 55 54 46 38 2c 20 30 2c 0a 20 QLITE_UTF8, 0,.
6a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65 re
6a50: 61 64 66 69 6c 65 46 75 6e 63 2c 20 30 2c 20 30 adfileFunc, 0, 0
6a60: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c );. if( rc==SQL
6a70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 ITE_OK ){. rc
6a80: 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 = sqlite3_creat
6a90: 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22 e_function(db, "
6aa0: 77 72 69 74 65 66 69 6c 65 22 2c 20 2d 31 2c 20 writefile", -1,
6ab0: 53 51 4c 49 54 45 5f 55 54 46 38 2c 20 30 2c 0a SQLITE_UTF8, 0,.
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6ae0: 20 77 72 69 74 65 66 69 6c 65 46 75 6e 63 2c 20 writefileFunc,
6af0: 30 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 69 66 28 0, 0);. }. if(
6b00: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 rc==SQLITE_OK )
6b10: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 {. rc = sqlit
6b20: 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 e3_create_functi
6b30: 6f 6e 28 64 62 2c 20 22 6c 73 6d 6f 64 65 22 2c on(db, "lsmode",
6b40: 20 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c 1, SQLITE_UTF8,
6b50: 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 0,.
6b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6b70: 20 20 20 20 20 6c 73 4d 6f 64 65 46 75 6e 63 2c lsModeFunc,
6b80: 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 69 66 0, 0);. }. if
6b90: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 ( rc==SQLITE_OK
6ba0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 66 73 64 69 ){. rc = fsdi
6bb0: 72 52 65 67 69 73 74 65 72 28 64 62 29 3b 0a 20 rRegister(db);.
6bc0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a }. return rc;.
6bd0: 7d 0a }.