mirror of
https://github.com/tstack/lnav.git
synced 2024-09-11 13:05:51 +03:00
[sqlite] add an xml/xpath extension
This commit is contained in:
parent
9ed3a80326
commit
4ca6fd7bfd
2
NEWS
2
NEWS
@ -2,6 +2,8 @@ lnav v0.9.1:
|
||||
Features:
|
||||
* Added the ':filter-expr' command to filter log messages based on an SQL
|
||||
expression. This command allows much greater control over filtering.
|
||||
* Added an 'xpath()' table-valued function for extracting values from
|
||||
strings containing XML snippets.
|
||||
* Added the ':prompt' command to allow for more customization of prompts.
|
||||
Combined with a custom keymapping, you can now open a prompt and prefill
|
||||
it with a given value. For example, a key could be bound to the
|
||||
|
@ -289,6 +289,7 @@ AC_CONFIG_FILES([src/Makefile])
|
||||
AC_CONFIG_FILES([src/base/Makefile])
|
||||
AC_CONFIG_FILES([src/fmtlib/Makefile])
|
||||
AC_CONFIG_FILES([src/pcrepp/Makefile])
|
||||
AC_CONFIG_FILES([src/pugixml/Makefile])
|
||||
AC_CONFIG_FILES([src/yajl/Makefile])
|
||||
AC_CONFIG_FILES([src/yajlpp/Makefile])
|
||||
AC_CONFIG_FILES([test/Makefile])
|
||||
|
@ -291,6 +291,7 @@ add_library(diag STATIC
|
||||
papertrail_proc.cc
|
||||
ptimec_rt.cc
|
||||
pretty_printer.cc
|
||||
pugixml/pugixml.cpp
|
||||
readline_callbacks.cc
|
||||
readline_curses.cc
|
||||
readline_highlighters.cc
|
||||
@ -330,6 +331,7 @@ add_library(diag STATIC
|
||||
vt52_curses.cc
|
||||
vtab_module.cc
|
||||
log_vtab_impl.cc
|
||||
xpath_vtab.cc
|
||||
xterm_mouse.cc
|
||||
yajlpp/yajlpp.cc
|
||||
yajl/yajl.c
|
||||
@ -407,6 +409,8 @@ add_library(diag STATIC
|
||||
pretty_printer.hh
|
||||
preview_status_source.hh
|
||||
ptimec.hh
|
||||
pugixml/pugiconfig.hpp
|
||||
pugixml/pugixml.hpp
|
||||
readline_callbacks.hh
|
||||
readline_possibilities.hh
|
||||
regexp_vtab.hh
|
||||
@ -444,6 +448,7 @@ add_library(diag STATIC
|
||||
vtab_module_json.hh
|
||||
yajlpp/yajlpp.hh
|
||||
yajlpp/yajlpp_def.hh
|
||||
xpath_vtab.hh
|
||||
|
||||
mapbox/recursive_wrapper.hpp
|
||||
mapbox/variant.hpp
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
SUBDIRS = base fmtlib pcrepp yajl yajlpp .
|
||||
SUBDIRS = base fmtlib pcrepp pugixml yajl yajlpp .
|
||||
|
||||
bin_PROGRAMS = lnav
|
||||
|
||||
@ -224,6 +224,7 @@ LDADD = \
|
||||
base/libbase.a \
|
||||
fmtlib/libcppfmt.a \
|
||||
pcrepp/libpcrepp.a \
|
||||
pugixml/libpugixml.a \
|
||||
yajl/libyajl.a \
|
||||
yajlpp/libyajlpp.a \
|
||||
$(READLINE_LIBS) \
|
||||
@ -369,6 +370,7 @@ noinst_HEADERS = \
|
||||
vtab_module_json.hh \
|
||||
log_vtab_impl.hh \
|
||||
log_format_impls.cc \
|
||||
xpath_vtab.hh \
|
||||
xterm_mouse.hh \
|
||||
spookyhash/SpookyV2.h \
|
||||
ghc/filesystem.hpp \
|
||||
@ -484,6 +486,7 @@ libdiag_a_SOURCES = \
|
||||
vt52_curses.cc \
|
||||
vtab_module.cc \
|
||||
log_vtab_impl.cc \
|
||||
xpath_vtab.cc \
|
||||
xterm_mouse.cc \
|
||||
spookyhash/SpookyV2.cpp
|
||||
|
||||
|
@ -838,7 +838,7 @@ char(*X*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -874,7 +874,7 @@ charindex(*needle*, *haystack*, *\[start\]*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1159,7 +1159,7 @@ endswith(*str*, *suffix*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1220,7 +1220,7 @@ extract(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1386,7 +1386,7 @@ group_concat(*X*, *\[sep\]*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1413,7 +1413,7 @@ group_spooky_hash(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1490,7 +1490,7 @@ instr(*haystack*, *needle*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1873,7 +1873,7 @@ leftstr(*str*, *N*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -1900,7 +1900,7 @@ length(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2082,7 +2082,7 @@ lower(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2117,7 +2117,7 @@ ltrim(*str*, *\[chars\]*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2289,7 +2289,7 @@ padc(*str*, *len*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2324,7 +2324,7 @@ padl(*str*, *len*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2359,7 +2359,7 @@ padr(*str*, *len*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2466,7 +2466,7 @@ printf(*format*, *X*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2493,7 +2493,7 @@ proper(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2692,7 +2692,7 @@ regexp_capture(*string*, *pattern*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2734,7 +2734,7 @@ regexp_match(*re*, *str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_replace`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_replace`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2770,7 +2770,7 @@ regexp_replace(*str*, *re*, *repl*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_match`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_match`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2806,7 +2806,7 @@ replace(*str*, *old*, *replacement*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2834,7 +2834,7 @@ replicate(*str*, *N*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2861,7 +2861,7 @@ reverse(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -2896,7 +2896,7 @@ rightstr(*str*, *N*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3000,7 +3000,7 @@ rtrim(*str*, *\[chars\]*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3089,7 +3089,7 @@ spooky_hash(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3212,7 +3212,7 @@ startswith(*str*, *prefix*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3240,7 +3240,7 @@ strfilter(*source*, *include*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3333,7 +3333,7 @@ substr(*str*, *start*, *\[size\]*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3548,7 +3548,7 @@ trim(*str*, *\[chars\]*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`unicode`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3606,7 +3606,7 @@ unicode(*X*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`upper`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`upper`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
@ -3648,7 +3648,53 @@ upper(*str*)
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`xpath`
|
||||
|
||||
----
|
||||
|
||||
|
||||
.. _xpath:
|
||||
|
||||
xpath(*xpath*, *xmldoc*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A table-valued function that executes an xpath expression over an XML string and returns the selected values.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* **xpath\*** --- The XPATH expression to evaluate over the XML document.
|
||||
* **xmldoc\*** --- The XML document as a string.
|
||||
|
||||
**Examples:**
|
||||
|
||||
To select the XML nodes on the path '/abc/def':
|
||||
|
||||
.. code-block:: custsqlite
|
||||
|
||||
;SELECT * FROM xpath('/abc/def', '<abc><def a="b">Hello</def><def>Bye</def></abc>')
|
||||
result node_path node_attr node_text
|
||||
<def a="b">Hello</def> /abc/def[1] {"a":"b"} Hello
|
||||
<def>Bye</def> /abc/def[2] {} Bye
|
||||
|
||||
To select all 'a' attributes on the path '/abc/def':
|
||||
|
||||
.. code-block:: custsqlite
|
||||
|
||||
;SELECT * FROM xpath('/abc/def/@a', '<abc><def a="b">Hello</def><def>Bye</def></abc>')
|
||||
result node_path node_attr node_text
|
||||
b /abc/def[1]/@a {"a":"b"} Hello
|
||||
|
||||
To select the text nodes on the path '/abc/def':
|
||||
|
||||
.. code-block:: custsqlite
|
||||
|
||||
;SELECT * FROM xpath('/abc/def/text()', '<abc><def a="b">Hello ★</def></abc>')
|
||||
result node_path node_attr node_text
|
||||
Hello ★ /abc/def/text() {} Hello ★
|
||||
|
||||
**See Also:**
|
||||
|
||||
:ref:`char`, :ref:`charindex`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
|
||||
|
||||
----
|
||||
|
||||
|
@ -118,6 +118,7 @@
|
||||
#include "file_vtab.hh"
|
||||
#include "regexp_vtab.hh"
|
||||
#include "fstat_vtab.hh"
|
||||
#include "xpath_vtab.hh"
|
||||
#include "textfile_highlighters.hh"
|
||||
#include "base/future_util.hh"
|
||||
|
||||
@ -2184,6 +2185,7 @@ int main(int argc, char *argv[])
|
||||
register_views_vtab(lnav_data.ld_db.in());
|
||||
register_file_vtab(lnav_data.ld_db.in(), lnav_data.ld_active_files);
|
||||
register_regexp_vtab(lnav_data.ld_db.in());
|
||||
register_xpath_vtab(lnav_data.ld_db.in());
|
||||
register_fstat_vtab(lnav_data.ld_db.in());
|
||||
|
||||
lnav_data.ld_vtab_manager = std::make_unique<log_vtab_manager>(
|
||||
|
9
src/pugixml/Makefile.am
Normal file
9
src/pugixml/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
noinst_LIBRARIES = libpugixml.a
|
||||
|
||||
noinst_HEADERS = \
|
||||
pugiconfig.hpp \
|
||||
pugixml.hpp
|
||||
|
||||
libpugixml_a_SOURCES = \
|
||||
pugixml.cpp
|
77
src/pugixml/pugiconfig.hpp
Normal file
77
src/pugixml/pugiconfig.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* pugixml parser - version 1.11
|
||||
* --------------------------------------------------------
|
||||
* Copyright (C) 2006-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* Report bugs and download new versions at https://pugixml.org/
|
||||
*
|
||||
* This library is distributed under the MIT License. See notice at the end
|
||||
* of this file.
|
||||
*
|
||||
* This work is based on the pugxml parser, which is:
|
||||
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||
*/
|
||||
|
||||
#ifndef HEADER_PUGICONFIG_HPP
|
||||
#define HEADER_PUGICONFIG_HPP
|
||||
|
||||
// Uncomment this to enable wchar_t mode
|
||||
// #define PUGIXML_WCHAR_MODE
|
||||
|
||||
// Uncomment this to enable compact mode
|
||||
// #define PUGIXML_COMPACT
|
||||
|
||||
// Uncomment this to disable XPath
|
||||
// #define PUGIXML_NO_XPATH
|
||||
|
||||
// Uncomment this to disable STL
|
||||
// #define PUGIXML_NO_STL
|
||||
|
||||
// Uncomment this to disable exceptions
|
||||
#define PUGIXML_NO_EXCEPTIONS
|
||||
|
||||
// Set this to control attributes for public classes/functions, i.e.:
|
||||
// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
|
||||
// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
|
||||
// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
|
||||
// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
|
||||
|
||||
// Tune these constants to adjust memory-related behavior
|
||||
// #define PUGIXML_MEMORY_PAGE_SIZE 32768
|
||||
// #define PUGIXML_MEMORY_OUTPUT_STACK 10240
|
||||
// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
|
||||
|
||||
// Tune this constant to adjust max nesting for XPath queries
|
||||
// #define PUGIXML_XPATH_DEPTH_LIMIT 1024
|
||||
|
||||
// Uncomment this to switch to header-only version
|
||||
// #define PUGIXML_HEADER_ONLY
|
||||
|
||||
// Uncomment this to enable long long support
|
||||
// #define PUGIXML_HAS_LONG_LONG
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copyright (c) 2006-2020 Arseny Kapoulkine
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
13020
src/pugixml/pugixml.cpp
Normal file
13020
src/pugixml/pugixml.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1499
src/pugixml/pugixml.hpp
Normal file
1499
src/pugixml/pugixml.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@
|
||||
#include "elem_to_json.hh"
|
||||
#include "vtab_module.hh"
|
||||
#include "vtab_module_json.hh"
|
||||
#include "safe/safe.h"
|
||||
#include "spookyhash/SpookyV2.h"
|
||||
|
||||
#include "optional.hpp"
|
||||
@ -43,12 +44,14 @@ typedef struct {
|
||||
|
||||
static cache_entry *find_re(const char *re)
|
||||
{
|
||||
static unordered_map<string, cache_entry> CACHE;
|
||||
using safe_cache = safe::Safe<unordered_map<string, cache_entry>>;
|
||||
static safe_cache CACHE;
|
||||
|
||||
safe::WriteAccess<safe_cache> wcache(CACHE);
|
||||
string re_str = re;
|
||||
auto iter = CACHE.find(re_str);
|
||||
auto iter = wcache->find(re_str);
|
||||
|
||||
if (iter == CACHE.end()) {
|
||||
if (iter == wcache->end()) {
|
||||
cache_entry c;
|
||||
|
||||
c.re2 = make_shared<pcrepp>(re_str);
|
||||
@ -59,9 +62,9 @@ static cache_entry *find_re(const char *re)
|
||||
e2 = sqlite3_mprintf("%s: %s", re, c.re->error().c_str());
|
||||
throw pcrepp::error(e2.in(), 0);
|
||||
}
|
||||
CACHE[re_str] = c;
|
||||
auto pair = wcache->insert(std::make_pair(re_str, c));
|
||||
|
||||
iter = CACHE.find(re_str);
|
||||
iter = pair.first;
|
||||
}
|
||||
|
||||
return &iter->second;
|
||||
|
@ -376,7 +376,7 @@ void execute_examples()
|
||||
attr_line_t al;
|
||||
dos.list_value_for_overlay(db_tc,
|
||||
0, 1,
|
||||
vis_line_t(0),
|
||||
0_vl,
|
||||
al);
|
||||
result.append(al);
|
||||
for (int lpc = 0;
|
||||
@ -387,6 +387,10 @@ void execute_examples()
|
||||
false);
|
||||
dls.text_attrs_for_line(db_tc, lpc,
|
||||
al.get_attrs());
|
||||
std::replace(al.get_string().begin(),
|
||||
al.get_string().end(),
|
||||
'\n',
|
||||
' ');
|
||||
result.append("\n")
|
||||
.append(al);
|
||||
}
|
||||
|
411
src/xpath_vtab.cc
Normal file
411
src/xpath_vtab.cc
Normal file
@ -0,0 +1,411 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/lnav_log.hh"
|
||||
#include "pugixml/pugixml.hpp"
|
||||
#include "sql_util.hh"
|
||||
#include "vtab_module.hh"
|
||||
#include "yajlpp/yajlpp.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum {
|
||||
XP_COL_RESULT,
|
||||
XP_COL_NODE_PATH,
|
||||
XP_COL_NODE_ATTR,
|
||||
XP_COL_NODE_TEXT,
|
||||
XP_COL_XPATH,
|
||||
XP_COL_VALUE,
|
||||
};
|
||||
|
||||
static
|
||||
thread_local std::unordered_map<std::string, pugi::xpath_query> QUERY_CACHE;
|
||||
|
||||
static
|
||||
pugi::xpath_query checkout_query(const std::string& query)
|
||||
{
|
||||
auto iter = QUERY_CACHE.find(query);
|
||||
if (iter == QUERY_CACHE.end()) {
|
||||
auto xquery = pugi::xpath_query(query.c_str());
|
||||
|
||||
if (!xquery) {
|
||||
return xquery;
|
||||
}
|
||||
|
||||
auto pair = QUERY_CACHE.emplace(query, std::move(xquery));
|
||||
|
||||
iter = pair.first;
|
||||
}
|
||||
|
||||
auto retval = std::move(iter->second);
|
||||
|
||||
QUERY_CACHE.erase(iter);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static
|
||||
void checkin_query(const std::string& query_str, pugi::xpath_query query)
|
||||
{
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
QUERY_CACHE[query_str] = std::move(query);
|
||||
}
|
||||
|
||||
static
|
||||
std::string get_actual_path(const pugi::xml_node& node)
|
||||
{
|
||||
std::string retval;
|
||||
auto curr = node;
|
||||
|
||||
while (curr) {
|
||||
switch (curr.type()) {
|
||||
case pugi::node_null:
|
||||
break;
|
||||
case pugi::node_pcdata:
|
||||
retval += "text()";
|
||||
break;
|
||||
default: {
|
||||
auto name = std::string(curr.name());
|
||||
|
||||
if (curr.previous_sibling(curr.name()) ||
|
||||
curr.next_sibling(curr.name())) {
|
||||
auto sibling = curr;
|
||||
int index = 0;
|
||||
|
||||
while (sibling) {
|
||||
index += 1;
|
||||
sibling = sibling.previous_sibling(curr.name());
|
||||
}
|
||||
|
||||
name += "[" + std::to_string(index) + "]";
|
||||
}
|
||||
if (retval.empty()) {
|
||||
retval = name;
|
||||
} else {
|
||||
retval = name + std::string("/") + retval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
curr = curr.parent();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct xpath_vtab {
|
||||
static constexpr const char *CREATE_STMT = R"(
|
||||
-- The xpath() table-valued function allows you to execute an xpath expression
|
||||
CREATE TABLE xpath (
|
||||
result text, -- The result of the xpath expression
|
||||
node_path text, -- The absolute path to the node selected by the expression
|
||||
node_attr text, -- The node attributes stored in a JSON object
|
||||
node_text text, -- The text portion of the node selected by the expression
|
||||
|
||||
xpath text HIDDEN,
|
||||
value text HIDDEN
|
||||
);
|
||||
)";
|
||||
|
||||
struct cursor {
|
||||
sqlite3_vtab_cursor base;
|
||||
sqlite3_int64 c_rowid{0};
|
||||
string c_xpath;
|
||||
string c_value;
|
||||
pugi::xpath_query c_query;
|
||||
pugi::xml_document c_doc;
|
||||
pugi::xpath_node_set c_results;
|
||||
|
||||
cursor(sqlite3_vtab *vt)
|
||||
: base({vt}) {
|
||||
};
|
||||
|
||||
~cursor() {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
int reset() {
|
||||
this->c_rowid = 0;
|
||||
checkin_query(this->c_xpath, std::move(this->c_query));
|
||||
|
||||
return SQLITE_OK;
|
||||
};
|
||||
|
||||
int next() {
|
||||
this->c_rowid += 1;
|
||||
|
||||
return SQLITE_OK;
|
||||
};
|
||||
|
||||
int eof() {
|
||||
return this->c_rowid >= this->c_results.size();
|
||||
};
|
||||
|
||||
int get_rowid(sqlite3_int64 &rowid_out) {
|
||||
rowid_out = this->c_rowid;
|
||||
|
||||
return SQLITE_OK;
|
||||
};
|
||||
};
|
||||
|
||||
int get_column(const cursor &vc, sqlite3_context *ctx, int col) {
|
||||
switch (col) {
|
||||
case XP_COL_RESULT: {
|
||||
auto& xpath_node = vc.c_results[vc.c_rowid];
|
||||
|
||||
if (xpath_node.node()) {
|
||||
ostringstream oss;
|
||||
|
||||
// XXX avoid the extra allocs
|
||||
xpath_node.node().print(oss);
|
||||
auto node_xml = oss.str();
|
||||
sqlite3_result_text(ctx,
|
||||
node_xml.c_str(),
|
||||
node_xml.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
} else if (xpath_node.attribute()) {
|
||||
sqlite3_result_text(ctx,
|
||||
xpath_node.attribute().value(),
|
||||
-1,
|
||||
SQLITE_TRANSIENT);
|
||||
} else {
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XP_COL_NODE_PATH: {
|
||||
auto& xpath_node = vc.c_results[vc.c_rowid];
|
||||
auto x_node = xpath_node.node();
|
||||
auto x_attr = xpath_node.attribute();
|
||||
|
||||
if (x_node || x_attr) {
|
||||
if (!x_node) {
|
||||
x_node = xpath_node.parent();
|
||||
}
|
||||
|
||||
auto node_path = get_actual_path(x_node);
|
||||
if (x_attr) {
|
||||
node_path += "/@" + std::string(x_attr.name());
|
||||
}
|
||||
sqlite3_result_text(ctx,
|
||||
node_path.c_str(),
|
||||
node_path.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
} else {
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XP_COL_NODE_ATTR: {
|
||||
auto& xpath_node = vc.c_results[vc.c_rowid];
|
||||
auto x_node = xpath_node.node();
|
||||
auto x_attr = xpath_node.attribute();
|
||||
|
||||
if (x_node || x_attr) {
|
||||
if (!x_node) {
|
||||
x_node = xpath_node.parent();
|
||||
}
|
||||
|
||||
yajlpp_gen gen;
|
||||
|
||||
yajl_gen_config(gen, yajl_gen_beautify, false);
|
||||
|
||||
{
|
||||
yajlpp_map attrs(gen);
|
||||
|
||||
for (const auto& attr : x_node.attributes()) {
|
||||
attrs.gen(attr.name());
|
||||
attrs.gen(attr.value());
|
||||
}
|
||||
}
|
||||
|
||||
auto sf = gen.to_string_fragment();
|
||||
|
||||
sqlite3_result_text(ctx,
|
||||
sf.data(),
|
||||
sf.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
sqlite3_result_subtype(ctx, 'J');
|
||||
} else {
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XP_COL_NODE_TEXT: {
|
||||
auto& xpath_node = vc.c_results[vc.c_rowid];
|
||||
auto x_node = xpath_node.node();
|
||||
auto x_attr = xpath_node.attribute();
|
||||
|
||||
if (x_node || x_attr) {
|
||||
if (!x_node) {
|
||||
x_node = xpath_node.parent();
|
||||
}
|
||||
|
||||
auto node_text = x_node.text();
|
||||
|
||||
sqlite3_result_text(ctx,
|
||||
node_text.get(),
|
||||
-1,
|
||||
SQLITE_TRANSIENT);
|
||||
} else {
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XP_COL_XPATH:
|
||||
sqlite3_result_text(ctx,
|
||||
vc.c_xpath.c_str(),
|
||||
vc.c_xpath.length(),
|
||||
SQLITE_STATIC);
|
||||
break;
|
||||
case XP_COL_VALUE:
|
||||
sqlite3_result_text(ctx,
|
||||
vc.c_value.c_str(),
|
||||
vc.c_value.length(),
|
||||
SQLITE_STATIC);
|
||||
break;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static int rcBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo)
|
||||
{
|
||||
vtab_index_constraints vic(pIdxInfo);
|
||||
vtab_index_usage viu(pIdxInfo);
|
||||
|
||||
for (auto iter = vic.begin(); iter != vic.end(); ++iter) {
|
||||
if (iter->op != SQLITE_INDEX_CONSTRAINT_EQ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (iter->iColumn) {
|
||||
case XP_COL_VALUE:
|
||||
case XP_COL_XPATH:
|
||||
viu.column_used(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
viu.allocate_args(2);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int rcFilter(sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv)
|
||||
{
|
||||
auto *pCur = (xpath_vtab::cursor *)pVtabCursor;
|
||||
|
||||
if (argc != 2) {
|
||||
pCur->c_xpath.clear();
|
||||
pCur->c_value.clear();
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
pCur->c_value = (const char *) sqlite3_value_text(argv[1]);
|
||||
auto parse_res = pCur->c_doc.load_string(pCur->c_value.c_str());
|
||||
if (!parse_res) {
|
||||
pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
|
||||
"Invalid XML document at offset %d: %s",
|
||||
parse_res.offset, parse_res.description());
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
pCur->c_xpath = (const char *) sqlite3_value_text(argv[0]);
|
||||
pCur->c_query = checkout_query(pCur->c_xpath);
|
||||
if (!pCur->c_query) {
|
||||
auto& res = pCur->c_query.result();
|
||||
pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
|
||||
"Invalid XPATH expression at offset %d: %s",
|
||||
res.offset, res.description());
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
pCur->c_rowid = 0;
|
||||
pCur->c_results = pCur->c_doc.select_nodes(pCur->c_query);
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int register_xpath_vtab(sqlite3 *db)
|
||||
{
|
||||
static vtab_module<tvt_no_update<xpath_vtab>> XPATH_MODULE;
|
||||
static help_text xpath_help = help_text("xpath",
|
||||
"A table-valued function that executes an xpath expression over an XML "
|
||||
"string and returns the selected values.")
|
||||
.sql_table_valued_function()
|
||||
.with_parameter({"xpath",
|
||||
"The XPATH expression to evaluate over the XML document."})
|
||||
.with_parameter({"xmldoc",
|
||||
"The XML document as a string."})
|
||||
.with_result({"result",
|
||||
"The result of the XPATH expression."})
|
||||
.with_result({"node_path",
|
||||
"The absolute path to the node containing the result."})
|
||||
.with_result({"node_attr",
|
||||
"The node's attributes stored in JSON object."})
|
||||
.with_result({"node_text",
|
||||
"The node's text value."})
|
||||
.with_tags({"string", "xml"})
|
||||
.with_example({
|
||||
"To select the XML nodes on the path '/abc/def'",
|
||||
"SELECT * FROM xpath('/abc/def', '<abc><def a=\"b\">Hello</def><def>Bye</def></abc>')"
|
||||
})
|
||||
.with_example({
|
||||
"To select all 'a' attributes on the path '/abc/def'",
|
||||
"SELECT * FROM xpath('/abc/def/@a', '<abc><def a=\"b\">Hello</def><def>Bye</def></abc>')"
|
||||
})
|
||||
.with_example({
|
||||
"To select the text nodes on the path '/abc/def'",
|
||||
"SELECT * FROM xpath('/abc/def/text()', '<abc><def a=\"b\">Hello ★</def></abc>')"
|
||||
});
|
||||
|
||||
int rc;
|
||||
|
||||
XPATH_MODULE.vm_module.xBestIndex = rcBestIndex;
|
||||
XPATH_MODULE.vm_module.xFilter = rcFilter;
|
||||
|
||||
rc = XPATH_MODULE.create(db, "xpath");
|
||||
sqlite_function_help.insert(make_pair("xpath", &xpath_help));
|
||||
xpath_help.index_tags();
|
||||
|
||||
ensure(rc == SQLITE_OK);
|
||||
|
||||
return rc;
|
||||
}
|
37
src/xpath_vtab.hh
Normal file
37
src/xpath_vtab.hh
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef xpath_vtab_hh
|
||||
#define xpath_vtab_hh
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
int register_xpath_vtab(sqlite3 *db);
|
||||
|
||||
#endif
|
@ -77,6 +77,7 @@ LDADD = \
|
||||
$(top_builddir)/src/yajl/libyajl.a \
|
||||
$(top_builddir)/src/yajlpp/libyajlpp.a \
|
||||
$(top_builddir)/src/base/libbase.a \
|
||||
$(top_builddir)/src/pugixml/libpugixml.a \
|
||||
$(CURSES_LIB) \
|
||||
$(LIBARCHIVE_LIBS) \
|
||||
$(SQLITE3_LIBS) \
|
||||
@ -169,6 +170,7 @@ dist_noinst_SCRIPTS = \
|
||||
test_sql_json_func.sh \
|
||||
test_sql_str_func.sh \
|
||||
test_sql_time_func.sh \
|
||||
test_sql_xml_func.sh \
|
||||
test_sql_fs_func.sh \
|
||||
test_view_colors.sh \
|
||||
test_vt52_curses.sh \
|
||||
@ -337,6 +339,7 @@ TESTS = \
|
||||
test_sql_fs_func.sh \
|
||||
test_sql_str_func.sh \
|
||||
test_sql_time_func.sh \
|
||||
test_sql_xml_func.sh \
|
||||
test_data_parser.sh \
|
||||
test_pretty_print.sh \
|
||||
test_vt52_curses.sh
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "auto_mem.hh"
|
||||
#include "sqlite-extension-func.hh"
|
||||
#include "regexp_vtab.hh"
|
||||
#include "xpath_vtab.hh"
|
||||
|
||||
struct callback_state {
|
||||
int cs_row;
|
||||
@ -92,6 +93,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
register_regexp_vtab(db.in());
|
||||
register_xpath_vtab(db.in());
|
||||
|
||||
if (sqlite3_exec(db.in(),
|
||||
stmt.c_str(),
|
||||
|
@ -1236,7 +1236,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), substr(), trim(), unicode(), upper()
|
||||
startswith(), strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To get a string with the code points 0x48 and 0x49:
|
||||
;SELECT char(0x48, 0x49)
|
||||
@ -1256,7 +1256,7 @@ See Also
|
||||
leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To search for the string 'abc' within 'abcabc' and starting at position 2:
|
||||
;SELECT charindex('abc', 'abcabc', 2)
|
||||
@ -1406,7 +1406,7 @@ See Also
|
||||
leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To test if the string 'notbad.jpg' ends with '.jpg':
|
||||
;SELECT endswith('notbad.jpg', '.jpg')
|
||||
@ -1440,7 +1440,7 @@ See Also
|
||||
leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To extract key/value pairs from a string:
|
||||
;SELECT extract('foo=1 bar=2 name="Rolo Tomassi"')
|
||||
@ -1522,7 +1522,7 @@ See Also
|
||||
leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To concatenate the values of the column 'ex_procname' from the table 'lnav_example_log'
|
||||
:
|
||||
@ -1549,7 +1549,7 @@ See Also
|
||||
length(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(),
|
||||
regexp_capture(), regexp_match(), regexp_replace(), replace(), replicate(),
|
||||
reverse(), rightstr(), rtrim(), spooky_hash(), startswith(), strfilter(),
|
||||
substr(), trim(), unicode(), upper()
|
||||
substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To produce a hash of all of the values of 'column1':
|
||||
;SELECT group_spooky_hash(column1) FROM (VALUES ('abc'), ('123'))
|
||||
@ -1593,7 +1593,7 @@ See Also
|
||||
leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To test get the position of 'b' in the string 'abc':
|
||||
;SELECT instr('abc', 'b')
|
||||
@ -1798,7 +1798,7 @@ See Also
|
||||
instr(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(),
|
||||
regexp_capture(), regexp_match(), regexp_replace(), replace(), replicate(),
|
||||
reverse(), rightstr(), rtrim(), spooky_hash(), startswith(), strfilter(),
|
||||
substr(), trim(), unicode(), upper()
|
||||
substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To get the first character of the string 'abc':
|
||||
;SELECT leftstr('abc', 1)
|
||||
@ -1819,7 +1819,7 @@ See Also
|
||||
instr(), leftstr(), lower(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To get the length of the string 'abc':
|
||||
;SELECT length('abc')
|
||||
@ -1914,7 +1914,7 @@ See Also
|
||||
instr(), leftstr(), length(), ltrim(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To lowercase the string 'AbC':
|
||||
;SELECT lower('AbC')
|
||||
@ -1933,7 +1933,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), padc(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To trim the leading whitespace from the string ' abc':
|
||||
;SELECT ltrim(' abc')
|
||||
@ -2031,7 +2031,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padl(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To pad the string 'abc' to a length of six characters:
|
||||
;SELECT padc('abc', 6) || 'def'
|
||||
@ -2053,7 +2053,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padr(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To pad the string 'abc' to a length of six characters:
|
||||
;SELECT padl('abc', 6)
|
||||
@ -2075,7 +2075,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), printf(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To pad the string 'abc' to a length of six characters:
|
||||
;SELECT padr('abc', 6) || 'def'
|
||||
@ -2131,7 +2131,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
proper(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To substitute 'World' into the string 'Hello, %s!':
|
||||
;SELECT printf('Hello, %s!', 'World')
|
||||
@ -2155,7 +2155,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), regexp_capture(), regexp_match(), regexp_replace(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To capitalize the words in the string 'hello, world!':
|
||||
;SELECT proper('hello, world!')
|
||||
@ -2259,7 +2259,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_match(), regexp_replace(), replace(), replicate(),
|
||||
reverse(), rightstr(), rtrim(), spooky_hash(), startswith(), strfilter(),
|
||||
substr(), trim(), unicode(), upper()
|
||||
substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To extract the key/value pairs 'a'/1 and 'b'/2 from the string 'a=1; b=2':
|
||||
;SELECT * FROM regexp_capture('a=1; b=2', '(\w+)=(\d+)')
|
||||
@ -2277,7 +2277,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_replace(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), substr(), trim(), unicode(), upper()
|
||||
startswith(), strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To capture the digits from the string '123':
|
||||
;SELECT regexp_match('(\d+)', '123')
|
||||
@ -2307,7 +2307,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_match(), replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To replace the word at the start of the string 'Hello, World!' with 'Goodbye':
|
||||
;SELECT regexp_replace('Hello, World!', '^(\w+)', 'Goodbye')
|
||||
@ -2331,7 +2331,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replicate(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To replace the string 'x' with 'z' in 'abc':
|
||||
;SELECT replace('abc', 'x', 'z')
|
||||
@ -2352,7 +2352,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), reverse(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To repeat the string 'abc' three times:
|
||||
;SELECT replicate('abc', 3)
|
||||
@ -2368,7 +2368,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), rightstr(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To reverse the string 'abc':
|
||||
;SELECT reverse('abc')
|
||||
@ -2386,7 +2386,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rtrim(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To get the last character of the string 'abc':
|
||||
;SELECT rightstr('abc', 1)
|
||||
@ -2446,7 +2446,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), spooky_hash(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To trim the whitespace from the end of the string 'abc ':
|
||||
;SELECT rtrim('abc ')
|
||||
@ -2488,7 +2488,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), startswith(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To produce a hash for the string 'Hello, World!':
|
||||
;SELECT spooky_hash('Hello, World!')
|
||||
@ -2560,7 +2560,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
strfilter(), substr(), trim(), unicode(), upper()
|
||||
strfilter(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To test if the string 'foobar' starts with 'foo':
|
||||
;SELECT startswith('foobar', 'foo')
|
||||
@ -2582,7 +2582,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), substr(), trim(), unicode(), upper()
|
||||
startswith(), substr(), trim(), unicode(), upper(), xpath()
|
||||
Example
|
||||
#1 To get the 'b', 'c', and 'd' characters from the string 'abcabc':
|
||||
;SELECT strfilter('abcabc', 'bcd')
|
||||
@ -2630,7 +2630,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), trim(), unicode(), upper()
|
||||
startswith(), strfilter(), trim(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To get the substring starting at the second character until the end of the string 'abc'
|
||||
:
|
||||
@ -2756,7 +2756,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), substr(), unicode(), upper()
|
||||
startswith(), strfilter(), substr(), unicode(), upper(), xpath()
|
||||
Examples
|
||||
#1 To trim whitespace from the start and end of the string ' abc ':
|
||||
;SELECT trim(' abc ')
|
||||
@ -2793,7 +2793,7 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), substr(), trim(), upper()
|
||||
startswith(), strfilter(), substr(), trim(), upper(), xpath()
|
||||
Example
|
||||
#1 To get the unicode code point for the first character of 'abc':
|
||||
;SELECT unicode('abc')
|
||||
@ -2816,13 +2816,44 @@ See Also
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), substr(), trim(), unicode()
|
||||
startswith(), strfilter(), substr(), trim(), unicode(), xpath()
|
||||
Example
|
||||
#1 To uppercase the string 'aBc':
|
||||
;SELECT upper('aBc')
|
||||
|
||||
|
||||
|
||||
Synopsis
|
||||
xpath(xpath, xmldoc) -- A table-valued function that executes an xpath
|
||||
expression over an XML string and returns the selected values.
|
||||
Parameters
|
||||
xpath The XPATH expression to evaluate over the XML document.
|
||||
xmldoc The XML document as a string.
|
||||
Results
|
||||
result The result of the XPATH expression.
|
||||
node_path The absolute path to the node containing the result.
|
||||
node_attr The node's attributes stored in JSON object.
|
||||
node_text The node's text value.
|
||||
See Also
|
||||
char(), charindex(), endswith(), extract(), group_concat(), group_spooky_hash(),
|
||||
instr(), leftstr(), length(), lower(), ltrim(), padc(), padl(), padr(),
|
||||
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
|
||||
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
|
||||
startswith(), strfilter(), substr(), trim(), unicode(), upper()
|
||||
Examples
|
||||
#1 To select the XML nodes on the path '/abc/def':
|
||||
;SELECT * FROM xpath('/abc/def', '<abc><def a="b">Hello</def><def>Bye</def></abc>')
|
||||
|
||||
|
||||
#2 To select all 'a' attributes on the path '/abc/def':
|
||||
;SELECT * FROM xpath('/abc/def/@a', '<abc><def a="b">Hello</def><def>Bye</def></abc>')
|
||||
|
||||
|
||||
#3 To select the text nodes on the path '/abc/def':
|
||||
;SELECT * FROM xpath('/abc/def/text()', '<abc><def a="b">Hello ★</def></abc>')
|
||||
|
||||
|
||||
|
||||
Synopsis
|
||||
zeroblob(N) -- Returns a BLOB consisting of N bytes of 0x00.
|
||||
Parameter
|
||||
|
67
test/formats/xmlmsg/format.json
Normal file
67
test/formats/xmlmsg/format.json
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"xml_msg_log": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"regex": {
|
||||
"std": {
|
||||
"pattern": "^\\[(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3})\\]\\s+(?<level>\\w+)\\s+\\[(?<module>[^:]*):(?<line>\\d+)\\]\\s*(?<body>[^\\n]*)\\n?(?<msg_data>(?:.|\\n)*)"
|
||||
}
|
||||
},
|
||||
"level": {
|
||||
"critical": "CRITICAL",
|
||||
"error": "ERROR",
|
||||
"warning": "WARNING",
|
||||
"info": "INFO",
|
||||
"debug": "DEBUG"
|
||||
},
|
||||
"value": {
|
||||
"module": {
|
||||
"kind": "string",
|
||||
"identifier": true,
|
||||
"description": "Python source module which emitted log entry"
|
||||
},
|
||||
"line": {
|
||||
"kind": "integer",
|
||||
"description": "Line number – in the module – where log entry was emitted"
|
||||
},
|
||||
"head": {
|
||||
"kind": "string",
|
||||
"description": "<head>",
|
||||
"hidden": true
|
||||
},
|
||||
"source": {
|
||||
"kind": "string",
|
||||
"description": "request <source>",
|
||||
"hidden": true
|
||||
},
|
||||
"msg_data": {
|
||||
"kind": "string"
|
||||
}
|
||||
},
|
||||
"highlights": {
|
||||
"client_id": {
|
||||
"pattern": "(?<=>)\\d+(?=<\/client>)",
|
||||
"color": "Orange1",
|
||||
"underline": true
|
||||
},
|
||||
"reply_error": {
|
||||
"pattern": "(?<=<result>)ERROR(?=</result>)",
|
||||
"color": "Red1"
|
||||
}
|
||||
},
|
||||
"sample": [
|
||||
{
|
||||
"line": "[2020-12-10 06:56:41,477] INFO [m:108] Calling 'x' with params:",
|
||||
"level": "info"
|
||||
},
|
||||
{
|
||||
"line": "[2020-12-10 06:56:41,092] DEBUG [m:69] Full request text:\n<?xml version='1.0' encoding='iso-8859-2'?>\n<a-request>\n <head>\n x\n </head>\n <source>\n x\n </source>\n <request>\n <name>\n x\n </name>\n </request>\n</a-request>\n",
|
||||
"level": "debug"
|
||||
},
|
||||
{
|
||||
"line": "[2020-12-10 06:56:41,099] DEBUG [m:85] Full reply text:\n<?xml version='1.0' encoding='iso-8859-2'?>\n<a-reply>\n <head>\n x\n </head>\n <reply>\n <status>\n <result>OK</result>\n </status>\n <name>\n x\n </name>\n </reply>\n <technical-track>\n x\n </technical-track>\n</a-reply>\n",
|
||||
"level": "debug"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
36
test/logfile_xml_msg.0
Normal file
36
test/logfile_xml_msg.0
Normal file
@ -0,0 +1,36 @@
|
||||
[2020-12-10 06:56:41,061] INFO [m:108] Calling 'x' with params:
|
||||
|
||||
[2020-12-10 06:56:41,092] DEBUG [connect.client:69] Full request text:
|
||||
<?xml version='1.0' encoding='iso-8859-2'?>
|
||||
<a-request>
|
||||
<head>
|
||||
x
|
||||
</head>
|
||||
<source>
|
||||
x
|
||||
</source>
|
||||
<request>
|
||||
<name>
|
||||
x
|
||||
</name>
|
||||
</request>
|
||||
</a-request>
|
||||
|
||||
[2020-12-10 06:56:41,099] DEBUG [m:85] Full reply text:
|
||||
<?xml version='1.0' encoding='iso-8859-2'?>
|
||||
<a-reply>
|
||||
<head>
|
||||
x
|
||||
</head>
|
||||
<reply>
|
||||
<status>
|
||||
<result>OK</result>
|
||||
</status>
|
||||
<name>
|
||||
x
|
||||
</name>
|
||||
</reply>
|
||||
<technical-track>
|
||||
x
|
||||
</technical-track>
|
||||
</a-reply>
|
@ -819,7 +819,7 @@ EOF
|
||||
|
||||
|
||||
schema_dump() {
|
||||
${lnav_test} -n -c ';.schema' ${test_dir}/logfile_access_log.0 | head -n18
|
||||
${lnav_test} -n -c ';.schema' ${test_dir}/logfile_access_log.0 | head -n19
|
||||
}
|
||||
|
||||
run_test schema_dump
|
||||
@ -836,6 +836,7 @@ CREATE VIEW lnav_view_filters_and_stats AS
|
||||
SELECT * FROM lnav_view_filters LEFT NATURAL JOIN lnav_view_filter_stats;
|
||||
CREATE VIRTUAL TABLE lnav_file USING lnav_file_impl();
|
||||
CREATE VIRTUAL TABLE regexp_capture USING regexp_capture_impl();
|
||||
CREATE VIRTUAL TABLE xpath USING xpath_impl();
|
||||
CREATE VIRTUAL TABLE fstat USING fstat_impl();
|
||||
CREATE TABLE http_status_codes (
|
||||
status integer PRIMARY KEY,
|
||||
|
40
test/test_sql_xml_func.sh
Normal file
40
test/test_sql_xml_func.sh
Normal file
@ -0,0 +1,40 @@
|
||||
#! /bin/bash
|
||||
|
||||
run_test ./drive_sql "SELECT * FROM xpath('/abc[', '<abc/>')"
|
||||
|
||||
check_error_output "invalid xpath not reported?" <<EOF
|
||||
error: sqlite3_exec failed -- Invalid XPATH expression at offset 5: Unrecognized node test
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "SELECT * FROM xpath('/abc', '<abc')"
|
||||
|
||||
check_error_output "invalid XML not reported?" <<EOF
|
||||
error: sqlite3_exec failed -- Invalid XML document at offset 3: Error parsing start element tag
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "SELECT * FROM xpath('/abc/def', '<abc/>')"
|
||||
|
||||
check_output "got unexpected results" <<EOF
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "SELECT * FROM xpath('/abc/def[@a=\"b\"]', '<abc><def/><def a=\"b\">ghi</def></abc>')"
|
||||
|
||||
check_output "got unexpected results" <<EOF
|
||||
Row 0:
|
||||
Column result: <def a="b">ghi</def>
|
||||
|
||||
Column node_path: /abc/def[2]
|
||||
Column node_attr: {"a":"b"}
|
||||
Column node_text: ghi
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "SELECT * FROM xpath('/abc/def', '<abc><def>Hello ></def></abc>')"
|
||||
|
||||
check_output "got unexpected results" <<EOF
|
||||
Row 0:
|
||||
Column result: <def>Hello ></def>
|
||||
|
||||
Column node_path: /abc/def
|
||||
Column node_attr: {}
|
||||
Column node_text: Hello >
|
||||
EOF
|
Loading…
Reference in New Issue
Block a user