System.Data.SQLite
Check-in [42512a2bfb]
Not logged in

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

Overview
Comment:Preserve selected HTML tags when processing the virtual table methods documentation into the CHM file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | vtabDocComments
Files: files | file ages | folders
SHA1: 42512a2bfbd526393dcefeb0e0ef0a735bb39090
User & Date: mistachkin 2015-10-18 20:07:44
Context
2015-10-18
20:11
Minor simplification to the previous check-in. Also, correct a comment. Closed-Leaf check-in: fcc756f8d0 user: mistachkin tags: vtabDocComments
20:07
Preserve selected HTML tags when processing the virtual table methods documentation into the CHM file. check-in: 42512a2bfb user: mistachkin tags: vtabDocComments
05:32
Update embedded virtual table methods documentation comments using the new tool. check-in: 29f36edc2d user: mistachkin tags: vtabDocComments
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to Doc/buildChm.tcl.

41
42
43
44
45
46
47

































































48
49
50
51
52
53
54
...
135
136
137
138
139
140
141







142
143
144
145
146
147
148
149
150
151
152
153
154
155
...
292
293
294
295
296
297
298














299
300
301
302
303
304
305
    exec fossil.exe sha1sum [file nativename $fileName]
  } result] == 0} then {
    return [string trim [lindex [split $result " "] 0]]
  }
  return ""
}
 

































































#
# HACK: This procedure checks all the "href" attribute values in the specified
#       core documentation file.  For each value, this procedure checks if the
#       reference conforms to one of the following general categories:
#
#       1. A relative reference to a named anchor within the same document.
#       2. An absolute reference using HTTP or HTTPS.
................................................................................
    # NOTE: Perform the replacements, if any, keeping track of how many were
    #       done.
    #
    incr count [regsub -all -- $pattern $data $subSpec data]
  }

  #







  # NOTE: If some replacements were performed on the data from the file, then
  #       overwrite it with the new data; otherwise, issue a warning.
  #
  if {$count > 0} then {
    writeFile $fileName $data
  } else {
    puts stdout "*WARNING* File \"$fileName\" does not match: href=\"(.*?)\""
  }
}
 
#
# HACK: Copy our local [fixed] copy of the MSDN documenter assembly into the
#       installed location of NDoc3, if necessary.  Actually copying the file
#       will require elevated administrator privileges; otherwise, it will
................................................................................
  if {![file isfile $fileName]} then {
    puts stdout "Cannot find core syntax file: $fileName"
    exit 1
  }

  transformCoreDocumentationFile $fileName https://www.sqlite.org/
}















###############################################################################

set patterns(.hhc,1) {<!--This document contains Table of Contents information\
for the HtmlHelp compiler\.--><UL>}

set patterns(.hhp,1) {Default topic=~System\.Data\.SQLite\.html}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
|
|



<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218


219
220
221
222
223
224
225
...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    exec fossil.exe sha1sum [file nativename $fileName]
  } result] == 0} then {
    return [string trim [lindex [split $result " "] 0]]
  }
  return ""
}
 
#
# NOTE: This procedure unescapes certain HTML tags that are used within the
#       documentation for the virtual table methods.
#
proc unescapeHtmlTags { fileName cdata } {
  #
  # NOTE: Read all the textual data from the file.
  #
  set data [readFile $fileName]

  #
  # NOTE: No replacements made yet.
  #
  set count 0

  #
  # NOTE: If requested by the caller, unwrap all content contained with XML
  #       CDATA sections as well.
  #
  if {$cdata} then {
    #
    # NOTE: Grab everything within the CDATA tags and use verbatim.
    #
    set cdataCount [regsub -all -- {<![CDATA[(.*?)]]>} $data {\1} data]

    if {$cdataCount > 0} then {
      incr count $cdataCount
    } else {
      # puts stdout "*WARNING* File \"$fileName\" has no CDATA"
    }
  }

  #
  # TODO: Handle all the HTML tags we know may be present in the virtual
  #       table method documentation.  This may need adjustments in the
  #       future.
  #
  foreach to [list \
      {<b>} {</b>} {<br>} {<dd>} {</dd>} {<dl>} {</dl>} {<dt>} \
      {</dt>} {<li>} {</li>} {<ol>} {</ol>} {<tt>} {</tt>} \
      {<ul>} {</ul>}] {
    #
    # NOTE: Figure out the escaped form of this tag and then replace it
    #       with the unescaped form.
    #
    set from [string map [list < &lt\; > &gt\;] $to]
    incr count [regsub -all -- $from $data $to data]
  }

  #
  # NOTE: Issue a warning if the "href" pattern was not matched.
  #
  if {$count == 0} then {
    puts stdout "*WARNING* File \"$fileName\" has no supported HTML tags"
  }

  #
  # NOTE: If some replacements were performed on the data from the file,
  #       then overwrite it with the new data.
  #
  if {$count > 0} then {
    writeFile $fileName $data
  }
}
 
#
# HACK: This procedure checks all the "href" attribute values in the specified
#       core documentation file.  For each value, this procedure checks if the
#       reference conforms to one of the following general categories:
#
#       1. A relative reference to a named anchor within the same document.
#       2. An absolute reference using HTTP or HTTPS.
................................................................................
    # NOTE: Perform the replacements, if any, keeping track of how many were
    #       done.
    #
    incr count [regsub -all -- $pattern $data $subSpec data]
  }

  #
  # NOTE: Issue a warning if the "href" pattern was not matched.
  #
  if {$count == 0} then {
    puts stdout "*WARNING* File \"$fileName\" does not match: href=\"(.*?)\""
  }

  #
  # NOTE: If some replacements were performed on the data from the file,
  #       then overwrite it with the new data.
  #
  if {$count > 0} then {
    writeFile $fileName $data


  }
}
 
#
# HACK: Copy our local [fixed] copy of the MSDN documenter assembly into the
#       installed location of NDoc3, if necessary.  Actually copying the file
#       will require elevated administrator privileges; otherwise, it will
................................................................................
  if {![file isfile $fileName]} then {
    puts stdout "Cannot find core syntax file: $fileName"
    exit 1
  }

  transformCoreDocumentationFile $fileName https://www.sqlite.org/
}

###############################################################################

foreach fileName [glob -nocomplain [file join $temporaryPath \
    System.Data.SQLite~System.Data.SQLite.ISQLiteNativeModule*.html]] {
  set fileName [file join $path $fileName]

  if {![file isfile $fileName]} then {
    puts stdout "Cannot find temporary provider file: $fileName"
    exit 1
  }

  unescapeHtmlTags $fileName false
}

###############################################################################

set patterns(.hhc,1) {<!--This document contains Table of Contents information\
for the HtmlHelp compiler\.--><UL>}

set patterns(.hhp,1) {Default topic=~System\.Data\.SQLite\.html}

Changes to Doc/vtab.tcl.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63






64
65
66
67
68
69
70
..
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
      [regexp -- {<h\d(?: |>)} [string range $line 0 3]]} then {
    return ""
  }

  set result $line

  foreach remove [list \
      {<a name=".*?">} {<a href=".*?">} {</a>} {<b>} {</b>} \
      {<dd>} {</dd>} {<dl>} {</dl>} {<dt>} {</dt>} {<li>} \
      {</li>} {<ol>} {</ol>} {<p>} {</p>} {<ul>} {</ul>}] {
    regsub -all -- $remove $result "" result

    if {[string length [string trim $result]] == 0} then {
      return ""
    }
  }

  regsub -all -- {<br>} $result \n[escapeSubSpec $prefix] result






  regsub -all -- {&ne;} $result {\&#8800;} result
  regsub -all -- {&#91(?:;)?} $result {[} result
  regsub -all -- {&#93(?:;)?} $result {]} result
  regsub -all -- {<( |\"|\d|=)} $result {\&lt;\1} result
  regsub -all -- {( |\"|\d|=)>} $result {\1\&gt;} result
  regsub -all -- {<blockquote><pre>} $result <para><code> result
  regsub -all -- {</pre></blockquote>} $result </code></para> result
................................................................................
  return $result
}
 
proc extractMethod { name lines pattern prefix indexVarName methodsVarName } {
  upvar 1 $indexVarName index
  upvar 1 $methodsVarName methods

  set paragraph 0
  set length [llength $lines]

  while {$index < $length} {
    set line [lindex $lines $index]

    if {[regexp -- $pattern $line]} then {
      break; # stop on this line for outer loop.
    } else {
      set trimLine [string trim $line]; set data ""

      if {$paragraph > 0 && [string length $trimLine] == 0} then {
        # blank line, close paragraph.
        if {[info exists methods($name)]} then {
          # non-first line, leading line separator.
          append data \n $prefix </para>
        } else {
          # first line, no leading line separator.
          append data $prefix </para>
        }

        incr paragraph -1
      } elseif {[string range $trimLine 0 2] eq "<p>"} then {
        # open paragraph ... maybe one line?
        if {[string range $trimLine end-3 end] eq "</p>"} then {
          set newLine [processLine $line $prefix]

          if {[string length $newLine] > 0} then {
            # one line paragraph, wrap.
            if {[info exists methods($name)]} then {
              # non-first line, leading line separator.
              append data \n $prefix <para>
            } else {
              # first line, no leading line separator.
              append data $prefix <para>
            }
................................................................................

          set newLine [processLine $line $prefix]

          if {[string length $newLine] > 0} then {
            append data \n $prefix $newLine
          }

          incr paragraph
        }
      } else {
        set newLine [processLine $line $prefix]

        if {[string length $newLine] > 0} then {
          if {[info exists methods($name)]} then {
            # non-first line, leading line separator.







|
<
<







|
>
>
>
>
>
>







 







|










|









|

|




|







 







|







46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
      [regexp -- {<h\d(?: |>)} [string range $line 0 3]]} then {
    return ""
  }

  set result $line

  foreach remove [list \
      {<a name=".*?">} {<a href=".*?">} {</a>} {<p>} {</p>}] {


    regsub -all -- $remove $result "" result

    if {[string length [string trim $result]] == 0} then {
      return ""
    }
  }

  foreach escape [list \
      {<b>} {</b>} {<br>} {<dd>} {</dd>} {<dl>} {</dl>} {<dt>} \
      {</dt>} {<li>} {</li>} {<ol>} {</ol>} {<tt>} {</tt>} \
      {<ul>} {</ul>}] {
    regsub -all -- ($escape) $result {<![CDATA[\1]]>} result
  }

  regsub -all -- {&ne;} $result {\&#8800;} result
  regsub -all -- {&#91(?:;)?} $result {[} result
  regsub -all -- {&#93(?:;)?} $result {]} result
  regsub -all -- {<( |\"|\d|=)} $result {\&lt;\1} result
  regsub -all -- {( |\"|\d|=)>} $result {\1\&gt;} result
  regsub -all -- {<blockquote><pre>} $result <para><code> result
  regsub -all -- {</pre></blockquote>} $result </code></para> result
................................................................................
  return $result
}
 
proc extractMethod { name lines pattern prefix indexVarName methodsVarName } {
  upvar 1 $indexVarName index
  upvar 1 $methodsVarName methods

  array set levels {p 0}
  set length [llength $lines]

  while {$index < $length} {
    set line [lindex $lines $index]

    if {[regexp -- $pattern $line]} then {
      break; # stop on this line for outer loop.
    } else {
      set trimLine [string trim $line]; set data ""

      if {$levels(p) > 0 && [string length $trimLine] == 0} then {
        # blank line, close paragraph.
        if {[info exists methods($name)]} then {
          # non-first line, leading line separator.
          append data \n $prefix </para>
        } else {
          # first line, no leading line separator.
          append data $prefix </para>
        }

        incr levels(p) -1
      } elseif {[string range $trimLine 0 2] eq "<p>"} then {
        # open tag ... maybe one line?
        if {[string range $trimLine end-3 end] eq "</p>"} then {
          set newLine [processLine $line $prefix]

          if {[string length $newLine] > 0} then {
            # one line tag, wrap.
            if {[info exists methods($name)]} then {
              # non-first line, leading line separator.
              append data \n $prefix <para>
            } else {
              # first line, no leading line separator.
              append data $prefix <para>
            }
................................................................................

          set newLine [processLine $line $prefix]

          if {[string length $newLine] > 0} then {
            append data \n $prefix $newLine
          }

          incr levels(p)
        }
      } else {
        set newLine [processLine $line $prefix]

        if {[string length $newLine] > 0} then {
          if {[info exists methods($name)]} then {
            # non-first line, leading line separator.

Changes to System.Data.SQLite/ISQLiteNativeModule.cs.

105
106
107
108
109
110
111

112
113
114
115
116
117

118
119
120
121
122
123
124
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
...
870
871
872
873
874
875
876

877
878
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893
...
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
        /// If a column datatype contains the special keyword "HIDDEN"
        /// (in any combination of upper and lower case letters) then that keyword
        /// it is omitted from the column datatype name and the column is marked 
        /// as a hidden column internally. 
        /// A hidden column differs from a normal column in three respects:
        /// </para>
        /// <para>

        ///  Hidden columns are not listed in the dataset returned by 
        ///      "PRAGMA table_info",
        ///  Hidden columns are not included in the expansion of a "*"
        ///      expression in the result set of a SELECT, and
        ///  Hidden columns are not included in the implicit column-list 
        ///      used by an INSERT statement that lacks an explicit column-list. 

        /// </para>
        /// <para>
        /// For example, if the following SQL is passed to sqlite3_declare_vtab():
        /// </para>
        /// <para><code>
        ///    CREATE TABLE x(a HIDDEN VARCHAR(12), b INTEGER, c INTEGER Hidden);
        /// </code></para>
................................................................................
        ///       unsigned char omit;      /* Do not code a test for this constraint */
        ///     } *const aConstraintUsage;
        ///     int idxNum;                /* Number used to identify the index */
        ///     char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
        ///     int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
        ///     int orderByConsumed;       /* True if output is already ordered */
        ///     double estimatedCost;      /* Estimated cost of using this index */
        ///     /* Fields below are only available in SQLite 3.8.2 and later */
        ///     sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
        ///     /* Fields below are only available in SQLite 3.9.0 and later */
        ///     int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
        ///   };
        /// </code></para>
        /// <para>
        /// Please note the warnings on the "estimatedRows" and "idxFlags" field.
        /// These fields were added with SQLite versions 3.8.2 and 3.9.0, respectively. 
        /// Any extension that reads or writes these fields must first check that the 
................................................................................
        /// The SQLite core invokes this method in order to find the value for 
        /// the N-th column of the current row. N is zero-based so the first column 
        /// is numbered 0. 
        /// The xColumn method may return its result back to SQLite using one of the
        /// following interface:
        /// </para>
        /// <para>

        ///  sqlite3_result_blob()
        ///  sqlite3_result_double()
        ///  sqlite3_result_int()
        ///  sqlite3_result_int64()
        ///  sqlite3_result_null()
        ///  sqlite3_result_text()
        ///  sqlite3_result_text16()
        ///  sqlite3_result_text16le()
        ///  sqlite3_result_text16be()
        ///  sqlite3_result_zeroblob()

        /// </para>
        /// <para>
        /// If the xColumn method implementation calls none of the functions above,
        /// then the value of the column defaults to an SQL NULL.
        /// </para>
        /// <para>
        /// To raise an error, the xColumn method should use one of the result_text() 
................................................................................
        /// The value of argc will be 1 for a pure delete operation or N+2 for an insert
        /// or replace or update where N is the number of columns in the table.  
        /// In the previous sentence, N includes any hidden columns.
        /// </para>
        /// <para>
        /// Every argv entry will have a non-NULL value in C but may contain the 
        /// SQL value NULL.  In other words, it is always true that
        /// <tt>argv[i]!=0</tt> for i between 0 and <tt>argc-1</tt>.
        /// However, it might be the case that
        /// <tt>sqlite3_value_type(argv[i])==SQLITE_NULL</tt>.
        /// </para>
        /// <para>
        /// The argv[0] parameter is the rowid of a row in the virtual table 
        /// to be deleted. If argv[0] is an SQL NULL, then no deletion occurs.
        /// </para>
        /// <para>
        /// The argv[1] parameter is the rowid of a new row to be inserted 
................................................................................
        /// this will become the value returned by the sqlite3_last_insert_rowid()
        /// function. Setting this value in all the other cases is a harmless no-op;
        /// the SQLite engine ignores the *pRowid return value if argc==1 or 
        /// argv[1] is not an SQL NULL.
        /// </para>
        /// <para>
        /// Each call to xUpdate will fall into one of cases shown below.
        /// Not that references to argv[i] mean the SQL value
        /// held within the argv[i] object, not the argv[i]
        /// object itself.
        /// </para>
        /// <para><code>
        /// argc = 1

        /// The single row with rowid equal to argv[0] is deleted. No insert occurs.
        /// argc &gt; 1 
        ///  argv[0] = NULL
        /// A new row is inserted with a rowid argv[1] and column values in
        ///        argv[2] and following.  If argv[1] is an SQL NULL,
        ///        the a new unique rowid is generated automatically.
        /// argc &gt; 1 
        ///  argv[0] &#8800; NULL 
        ///  argv[0] = argv[1]
        /// The row with rowid argv[0] is updated with new values 
        ///        in argv[2] and following parameters.
        /// argc &gt; 1 
        ///  argv[0] &#8800; NULL 
        ///  argv[0] &#8800; argv[1]

        ///  The row with rowid argv[0] is updated with rowid argv[1] 
        /// and new values in argv[2] and following parameters. This will occur 
        /// when an SQL statement updates a rowid, as in the statement:
        /// <para><code>
        ///    UPDATE table SET rowid=rowid+1 WHERE ...; 
        /// </code></para>

        /// </code></para>
        /// <para>
        /// The xUpdate method must return SQLITE_OK if and only if it is
        /// successful.  If a failure occurs, the xUpdate must return an appropriate
        /// error code.  On a failure, the pVTab->zErrMsg element may optionally
        /// be replaced with error message text stored in memory allocated from SQLite 
        /// using functions such as sqlite3_mprintf() or sqlite3_malloc().







>
|

|

|

>







 







|

|







 







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







 







|

|







 







|




|
>
|
<
|
|


|
<
<
|

<
<
<
>
|





>







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
...
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
....
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021


1022
1023



1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
        /// If a column datatype contains the special keyword "HIDDEN"
        /// (in any combination of upper and lower case letters) then that keyword
        /// it is omitted from the column datatype name and the column is marked 
        /// as a hidden column internally. 
        /// A hidden column differs from a normal column in three respects:
        /// </para>
        /// <para>
        /// <![CDATA[<ul>]]>
        /// <![CDATA[<li>]]> Hidden columns are not listed in the dataset returned by 
        ///      "PRAGMA table_info",
        /// <![CDATA[<li>]]> Hidden columns are not included in the expansion of a "*"
        ///      expression in the result set of a SELECT, and
        /// <![CDATA[<li>]]> Hidden columns are not included in the implicit column-list 
        ///      used by an INSERT statement that lacks an explicit column-list. 
        /// <![CDATA[</ul>]]>
        /// </para>
        /// <para>
        /// For example, if the following SQL is passed to sqlite3_declare_vtab():
        /// </para>
        /// <para><code>
        ///    CREATE TABLE x(a HIDDEN VARCHAR(12), b INTEGER, c INTEGER Hidden);
        /// </code></para>
................................................................................
        ///       unsigned char omit;      /* Do not code a test for this constraint */
        ///     } *const aConstraintUsage;
        ///     int idxNum;                /* Number used to identify the index */
        ///     char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
        ///     int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
        ///     int orderByConsumed;       /* True if output is already ordered */
        ///     double estimatedCost;      /* Estimated cost of using this index */
        ///     <![CDATA[<b>]]>/* Fields below are only available in SQLite 3.8.2 and later */<![CDATA[</b>]]>
        ///     sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
        ///     <![CDATA[<b>]]>/* Fields below are only available in SQLite 3.9.0 and later */<![CDATA[</b>]]>
        ///     int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
        ///   };
        /// </code></para>
        /// <para>
        /// Please note the warnings on the "estimatedRows" and "idxFlags" field.
        /// These fields were added with SQLite versions 3.8.2 and 3.9.0, respectively. 
        /// Any extension that reads or writes these fields must first check that the 
................................................................................
        /// The SQLite core invokes this method in order to find the value for 
        /// the N-th column of the current row. N is zero-based so the first column 
        /// is numbered 0. 
        /// The xColumn method may return its result back to SQLite using one of the
        /// following interface:
        /// </para>
        /// <para>
        /// <![CDATA[<ul>]]>
        /// <![CDATA[<li>]]> sqlite3_result_blob()
        /// <![CDATA[<li>]]> sqlite3_result_double()
        /// <![CDATA[<li>]]> sqlite3_result_int()
        /// <![CDATA[<li>]]> sqlite3_result_int64()
        /// <![CDATA[<li>]]> sqlite3_result_null()
        /// <![CDATA[<li>]]> sqlite3_result_text()
        /// <![CDATA[<li>]]> sqlite3_result_text16()
        /// <![CDATA[<li>]]> sqlite3_result_text16le()
        /// <![CDATA[<li>]]> sqlite3_result_text16be()
        /// <![CDATA[<li>]]> sqlite3_result_zeroblob()
        /// <![CDATA[</ul>]]>
        /// </para>
        /// <para>
        /// If the xColumn method implementation calls none of the functions above,
        /// then the value of the column defaults to an SQL NULL.
        /// </para>
        /// <para>
        /// To raise an error, the xColumn method should use one of the result_text() 
................................................................................
        /// The value of argc will be 1 for a pure delete operation or N+2 for an insert
        /// or replace or update where N is the number of columns in the table.  
        /// In the previous sentence, N includes any hidden columns.
        /// </para>
        /// <para>
        /// Every argv entry will have a non-NULL value in C but may contain the 
        /// SQL value NULL.  In other words, it is always true that
        /// <![CDATA[<tt>]]>argv[i]!=0<![CDATA[</tt>]]> for <![CDATA[<b>]]>i<![CDATA[</b>]]> between 0 and <![CDATA[<tt>]]>argc-1<![CDATA[</tt>]]>.
        /// However, it might be the case that
        /// <![CDATA[<tt>]]>sqlite3_value_type(argv[i])==SQLITE_NULL<![CDATA[</tt>]]>.
        /// </para>
        /// <para>
        /// The argv[0] parameter is the rowid of a row in the virtual table 
        /// to be deleted. If argv[0] is an SQL NULL, then no deletion occurs.
        /// </para>
        /// <para>
        /// The argv[1] parameter is the rowid of a new row to be inserted 
................................................................................
        /// this will become the value returned by the sqlite3_last_insert_rowid()
        /// function. Setting this value in all the other cases is a harmless no-op;
        /// the SQLite engine ignores the *pRowid return value if argc==1 or 
        /// argv[1] is not an SQL NULL.
        /// </para>
        /// <para>
        /// Each call to xUpdate will fall into one of cases shown below.
        /// Not that references to <![CDATA[<b>]]>argv[i]<![CDATA[</b>]]> mean the SQL value
        /// held within the argv[i] object, not the argv[i]
        /// object itself.
        /// </para>
        /// <para><code>
        /// <![CDATA[<dl>]]>
        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc = 1<![CDATA[</b>]]>
        /// <![CDATA[<dd>]]>The single row with rowid equal to argv[0] is deleted. No insert occurs.

        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc &gt; 1 <![CDATA[<br>]]> argv[0] = NULL<![CDATA[</b>]]>
        /// <![CDATA[<dd>]]>A new row is inserted with a rowid argv[1] and column values in
        ///        argv[2] and following.  If argv[1] is an SQL NULL,
        ///        the a new unique rowid is generated automatically.
        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc &gt; 1 <![CDATA[<br>]]> argv[0] &#8800; NULL <![CDATA[<br>]]> argv[0] = argv[1]<![CDATA[</b>]]>


        /// <![CDATA[<dd>]]>The row with rowid argv[0] is updated with new values 
        ///        in argv[2] and following parameters.



        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc &gt; 1 <![CDATA[<br>]]> argv[0] &#8800; NULL <![CDATA[<br>]]> argv[0] &#8800; argv[1]<![CDATA[</b>]]>
        /// <![CDATA[<dd>]]> The row with rowid argv[0] is updated with rowid argv[1] 
        /// and new values in argv[2] and following parameters. This will occur 
        /// when an SQL statement updates a rowid, as in the statement:
        /// <para><code>
        ///    UPDATE table SET rowid=rowid+1 WHERE ...; 
        /// </code></para>
        /// <![CDATA[</dl>]]>
        /// </code></para>
        /// <para>
        /// The xUpdate method must return SQLITE_OK if and only if it is
        /// successful.  If a failure occurs, the xUpdate must return an appropriate
        /// error code.  On a failure, the pVTab->zErrMsg element may optionally
        /// be replaced with error message text stored in memory allocated from SQLite 
        /// using functions such as sqlite3_mprintf() or sqlite3_malloc().