/* Automatically generated by setup.py from tools/shell.py */
"%s%s%s%s",
  "\n"
  "import sys\n"
  "import shlex\n"
  "import os\n"
  "import csv\n"
  "import re\n"
  "import textwrap\n"
  "import time\n"
  "import codecs\n"
  "import base64\n"
  "\n"
  "if sys.platform==\"win32\":\n"
  "    _win_colour=False\n"
  "    try:\n"
  "        import colorama\n"
  "        colorama.init()\n"
  "        del colorama\n"
  "        _win_colour=True\n"
  "    except: # there are several failure reasons, ignore them all\n"
  "        pass\n"
  "\n"
  "\n"
  "class Shell(object):\n"
  "    \"\"\"Implements a SQLite shell\n"
  "\n"
  "    :param stdin: Where to read input from (default sys.stdin)\n"
  "    :param stdout: Where to send output (default sys.stdout)\n"
  "    :param stderr: Where to send errors (default sys.stderr)\n"
  "    :param encoding: Default encoding for files opened/created by the\n"
  "      Shell.  If you want stdin/out/err to use a particular encoding\n"
  "      then you need to provide them `already configured <http://docs.python.org/library/codecs.html#codecs.open>`__ that way.\n"
  "    :param args: This should be program arguments only (ie if\n"
  "      passing in sys.argv do not include sys.argv[0] which is the\n"
  "      program name.  You can also pass in None and then call\n"
  "      :meth:`process_args` if you want to catch any errors\n"
  "      in handling the arguments yourself.\n"
  "    :param db: A existing :class:`Connection` you wish to use\n"
  "\n"
  "    The commands and behaviour are modelled after the `interactive\n"
  "    shell <https://sqlite.org/sqlite.html>`__ that is part of\n"
  "    SQLite.\n"
  "\n"
  "    You can inherit from this class to embed in your own code and user\n"
  "    interface.  Internally everything is handled as unicode.\n"
  "    Conversions only happen at the point of input or output which you\n"
  "    can override in your own code.\n"
  "\n"
  "    This implementation fixes a number of bugs/quirks present in the\n"
  "    sqlite shell.  Its control-C handling is also friendlier.  Some\n"
  "    examples of issues not present in this implementation:\n"
  "\n"
  "    * https://sqlite.org/src/info/c25aab7e7e\n"
  "    * https://sqlite.org/src/info/7b61b6c6ce\n"
  "    * https://sqlite.org/src/info/ee19e690ec\n"
  "    * https://sqlite.org/src/info/2466653295\n"
  "\n"
  "    Errors and diagnostics are only ever sent to error output\n"
  "    (self.stderr) and never to the regular output (self.stdout).  This\n"
  "    means using shell output is always easy and consistent.\n"
  "\n"
  "    Shell commands begin with a dot (eg .help).  They are implemented\n"
  "    as a method named after the command (eg command_help).  The method\n"
  "    is passed one parameter which is the list of arguments to the\n"
  "    command.\n"
  "\n"
  "    Output modes are implemented by functions named after the mode (eg\n"
  "    output_column).\n"
  "\n"
  "    When you request help the help information is automatically\n"
  "    generated from the docstrings for the command and output\n"
  "    functions.\n"
  "\n"
  "    You should not use a Shell object concurrently from multiple\n"
  "    threads.  It is one huge set of state information which would\n"
  "    become inconsistent if used simultaneously, and then give baffling\n"
  "    errors.  It is safe to call methods one at a time from different\n"
  "    threads.  ie it doesn't care what thread calls methods as long as\n"
  "    you don't call more than one concurrently.\n"
  "    \"\"\"\n"
  "\n"
  "    class Error(Exception):\n"
  "        \"\"\"Class raised on errors.  The expectation is that the error\n"
  "        will be displayed by the shell as text so there are no\n"
  "        specific subclasses as the distinctions between different\n"
  "        types of errors doesn't matter.\"\"\"\n"
  "        pass\n"
  "\n"
  "    def __init__(self, stdin=None, stdout=None, stderr=None, encoding=\"utf8\", args=None, db=None):\n"
  "        \"\"\"Create instance, set defaults and do argument processing.\"\"\"\n"
  "        super(Shell, self).__init__()\n"
  "        self.exceptions=False\n"
  "        self.history_file=\"~/.sqlite_history\"\n"
  "        self._db=None\n"
  "        self.dbfilename=None\n"
  "        if db:\n"
  "            self.db=db, db.filename\n"
  "        else:\n"
  "            self.db=None, None\n"
  "        self.prompt=    \"sqlite> \"\n"
  "        self.moreprompt=\"    ..> \"\n"
  "        self.separator=\"|\"\n"
  "        self.bail=False\n"
  "        self.echo=False\n"
  "        self.timer=False\n"
  "        self.header=False\n"
  "        self.nullvalue=\"\"\n"
  "        self.output=self.output_list\n"
  "        self._output_table=self._fmt_sql_identifier(\"table\")\n"
  "        self.widths=[]\n"
  "        self.truncate=True\n"
  "        self._output_stack=[]\n"
  "\n"
  "        self.set_encoding(encoding)\n"
  "        if stdin is None: stdin=sys.stdin\n"
  "        if stdout is None: stdout=sys.stdout\n"
  "        if stderr is None: stderr=sys.stderr\n"
  "        self.stdin=stdin\n"
  "        self.stdout=stdout\n"
  "        self._original_stdout=stdout\n"
  "        self.stderr=stderr\n"
  "        self.interactive=None\n"
  "        self.command_colour() # set to default\n"
  "        self._using_readline=False\n"
  "        self._input_stack=[]\n"
  "        self.input_line_number=0\n"
  "        self.push_input()\n"
  "        self.push_output()\n"
  "        self._input_descriptions=[]\n"
  "\n"
  "        if args:\n"
  "            try:\n"
  "                self.process_args(args)\n"
  "            except:\n"
  "                if len(self._input_descriptions):\n"
  "                    self._input_descriptions.append(\"Processing command line arguments\")\n"
  "                self.handle_exception()\n"
  "                raise\n"
  "\n"
  "        if self.interactive is None:\n"
  "            self.interactive=getattr(self.stdin, \"isatty\", False) and self.stdin.isatty() and getattr(self.stdout, \"isatty\", False) and self.stdout.isatty()\n"
  "\n"
  "    def _ensure_db(self):\n"
  "        \"The database isn't opened until first use.  This function ensures it is now open.\"\n"
  "        if not self._db:\n"
  "            if not self.dbfilename:\n"
  "                self.dbfilename=\":memory:\"\n"
  "            self._db=apsw.Connection(self.dbfilename, flags=apsw.SQLITE_OPEN_URI | apsw.SQLITE_OPEN_READWRITE | apsw.SQLITE_OPEN_CREATE)\n"
  "        return self._db\n"
  "\n"
  "    def _set_db(self, newv):\n"
  "        \"Sets the open database (or None) and filename\"\n"
  "        (db, dbfilename)=newv\n"
  "        if self._db:\n"
  "            self._db.close(True)\n"
  "            self._db=None\n"
  "        self._db=db\n"
  "        self.dbfilename=dbfilename\n"
  "\n"
  "    db=property(_ensure_db, _set_db, None, \"The current :class:`Connection`\")\n"
  "\n"
  "    def process_args(self, args):\n"
  "        \"\"\"Process command line options specified in args.  It is safe to\n"
  "        call this multiple times.  We try to be compatible with SQLite shell\n"
  "        argument parsing.\n"
  "\n"
  "        :param args: A list of string options.  Do not include the\n"
  "           program as args[0]\n"
  "\n"
  "        :returns: A tuple of (databasefilename, initfiles,\n"
  "           sqlncommands).  This is provided for informational purposes\n"
  "           only - they have already been acted upon.  An example use\n"
  "           is that the SQLite shell does not enter the main interactive\n"
  "           loop if any sql/commands were provided.\n"
  "\n"
  "        The first non-option is the database file name.  Each\n"
  "        remaining non-option is treated as a complete input (ie it\n"
  "        isn't joined with others looking for a trailing semi-colon).\n"
  "\n"
  "        The SQLite shell uses single dash in front of options.  We\n"
  "        allow both single and double dashes.  When an unrecognized\n"
  "        argument is encountered then\n"
  "        :meth:`process_unknown_args` is called.\n"
  "        \"\"\"\n"
  "        if not args:\n"
  "            return None, [], []\n"
  "\n"
  "        options=True\n"
  "        havedbname=False\n"
  "        inits=[]\n"
  "        sqls=[]\n"
  "\n"
  "        while args:\n"
  "            if not options or not args[0].startswith(\"-\"):\n"
  "                options=False\n"
  "                if not havedbname:\n"
  "                    self.db=None, args[0]\n"
  "                    havedbname=True\n"
  "                else:\n"
  "                    sqls.append(args[0])\n"
  "                args=args[1:]\n"
  "                continue\n"
  "\n"
  "            args[0]=args[0][1:]\n"
  "            if args[0].startswith(\"-\"):\n"
  "                args[0]=args[0][1:]\n"
  "\n"
  "            if args[0]==\"init\":\n"
  "                if len(args)<2:\n"
  "                    raise self.Error(\"You need to specify a filename after -init\")\n"
  "                inits.append(args[1])\n"
  "                args=args[2:]\n"
  "                continue\n"
  "\n"
  "            if args[0]==\"header\" or args[0]==\"noheader\":\n"
  "                self.header=args[0]==\"header\"\n"
  "                args=args[1:]\n"
  "                continue\n"
  "\n"
  "            if args[0] in (\"echo\", \"bail\", \"interactive\"):\n"
  "                setattr(self, args[0], True)\n"
  "                args=args[1:]\n"
  "                continue\n"
  "\n"
  "            if args[0]==\"batch\":\n"
  "                self.interactive=False\n"
  "                args=args[1:]\n"
  "                continue\n"
  "\n"
  "            if args[0] in (\"separator\", \"nullvalue\", \"encoding\"):\n"
  "                if len(args)<2:\n"
  "                    raise self.Error(\"You need to specify a value after -\"+args[0])\n"
  "                getattr(self, \"command_\"+args[0])([args[1]])\n"
  "                args=args[2:]\n"
  "                continue\n"
  "\n"
  "            if args[0]==\"version\":\n"
  "                self.write(self.stdout, apsw.sqlitelibversion()+\"\\n\")\n"
  "                sys.exit(0)\n"
  "\n"
  "            if args[0]==\"help\":\n"
  "                self.write(self.stderr, self.usage())\n"
  "                sys.exit(0)\n"
  "\n"
  "            if args[0] in (\"no-colour\", \"no-color\", \"nocolour\", \"nocolor\"):\n"
  "                self.colour_scheme=\"off\"\n"
  "                self._out_colour()\n"
  "                args=args[1:]\n"
  "                continue\n"
  "\n"
  "            if getattr(self, \"output_\"+args[0], None):\n"
  "                self.command_mode(args[:1])\n"
  "                args=args[1:]\n"
  "                continue\n"
  "\n"
  "            newargs=self.process_unknown_args(args)\n"
  "            if newargs is None:\n"
  "                raise self.Error(\"Unrecognized argument '\"+args[0]+\"'\")\n"
  "            args=newargs\n"
  "\n"
  "        for f in inits:\n"
  "            self.command_read([f])\n"
  "\n"
  "        for s in sqls:\n"
  "            self.process_complete_line(s)\n"
  "\n"
  "        return self.dbfilename, inits, sqls\n"
  "\n"
  "    def process_unknown_args(self, args):\n"
  "        \"\"\"This is called when :meth:`process_args` encounters an\n"
  "        argument it doesn't understand.  Override this method if you\n"
  "        want to be able to understand additional command line arguments.\n"
  "\n"
  "        :param args: A list of the remaining arguments.  The initial one will\n"
  "           have had the leading dashes removed (eg if it was --foo on the command\n"
  "           line then args[0] will be \"foo\"\n"
  "        :returns: None if you don't recognize the argument either.  Otherwise\n"
  "           return the list of remaining arguments after you have processed\n"
  "           yours.\n"
  "        \"\"\"\n"
  "        return None\n"
  "\n"
  "    def usage(self):\n"
  "        \"Returns the usage message.  Make sure it is newline terminated\"\n"
  "\n"
  "        msg=\"\"\"\n"
  "Usage: program [OPTIONS] FILENAME [SQL|CMD] [SQL|CMD]...\n"
  "FILENAME is the name of a SQLite database. A new database is\n"
  "created if the file does not exist.\n"
  "OPTIONS include:\n"
  "   -init filename       read/process named file\n"
  "   -echo                print commands before execution\n"
  "   -[no]header          turn headers on or off\n"
  "   -bail                stop after hitting an error\n"
  "   -interactive         force interactive I/O\n"
  "   -batch               force batch I/O\n"
  "   -column              set output mode to 'column'\n"
  "   -csv                 set output mode to 'csv'\n"
  "   -html                set output mode to 'html'\n"
  "   -line                set output mode to 'line'\n"
  "   -list                set output mode to 'list'\n"
  "   -python              set output mode to 'python'\n"
  "   -separator 'x'       set output field separator (|)\n"
  "   -nullvalue 'text'    set text string for NULL values\n"
  "   -version             show SQLite version\n"
  "   -encoding 'name'     the encoding to use for files\n"
  "                        opened via .import, .read & .output\n"
  "   -nocolour            disables colour output to screen\n"
  "\"\"\"\n"
  "        return msg.lstrip()\n"
  "\n"
  "\n"
  "    _binary_type = eval((\"buffer\", \"bytes\") [sys.version_info>=(3,0)])\n"
  "    _basestring = eval((\"basestring\", \"str\") [sys.version_info>=(3,0)])\n"
  "\n"
  "    _printable=[ord(x) for x in\n"
  "                \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()`_-+={}[]:;,.<>/?|\"\n"
  "                ]\n"
  "\n"
  "    def _fmt_c_string(self, v):\n"
  "        \"Format as a C string including surrounding double quotes\"\n"
  "        if isinstance(v, self._basestring):\n"
  "            op=['\"']\n"
  "            for c in v:\n"
  "                if c==\"\\\\\":\n"
  "                    op.append(\"\\\\\\\\\")\n"
  "                elif c==\"\\r\":\n"
  "                    op.append(\"\\\\r\")\n"
  "                elif c==\"\\n\":\n"
  "                    op.append(\"\\\\n\")\n"
  "                elif c==\"\\t\":\n"
  "                    op.append(\"\\\\t\")\n"
  "                elif ord(c) not in self._printable:\n"
  "                    op.append(\"\\\\\"+c)\n"
  "                else:\n"
  "                    op.append(c)\n"
  "            op.append('\"')\n"
  "            return \"\".join(op)\n"
  "        elif v is None:\n"
  "            return '\"'+self.nullvalue+'\"'\n"
  "        elif isinstance(v, self._binary_type):\n"
  "            if sys.version_info<(3,0):\n"
  "                o=lambda x: ord(x)\n"
  "                fromc=lambda x: x\n"
  "            else:\n"
  "                o=lambda x: x\n"
  "                fromc=lambda x: chr(x)\n"
  "            res=['\"']\n"
  "            for c in v:\n"
  "                if o(c) in self._printable:\n"
  "                    res.append(fromc(c))\n"
  "                else:\n"
  "                    res.append(\"\\\\x%02X\" % (o(c),))\n"
  "            res.append('\"')\n"
  "            return \"\".join(res)\n"
  "        else:\n"
  "            return '\"%s\"' % (v,)\n"
  "\n"
  "    def _fmt_html_col(self, v):\n"
  "        \"Format as HTML (mainly escaping &/</>\"\n"
  "        return self._fmt_text_col(v).\\\n"
  "           replace(\"&\", \"&amp;\"). \\\n"
  "           replace(\">\", \"&gt;\"). \\\n"
  "           replace(\"<\", \"&lt;\"). \\\n"
  "           replace(\"'\", \"&apos;\"). \\\n"
  "           replace('\"', \"&quot;\")\n"
  "\n"
  "    def _fmt_json_value(self, v):\n"
  "        \"Format a value.\"\n"
  "        if isinstance(v, self._basestring):\n"
  "            op=['\"']\n"
  "            for c in v:\n"
  "                if c==\"\\\\\":\n"
  "                    op.append(\"\\\\\\\\\")\n"
  "                elif c==\"\\r\":\n"
  "                    op.append(\"\\\\r\")\n"
  "                elif c==\"\\n\":\n"
  "                    op.append(\"\\\\n\")\n"
  "                elif c==\"\\t\":\n"
  "                    op.append(\"\\\\t\")\n"
  "                elif c==\"/\": # yes you have to escape forward slash for some reason\n"
  "                    op.append(\"\\\\/\")\n"
  "                elif c=='\"':\n"
  "                    op.append(\"\\\\\"+c)\n"
  "                elif c==\"\\\\b\":\n"
  "                    op.append(\"\\\\b\")\n"
  "                elif c==\"\\\\f\":\n"
  "                    op.append(\"\\\\f\")\n"
  "                else:\n"
  "                    op.append(c)\n"
  "            op.append('\"')\n"
  "            return \"\".join(op)\n"
  "        elif v is None:\n"
  "            return 'null'\n"
  "        elif isinstance(v, self._binary_type):\n"
  "            if sys.version_info<(3,0):\n"
  "                o=base64.encodestring(v)\n"
  "            else:\n"
  "                o=base64.encodebytes(v).decode(\"ascii\")\n"
  "            if o[-1]==\"\\n\":\n"
  "                o=o[:-1]\n"
  "            return '\"'+o+'\"'\n"
  "        else:\n"
  "            return '%s' % (v,)\n"
  "\n"
  "\n"
  "    def _fmt_python(self, v):\n"
  "        \"Format as python literal\"\n"
  "        if v is None:\n"
  "            return \"None\"\n"
  "        elif isinstance(v, self._basestring):\n"
  "            return repr(v)\n"
  "        elif isinstance(v, self._binary_type):\n"
  "            if sys.version_info<(3,0):\n"
  "                res=[\"buffer(\\\"\"]\n"
  "                for i in v:\n"
  "                    if ord(i) in self._printable:\n"
  "                        res.append(i)\n"
  "                    else:\n"
  "                        res.append(\"\\\\x%02X\" % (ord(i),))\n"
  "                res.append(\"\\\")\")\n"
  "                return \"\".join(res)\n"
  "            else:\n"
  "                res=['b\"']\n"
  "                for i in v:\n"
  "                    if i in self._printable:\n"
  "                        res.append(chr(i))\n"
  "                    else:\n"
  "                        res.append(\"\\\\x%02X\" % (i,))\n"
  "                res.append('\"')\n"
  "                return \"\".join(res)\n"
  "        else:\n"
  "            return \"%s\" % (v,)\n"
  "\n"
  "    def _fmt_sql_identifier(self, v):\n"
  "        \"Return the identifier quoted in SQL syntax if needed (eg table and column names)\"\n"
  "        if not len(v): # yes sqlite does allow zero length identifiers\n"
  "            return '\"\"'\n"
  "        nonalnum=re.sub(\"[A-Za-z_0-9]+\", \"\", v)\n"
  "        if len(nonalnum)==0:\n"
  "            if v.upper() not in self._sqlite_reserved:\n"
  "                if v[0] not in \"0123456789\":\n"
  "                    return v\n"
  "        if '\"' in nonalnum:\n"
  "            return \"[%s]\" % (v,)\n"
  "        return '\"%s\"' % (v,)\n"
  "\n"
  "    def _fmt_text_col(self, v):\n"
  "        \"Regular text formatting\"\n"
  "        if v is None:\n"
  "            return self.nullvalue\n"
  "        elif isinstance(v, self._basestring):\n"
  "            return v\n"
  "        elif isinstance(v, self._binary_type):\n"
  "            return \"<Binary data>\"\n"
  "        else:\n"
  "            return \"%s\" % (v,)\n"
  "\n"
  "\n"
  "    def output_column(self, header, line):\n"
  "        \"\"\"\n"
  "        Items left aligned in space padded columns.  They are\n"
  "        truncated if they do not fit. If the width hasn't been\n"
  "        specified for a column then 10 is used unless the column name\n"
  "        (header) is longer in which case that width is used.  Use the\n"
  "        .width command to change column sizes.\n"
  "        \"\"\"\n"
  "        if header:\n"
  "            def gw(n):\n"
  "                if n<len(self.widths) and self.widths[n]!=0:\n"
  "                    return self.widths[n]\n"
  "                text=self._fmt_text_col(line[n])\n"
  "                return max(len(text), 10)\n"
  "\n"
  "            widths=[gw(i) for i in range(len(line))]\n"
  "\n"
  "            if self.truncate:\n"
  "                self._actualwidths=[\"%\"+(\"-%d.%ds\", \"%d.%ds\")[w<0]%(abs(w), abs(w)) for w in widths]\n"
  "            else:\n"
  "                self._actualwidths=[\"%\"+(\"-%ds\", \"%ds\")[w<0]%(abs(w),) for w in widths]\n"
  "\n"
  "            if self.header:\n"
  "                c=self.colour\n"
  "                cols=[c.header+(self._actualwidths[i] % (self._fmt_text_col(line[i]),))+c.header_ for i in range(len(line))]\n"
  "                self.write(self.stdout, \"  \".join(cols)+\"\\n\")\n"
  "                if c is self._colours[\"off\"]:\n"
  "                    self.output_column(False, [\"-\"*abs(widths[i]) for i in range(len(widths))])\n"
  "            return\n"
  "        cols=[self.colour.colour_value(line[i], self._actualwidths[i] % (self._fmt_text_col(line[i]),)) for i in range(len(line))]\n"
  "        self.write(self.stdout, \"  \".join(cols)+\"\\n\")\n"
  "\n"
  "    output_columns=output_column\n"
  "\n"
  "    def output_csv(self, header, line):\n"
  "        \"\"\"\n"
  "        Items in csv format (comma separated).  Use tabs mode for tab\n"
  "        separated.  You can use the .separator command to use a\n"
  "        different one after switching mode.  A separator of comma uses\n"
  "        double quotes for quoting while other separators do not do any\n"
  "        quoting.  The Python csv library used for this only supports\n"
  "        single character separators.\n"
  "        \"\"\"\n"
  "\n"
  "\n"
  "        if sys.version_info<(3,0):\n"
  "            fixdata=lambda x: x.encode(\"utf8\")\n"
  "        else:\n"
  "            fixdata=lambda x: x\n"
  "\n"
  "        if header:\n"
  "            if sys.version_info<(3,0):\n"
  "                import StringIO as io\n"
  "            else:\n"
  "                import io\n"
  "            s=io.StringIO()\n"
  "            kwargs={}\n"
  "            if self.separator==\",\":\n"
  "                kwargs[\"dialect\"]=\"excel\"\n"
  "            elif self.separator==\"\\t\":\n"
  "                kwargs[\"dialect\"]=\"excel-tab\"\n"
  "            else:\n"
  "                kwargs[\"quoting\"]=csv.QUOTE_NONE\n"
  "                kwargs[\"delimiter\"]=fixdata(self.separator)\n"
  "                kwargs[\"doublequote\"]=False\n"
  "                kwargs[\"quotechar\"]=\"\\x00\"\n"
  "\n"
  "            writer=csv.writer(s, **kwargs)\n"
  "            self._csv=(s, writer)\n"
  "            if self.header:\n"
  "                self.output_csv(None, line)\n"
  "            return\n"
  "\n"
  "        if header is None:\n"
  "            c=self.colour\n"
  "            line=[c.header+fixdata(self._fmt_text_col(l))+c.header_ for l in line]\n"
  "        else:\n"
  "            fmt=lambda x: self.colour.colour_value(x, fixdata(self._fmt_text_col(x)))\n"
  "            line=[fmt(l) for l in line]\n"
  "        self._csv[1].writerow(line)\n"
  "        t=self._csv[0].getvalue()\n"
  "        if sys.version_info<(3,0):\n"
  "            t=t.decode(\"utf8\")\n"
  "        assert(t.endswith(\"\\r\\n\"))\n"
  "        t=t[:-2]\n"
  "        assert(not t.endswith(\"\\r\") and not  t.endswith(\"\\n\"))\n"
  "        self.write(self.stdout, t+\"\\n\")\n"
  "        self._csv[0].truncate(0)\n"
  "        self._csv[0].seek(0)\n"
  "\n"
  "    def output_html(self, header, line):\n"
  "        \"HTML table style\"\n"
  "        if header:\n"
  "            if not self.header:\n"
  "                return\n"
  "            fmt=lambda x: self.colour.header+self._fmt_html_col(x)+self.colour.header_\n"
  "        else:\n"
  "            fmt=lambda x: self.colour.colour_value(x, self._fmt_html_col(x))\n"
  "        line=[fmt(l) for l in line]\n"
  "        out=[\"<TR>\"]\n"
  "        for l in line:\n"
  "            out.append((\"<TD>\",\"<TH>\")[header])\n"
  "            out.append(l)\n"
  "            out.append((\"</TD>\\n\",\"</TH>\\n\")[header])\n"
  "        out.append(\"</TR>\\n\")\n"
  "        self.write(self.stdout, \"\".join(out))\n"
  "\n"
  "    def output_insert(self, header, line):\n"
  "        \"\"\"\n"
  "        Lines as SQL insert statements.  The table name is \"table\"\n"
  "        unless you specified a different one as the second parameter\n"
  "        to the .mode command.\n"
  "        \"\"\"\n"
  "        if header:\n"
  "            return\n"
  "        fmt=lambda x: self.colour.colour_value(x, apsw.format_sql_value(x))\n"
  "        out=\"INSERT INTO \"+self._output_table+\" VALUES(\"+\",\".join([fmt(l) for l in line])+\");\\n\"\n"
  "        self.write(self.stdout, out)\n"
  "\n"
  "    def output_json(self, header, line):\n"
  "        \"\"\"\n"
  "        Each line as a JSON object with a trailing comma.  Blobs are\n"
  "        output as base64 encoded strings.  You should be using UTF8\n"
  "        output encoding.\n"
  "        \"\"\"\n"
  "        if header:\n"
  "            self._output_json_cols=line\n"
  "            return\n"
  "        fmt=lambda x: self.colour.colour_value(x, self._fmt_json_value(x))\n"
  "        out=[\"%s: %s\" % (self._fmt_json_value(k), fmt(line[i])) for i,k in enumerate(self._output_json_cols)]\n"
  "        self.write(self.stdout, \"{ \"+\", \".join(out)+\"},\\n\")\n"
  "\n"
  "    def output_line(self, header, line):\n"
  "        \"\"\"\n"
  "        One value per line in the form 'column = value' with a blank\n"
  "        line between rows.\n"
  "        \"\"\"\n"
  "        if header:\n"
  "            w=5\n"
  "            for l in line:\n"
  "                if len(l)>w:\n"
  "                    w=len(l)\n"
  "            self._line_info=(w, line)\n"
  "            return\n"
  "        fmt=lambda x: self.colour.colour_value(x, self._fmt_text_col(x))\n"
  "        w=self._line_info[0]\n"
  "        for i in range(len(line)):\n"
  "            self.write(self.stdout, \"%*s = %s\\n\" % (w, self._line_info[1][i], fmt(line[i])))\n"
  "        self.write(self.stdout, \"\\n\")\n"
  "\n"
  "    output_lines=output_line\n"
  "\n"
  "    def output_list(self, header, line):\n"
  "        \"All items on one line with separator\"\n"
  "        if header:\n"
  "            if not self.header:\n"
  "                return\n"
  "            c=self.colour\n"
  "            fmt=lambda x: c.header+x+c.header_\n"
  "        else:\n"
  "            fmt=lambda x: self.colour.colour_value(x, self._fmt_text_col(x))\n"
  "        self.write(self.stdout, self.separator.join([fmt(x) for x in line])+\"\\n\")\n"
  "\n"
  "    def output_python(self, header, line):\n"
  "        \"Tuples in Python source form for each row\"\n"
  "        if header:\n"
  "            if not self.header:\n"
  "                return\n"
  "            c=self.colour\n"
  "            fmt=lambda x: c.header+self._fmt_python(x)+c.header_\n"
  "        else:\n"
  "            fmt=lambda x: self.colour.colour_value(x, self._fmt_python(x))\n"
  "        self.write(self.stdout, '('+\", \".join([fmt(l) for l in line])+\"),\\n\")\n"
  "\n"
  "    def output_tcl(self, header, line):\n"
  "        \"Outputs TCL/C style strings using current separator\"\n"
  "        if header:\n"
  "            if not self.header:\n"
  "                return\n"
  "            c=self.colour\n"
  "            fmt=lambda x: c.header+self._fmt_c_string(x)+c.header_\n"
  "        else:\n"
  "            fmt=lambda x: self.colour.colour_value(x, self._fmt_c_string(x))\n"
  "        self.write(self.stdout, self.separator.join([fmt(l) for l in line])+\"\\n\")\n"
  "\n"
  "    def _output_summary(self, summary):\n"
  "        self.write(self.stdout, self.colour.summary+summary+self.colour.summary_)\n"
  "\n"
  "\n"
  "    def cmdloop(self, intro=None):\n"
  "        \"\"\"Runs the main interactive command loop.\n"
  "\n"
  "        :param intro: Initial text banner to display instead of the\n"
  "           default.  Make sure you newline terminate it.\n"
  "        \"\"\"\n"
  "        if intro is None:\n"
  "            intro=\"\"\"\n"
  "SQLite version %s (APSW %s)\n"
  "Enter \".help\" for instructions\n"
  "Enter SQL statements terminated with a \";\"\n"
  "\"\"\" % (apsw.sqlitelibversion(), apsw.apswversion())\n"
  "            intro=intro.lstrip()\n"
  "        if self.interactive and intro:\n"
  "            if sys.version_info<(3,0):\n"
  "                intro=unicode(intro)\n"
  "            c=self.colour\n"
  "            self.write(self.stdout, c.intro+intro+c.intro_)\n"
  "\n"
  "        using_readline=False\n"
  "        try:\n"
  "            if self.interactive and self.stdin is sys.stdin:\n"
  "                import readline\n"
  "                old_completer=readline.get_completer()\n"
  "                readline.set_completer(self.complete)\n"
  "                readline.parse_and_bind(\"tab: complete\")\n"
  "                using_readline=True\n"
  "                try:\n"
  "                    readline.read_history_file(os.path.expanduser(self.history_file))\n"
  "                except:\n"
  "                    pass\n"
  "        except ImportError:\n"
  "            pass\n"
  "\n"
  "        try:\n"
  "            while True:\n"
  "                self._input_descriptions=[]\n"
  "                if using_readline:\n"
  "                    self._completion_cache=None\n"
  "                    self._using_readline=True\n"
  "                try:\n"
  "                    command=self.getcompleteline()\n"
  "                    if command is None: # EOF\n"
  "                        return\n"
  "                    self.process_complete_line(command)\n"
  "                except:\n"
  "                    self._append_input_description()\n"
  "                    try:\n"
  "                        self.handle_exception()\n"
  "                    except UnicodeDecodeError:\n"
  "                        self.handle_exception()\n"
  "        finally:\n"
  "            if using_readline:\n"
  "                readline.set_completer(old_completer)\n"
  "                readline.set_history_length(256)\n"
  "                readline.write_history_file(os.path.expanduser(self.history_file))\n"
  "\n"
  "    def handle_exception(self):\n"
  "        \"\"\"Handles the current exception, printing a message to stderr as appropriate.\n"
  "        It will reraise the exception if necessary (eg if bail is true)\"\"\"\n"
  "        eclass,eval,etb=sys.exc_info() # py2&3 compatible way of doing this\n"
  "        if isinstance(eval, SystemExit):\n"
  "            eval._handle_exception_saw_this=True\n"
  "            raise\n"
  "\n"
  "        self._out_colour()\n"
  "        self.write(self.stderr, self.colour.error)\n"
  "\n"
  "        if isinstance(eval, KeyboardInterrupt):\n"
  "            self.handle_interrupt()\n"
  "            text=\"Interrupted\"\n"
  "        else:\n"
  "            text=str(eval)\n"
  "\n"
  "        if not text.endswith(\"\\n\"):\n"
  "            text=text+\"\\n\"\n"
  "\n"
  "        if len(self._input_descriptions):\n"
  "            for i in range(len(self._input_descriptions)):\n"
  "                if i==0:\n"
  "                    pref=\"At \"\n"
  "                else:\n"
  "                    pref=\" \"*i+\"From \"\n"
  "                self.write(self.stderr, pref+self._input_descriptions[i]+\"\\n\")\n"
  "\n"
  "        self.write(self.stderr, text)\n"
  "        if self.exceptions:\n"
  "            stack=[]\n"
  "            while etb:\n"
  "                stack.append(etb.tb_frame)\n"
  "                etb = etb.tb_next\n"
  "\n"
  "            for frame in stack:\n"
  "                self.write(self.stderr, \"\\nFrame %s in %s at line %d\\n\" %\n"
  "                           (frame.f_code.co_name, frame.f_code.co_filename,\n"
  "                            frame.f_lineno))\n"
  "                vars=list(frame.f_locals.items())\n"
  "                vars.sort()\n"
  "                for k,v in vars:\n"
  "                    try:\n"
  "                        v=repr(v)[:80]\n"
  "                    except:\n"
  "                        v=\"<Unable to convert to string>\"\n"
  "                    self.write(self.stderr, \"%10s = %s\\n\" % (k,v))\n"
  "            self.write(self.stderr, \"\\n%s: %s\\n\" % (eclass, repr(eval)))\n"
  "\n"
  "        self.write(self.stderr, self.colour.error_)\n"
  "\n"
  "        eval._handle_exception_saw_this=True\n"
  "        if self.bail:\n"
  "            raise\n"
  "\n"
  "    def process_sql(self, sql, bindings=None, internal=False, summary=None):\n"
  "        \"\"\"Processes SQL text consisting of one or more statements\n"
  "\n"
  "        :param sql: SQL to execute\n"
  "\n"
  "        :param bindings: bindings for the *sql*\n"
  "\n"
  "        :param internal: If True then this is an internal execution\n"
  "          (eg the .tables or .database command).  When executing\n"
  "          internal sql timings are not shown nor is the SQL echoed.\n"
  "\n"
  "        :param summary: If not None then should be a tuple of two\n"
  "          items.  If the ``sql`` returns any data then the first item\n"
  "          is printed before the first row, and the second item is\n"
  "          printed after the last row.  An example usage is the .find\n"
  "          command which shows table names.\n"
  "        \"\"\"\n"
  "        cur=self.db.cursor()\n"
  "        state={'newsql': True, 'timing': None}\n"
  "        def et(cur, sql, bindings):\n"
  "            state['newsql']=True\n"
  "            if not internal and self.timer:\n"
  "                if state['timing']:\n"
  "                    self.display_timing(state['timing'], self.get_resource_usage())\n"
  "            if not internal and self.echo:\n"
  "                if bindings:\n"
  "                    self.write(self.stderr, \"%s [%s]\\n\" % (sql, bindings))\n"
  "                else:\n"
  "                    self.write(self.stderr, sql+\"\\n\")\n"
  "            if not internal and self.timer:\n"
  "                state['timing']=self.get_resource_usage()\n"
  "            return True\n"
  "        cur.setexectrace(et)\n"
  "        try:\n"
  "            for row in cur.execute(sql, bindings):\n"
  "                if state['newsql']:\n"
  "                    if summary:\n"
  "                        self._output_summary(summary[0])\n"
  "                    cols=[h for h,d in cur.getdescription()]\n"
  "                    self.output(True, cols)\n"
  "                    state['newsql']=False\n"
  "                self.output(False, row)\n"
  "            if not state['newsql'] and summary:\n"
  "                self._output_summary(summary[1])\n"
  "        except:\n"
  "            if not internal and self.echo:\n"
  "                tb=sys.exc_info()[2]\n"
  "                last=None\n"
  "                while tb:\n"
  "                    last=tb.tb_frame\n"
  "                    tb=tb.tb_next\n"
  "\n"
  "                if last and last.f_code.co_name==\"sqlite3_prepare\" \\\n"
  "                   and last.f_code.co_filename.endswith(\"statementcache.c\") \\\n"
  "                   and \"sql\" in last.f_locals:\n"
  "                    self.write(self.stderr, last.f_locals[\"sql\"]+\"\\n\")\n"
  "            raise\n"
  "\n"
  "        if not internal and self.timer:\n"
  "            self.display_timing(state['timing'], self.get_resource_usage())\n"
  "\n"
  "    def process_command(self, cmd):\n"
  "        \"\"\"Processes a dot command.  It is split into parts using the\n"
  "        `shlex.split\n"
  "        <http://docs.python.org/library/shlex.html#shlex.split>`__\n"
  "        function which is roughly the same method used by Unix/POSIX\n"
  "        shells.\n"
  "        \"\"\"\n"
  "        if self.echo:\n"
  "            self.write(self.stderr, cmd+\"\\n\")\n"
  "        if sys.version_info<(3,0):\n"
  "            cmd=cmd.encode(\"utf8\")\n"
  "            cmd=[c.decode(\"utf8\") for c in shlex.split(cmd)]\n"
  "        else:\n"
  "            cmd=shlex.split(cmd)\n"
  "        assert cmd[0][0]==\".\"\n"
  "        cmd[0]=cmd[0][1:]\n"
  "        fn=getattr(self, \"command_\"+cmd[0], None)\n"
  "        if not fn:\n"
  "            raise self.Error(\"Unknown command \\\"%s\\\".  Enter \\\".help\\\" for help\" % (cmd[0],))\n"
  "        res=fn(cmd[1:])\n"
  "\n"
  "\n"
  "    def _boolean_command(self, name, cmd):\n"
  "        \"Parse and verify boolean parameter\"\n"
  "        if len(cmd)!=1 or cmd[0].lower() not in (\"on\", \"off\"):\n"
  "            raise self.Error(name+\" expected ON or OFF\")\n"
  "        return cmd[0].lower()==\"on\"\n"
  "\n"
  "\n"
  "\n"
  "    def command_backup(self, cmd):\n"
  "        \"\"\"backup ?DB? FILE: Backup DB (default \"main\") to FILE\n"
  "\n"
  "        Copies the contents of the current database to FILE\n"
  "        overwriting whatever was in FILE.  If you have attached databases\n"
  "        then you can specify their name instead of the default of \"main\".\n"
  "\n"
  "        The backup is done at the page level - SQLite copies the pages\n"
  "        as is.  There is no round trip through SQL code.\n"
  "        \"\"\"\n"
  "        dbname=\"main\"\n"
  "        if len(cmd)==1:\n"
  "            fname=cmd[0]\n"
  "        elif len(cmd)==2:\n"
  "            dbname=cmd[0]\n"
  "            fname=cmd[1]\n"
  "        else:\n"
  "            raise self.Error(\"Backup takes one or two parameters\")\n"
  "        out=apsw.Connection(fname)\n"
  "        b=out.backup(\"main\", self.db, dbname)\n"
  "        try:\n"
  "            while not b.done:\n"
  "                b.step()\n"
  "        finally:\n"
  "            b.finish()\n"
  "            out.close()\n"
  "\n"
  "\n"
  "    def command_bail(self, cmd):\n"
  "        \"\"\"bail ON|OFF: Stop after hitting an error (default OFF)\n"
  "\n"
  "        If an error is encountered while processing commands or SQL\n"
  "        then exit.  (Note this is different than SQLite shell which\n"
  "        only exits for errors in SQL.)\n"
  "        \"\"\"\n"
  "        self.bail=self._boolean_command(\"bail\", cmd)\n"
  "\n"
  "    def command_colour(self, cmd=[]):\n"
  "        \"\"\"colour SCHEME: Selects a colour scheme\n"
  "\n"
  "        Residents of both countries that have not adopted the metric\n"
  "        system may also spell this command without a 'u'.  If using a\n"
  "        colour terminal in interactive mode then output is\n"
  "        automatically coloured to make it more readable.  Use 'off' to\n"
  "        turn off colour, and no name or 'default' for the default.\n"
  "        \"\"\"\n"
  "        if len(cmd)>1:\n"
  "            raise self.Error(\"Too many colour schemes\")\n"
  "        c=cmd and cmd[0] or \"default\"\n"
  "        if c not in self._colours:\n"
  "            raise self.Error(\"No such colour scheme: \"+c)\n"
  "        self.colour_scheme=c\n",
  "        self._out_colour()\n"
  "\n"
  "    command_color=command_colour\n"
  "\n"
  "    def command_databases(self, cmd):\n"
  "        \"\"\"databases: Lists names and files of attached databases\n"
  "\n"
  "        \"\"\"\n"
  "        if len(cmd):\n"
  "            raise self.Error(\"databases command doesn't take any parameters\")\n"
  "        self.push_output()\n"
  "        self.header=True\n"
  "        self.output=self.output_column\n"
  "        self.truncate=False\n"
  "        self.widths=[3,15,58]\n"
  "        try:\n"
  "            self.process_sql(\"pragma database_list\", internal=True)\n"
  "        finally:\n"
  "            self.pop_output()\n"
  "\n"
  "    def command_dump(self, cmd):\n"
  "        \"\"\"dump ?TABLE? [TABLE...]: Dumps all or specified tables in SQL text format\n"
  "\n"
  "        The table name is treated as like pattern so you can use % as\n"
  "        a wildcard.  You can use dump to make a text based backup of\n"
  "        the database.  It is also useful for comparing differences or\n"
  "        making the data available to other databases.  Indices and\n"
  "        triggers for the table(s) are also dumped.  Finally views\n"
  "        matching the table pattern name are dumped (it isn't possible\n"
  "        to work out which views access which table and views can\n"
  "        access multiple tables anyway).\n"
  "\n"
  "        Note that if you are dumping virtual tables such as used by\n"
  "        the FTS3 module then they may use other tables to store\n"
  "        information.  For example if you create a FTS3 table named\n"
  "        *recipes* then it also creates *recipes_content*,\n"
  "        *recipes_segdir* etc.  Consequently to dump this example\n"
  "        correctly use::\n"
  "\n"
  "           .dump recipes recipes_%\n"
  "\n"
  "        If the database is empty or no tables/views match then there\n"
  "        is no output.\n"
  "        \"\"\"\n"
  "\n"
  "        self.process_sql(\"BEGIN IMMEDIATE\", internal=True)\n"
  "\n"
  "        outputstrtype=str\n"
  "        if sys.version_info<(3,0):\n"
  "            outputstrtype=unicode\n"
  "\n"
  "        outputstrencoding=getattr(self.stdout, \"encoding\", \"ascii\")\n"
  "        try:\n"
  "            codecs.lookup(outputstrencoding)\n"
  "        except:\n"
  "            outputstrencoding=\"ascii\"\n"
  "\n"
  "        def unicodify(s):\n"
  "            if not isinstance(s, outputstrtype):\n"
  "                return s.decode(outputstrencoding, \"replace\")\n"
  "            return s\n"
  "\n"
  "        try:\n"
  "            v={\"virtuals\": False,\n"
  "               \"foreigns\": False}\n"
  "            def check(name, sql):\n"
  "                if name.lower().startswith(\"sqlite_\"):\n"
  "                    return False\n"
  "                sql=sql.lower()\n"
  "                if re.match(r\"^\\s*create\\s+virtual\\s+.*\", sql):\n"
  "                    v[\"virtuals\"]=True\n"
  "                if re.match(r\".*\\b(foreign\\s*key|references)\\b.*\", sql):\n"
  "                    v[\"foreigns\"]=True\n"
  "                return True\n"
  "\n"
  "            if len(cmd)==0:\n"
  "                cmd=[\"%\"]\n"
  "\n"
  "            tables=[]\n"
  "            for pattern in cmd:\n"
  "                for name,sql in self.db.cursor().execute(\"SELECT name,sql FROM sqlite_master \"\n"
  "                                                         \"WHERE sql NOT NULL AND type IN ('table','view') \"\n"
  "                                                         \"AND tbl_name LIKE ?1\", (pattern,)):\n"
  "                    if check(name, sql) and name not in tables:\n"
  "                        tables.append(name)\n"
  "\n"
  "            if not tables:\n"
  "                return\n"
  "\n"
  "            analyze_needed=[]\n"
  "            for stat in self.db.cursor().execute(\"select name from sqlite_master where sql not null and type='table' and tbl_name like 'sqlite_stat%'\"):\n"
  "                for name in tables:\n"
  "                    if len(self.db.cursor().execute(\"select * from \"+self._fmt_sql_identifier(stat[0])+\" WHERE tbl=?\", (name,)).fetchall()):\n"
  "                        if name not in analyze_needed:\n"
  "                            analyze_needed.append(name)\n"
  "            analyze_needed.sort()\n"
  "\n"
  "            def blank():\n"
  "                self.write(self.stdout, \"\\n\")\n"
  "\n"
  "            def comment(s):\n"
  "                s=unicodify(s)\n"
  "                self.write(self.stdout, textwrap.fill(s, 78, initial_indent=\"-- \", subsequent_indent=\"-- \")+\"\\n\")\n"
  "\n"
  "            pats=\", \".join([(x,\"(All)\")[x==\"%\"] for x in cmd])\n"
  "            comment(\"SQLite dump (by APSW %s)\" % (apsw.apswversion(),))\n"
  "            comment(\"SQLite version \" + apsw.sqlitelibversion())\n"
  "            comment(\"Date: \" +unicodify(time.strftime(\"%c\")))\n"
  "            comment(\"Tables like: \"+pats)\n"
  "            comment(\"Database: \"+self.db.filename)\n"
  "            try:\n"
  "                import getpass\n"
  "                import socket\n"
  "                comment(\"User: %s @ %s\" % (unicodify(getpass.getuser()), unicodify(socket.gethostname())))\n"
  "            except ImportError:\n"
  "                pass\n"
  "            blank()\n"
  "\n"
  "            comment(\"The values of various per-database settings\")\n"
  "            self.write(self.stdout, \"PRAGMA page_size=\"+str(self.db.cursor().execute(\"pragma page_size\").fetchall()[0][0])+\";\\n\")\n"
  "            comment(\"PRAGMA encoding='\"+self.db.cursor().execute(\"pragma encoding\").fetchall()[0][0]+\"';\\n\")\n"
  "            vac={0: \"NONE\", 1: \"FULL\", 2: \"INCREMENTAL\"}\n"
  "            vacvalue=self.db.cursor().execute(\"pragma auto_vacuum\").fetchall()[0][0]\n"
  "            comment(\"PRAGMA auto_vacuum=\"+vac.get(vacvalue, str(vacvalue))+\";\\n\")\n"
  "            comment(\"PRAGMA max_page_count=\"+str(self.db.cursor().execute(\"pragma max_page_count\").fetchall()[0][0])+\";\\n\")\n"
  "            blank()\n"
  "\n"
  "            dectables=[(x.lower(), x) for x in tables]\n"
  "            dectables.sort()\n"
  "            tables=[y for x,y in dectables]\n"
  "\n"
  "            virtuals=v[\"virtuals\"]\n"
  "            foreigns=v[\"foreigns\"]\n"
  "\n"
  "            if virtuals:\n"
  "                comment(\"This pragma is needed to restore virtual tables\")\n"
  "                self.write(self.stdout, \"PRAGMA writable_schema=ON;\\n\")\n"
  "            if foreigns:\n"
  "                comment(\"This pragma turns off checking of foreign keys \"\n"
  "                        \"as tables would be inconsistent while restoring.  It was introduced \"\n"
  "                        \"in SQLite 3.6.19.\")\n"
  "                self.write(self.stdout, \"PRAGMA foreign_keys=OFF;\\n\")\n"
  "\n"
  "            if virtuals or foreigns:\n"
  "                blank()\n"
  "\n"
  "            self.write(self.stdout, \"BEGIN TRANSACTION;\\n\")\n"
  "            blank()\n"
  "\n"
  "            def sqldef(s):\n"
  "                if \"--\" in s.split(\"\\n\")[-1]:\n"
  "                    nl=\"\\n\"\n"
  "                else:\n"
  "                    nl=\"\"\n"
  "                return s+nl+\";\\n\"\n"
  "\n"
  "            oldtable=self._output_table\n"
  "            try:\n"
  "                self.push_output()\n"
  "                self.output=self.output_insert\n"
  "                for table in tables:\n"
  "                    for sql in self.db.cursor().execute(\"SELECT sql FROM sqlite_master WHERE name=?1 AND type='table'\", (table,)):\n"
  "                        comment(\"Table  \"+table)\n"
  "                        if sql[0].lower().split()[:3]==[\"create\", \"virtual\", \"table\"]:\n"
  "                            self.write(self.stdout, \"DELETE FROM sqlite_master WHERE name=\"+apsw.format_sql_value(table)+\" AND type='table';\\n\")\n"
  "                            self.write(self.stdout, \"INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql) VALUES('table',%s,%s,0,%s);\\n\"\n"
  "                                       % (apsw.format_sql_value(table), apsw.format_sql_value(table), apsw.format_sql_value(sql[0])))\n"
  "                        else:\n"
  "                            self.write(self.stdout, \"DROP TABLE IF EXISTS \"+self._fmt_sql_identifier(table)+\";\\n\")\n"
  "                            self.write(self.stdout, sqldef(sql[0]))\n"
  "                            self._output_table=self._fmt_sql_identifier(table)\n"
  "                            self.process_sql(\"select * from \"+self._fmt_sql_identifier(table), internal=True)\n"
  "                        first=True\n"
  "                        for name,sql in self.db.cursor().execute(\"SELECT name,sql FROM sqlite_master \"\n"
  "                                                                 \"WHERE sql NOT NULL AND type IN ('index', 'trigger') \"\n"
  "                                                                 \"AND tbl_name=?1 AND name NOT LIKE 'sqlite_%' \"\n"
  "                                                                 \"ORDER BY lower(name)\", (table,)):\n"
  "                            if first:\n"
  "                                comment(\"Triggers and indices on  \"+table)\n"
  "                                first=False\n"
  "                            self.write(self.stdout, sqldef(sql))\n"
  "                        blank()\n"
  "                first=True\n"
  "                for name,sql in self.db.cursor().execute(\"SELECT name,sql FROM sqlite_master \"\n"
  "                                                         \"WHERE sql NOT NULL AND type='view' \"\n"
  "                                                         \"AND name IN ( \"+\",\".join([apsw.format_sql_value(i) for i in tables])+\n"
  "                                                         \") ORDER BY _ROWID_\"):\n"
  "                    if first:\n"
  "                        comment(\"Views\")\n"
  "                        first=False\n"
  "                    self.write(self.stdout, \"DROP VIEW IF EXISTS %s;\\n\" % (self._fmt_sql_identifier(name),))\n"
  "                    self.write(self.stdout, sqldef(sql))\n"
  "                if not first:\n"
  "                    blank()\n"
  "\n"
  "                if len(self.db.cursor().execute(\"select * from sqlite_master where name='sqlite_sequence'\").fetchall()):\n"
  "                    first=True\n"
  "                    for t in tables:\n"
  "                        v=self.db.cursor().execute(\"select seq from main.sqlite_sequence where name=?1\", (t,)).fetchall()\n"
  "                        if len(v):\n"
  "                            assert len(v)==1\n"
  "                            if first:\n"
  "                                comment(\"For primary key autoincrements the next id \"\n"
  "                                        \"to use is stored in sqlite_sequence\")\n"
  "                                first=False\n"
  "                            self.write(self.stdout, 'DELETE FROM main.sqlite_sequence WHERE name=%s;\\n' % (apsw.format_sql_value(t),))\n"
  "                            self.write(self.stdout, 'INSERT INTO main.sqlite_sequence VALUES (%s, %s);\\n' % (apsw.format_sql_value(t), v[0][0]))\n"
  "                    if not first:\n"
  "                        blank()\n"
  "            finally:\n"
  "                self.pop_output()\n"
  "                self._output_table=oldtable\n"
  "\n"
  "            if analyze_needed:\n"
  "                comment(\"You had used the analyze command on these tables before.  Rerun for this new data.\")\n"
  "                for n in analyze_needed:\n"
  "                    self.write(self.stdout, \"ANALYZE \"+self._fmt_sql_identifier(n)+\";\\n\")\n"
  "                blank()\n"
  "\n"
  "            uv=self.db.cursor().execute(\"pragma user_version\").fetchall()[0][0]\n"
  "            if uv:\n"
  "                comment(\"Your database may need this.  It is sometimes used to keep track of the schema version (eg Firefox does this).\")\n"
  "                self.write(self.stdout, \"pragma user_version=%d;\" % (uv,))\n"
  "                blank()\n"
  "\n"
  "            self.write(self.stdout, \"COMMIT TRANSACTION;\\n\")\n"
  "\n"
  "            if foreigns:\n"
  "                blank()\n"
  "                comment(\"Restoring foreign key checking back on.  Note that SQLite 3.6.19 is off by default\")\n"
  "                self.write(self.stdout, \"PRAGMA foreign_keys=ON;\\n\")\n"
  "            if virtuals:\n"
  "                blank()\n"
  "                comment(\"Restoring writable schema back to default\")\n"
  "                self.write(self.stdout, \"PRAGMA writable_schema=OFF;\\n\")\n"
  "                blank()\n"
  "                comment(\"We need to force SQLite to reread the schema because otherwise it doesn't know that \"\n"
  "                        \"the virtual tables we inserted directly into sqlite_master exist.  See \"\n"
  "                        \"last comments of https://sqlite.org/cvstrac/tktview?tn=3425\")\n"
  "                self.write(self.stdout, \"BEGIN;\\nCREATE TABLE no_such_table(x,y,z);\\nROLLBACK;\\n\")\n"
  "\n"
  "        finally:\n"
  "            self.process_sql(\"END\", internal=True)\n"
  "\n"
  "\n"
  "    def command_echo(self, cmd):\n"
  "        \"\"\"echo ON|OFF: If ON then each SQL statement or command is printed before execution (default OFF)\n"
  "\n"
  "        The SQL statement or command is sent to error output so that\n"
  "        it is not intermingled with regular output.\n"
  "        \"\"\"\n"
  "        self.echo=self._boolean_command(\"echo\", cmd)\n"
  "\n"
  "    def set_encoding(self, enc):\n"
  "        \"\"\"Saves *enc* as the default encoding, after verifying that\n"
  "        it is valid.  You can also include :error to specify error\n"
  "        handling - eg 'cp437:replace'\n"
  "\n"
  "        Raises an exception on invalid encoding or error\n"
  "        \"\"\"\n"
  "        enc=enc.split(\":\", 1)\n"
  "        if len(enc)>1:\n"
  "            enc, errors=enc\n"
  "        else:\n"
  "            enc=enc[0]\n"
  "            errors=None\n"
  "        try:\n"
  "            codecs.lookup(enc)\n"
  "        except LookupError:\n"
  "            raise self.Error(\"No known encoding '%s'\" % (enc,))\n"
  "        try:\n"
  "            if errors is not None:\n"
  "                codecs.lookup_error(errors)\n"
  "        except LookupError:\n"
  "            raise self.Error(\"No known codec error handler '%s'\" % (errors,))\n"
  "        self.encoding=enc, errors\n"
  "\n"
  "\n"
  "    def command_encoding(self, cmd):\n"
  "        \"\"\"encoding ENCODING: Set the encoding used for new files opened via .output and imports\n"
  "\n"
  "        SQLite and APSW work internally using Unicode and characters.\n"
  "        Files however are a sequence of bytes.  An encoding describes\n"
  "        how to convert between bytes and characters.  The default\n"
  "        encoding is utf8 and that is generally the best value to use\n"
  "        when other programs give you a choice.\n"
  "\n"
  "        You can also specify an error handler.  For example\n"
  "        'cp437:replace' will use code page 437 and any Unicode\n"
  "        codepoints not present in cp437 will be replaced (typically\n"
  "        with something like a question mark).  Other error handlers\n"
  "        include 'ignore', 'strict' (default) and 'xmlcharrefreplace'.\n"
  "\n"
  "        For the default input/output/error streams on startup the\n"
  "        shell defers to Python's detection of encoding.  For example\n"
  "        on Windows it asks what code page is in use and on Unix it\n"
  "        looks at the LC_CTYPE environment variable.  You can set the\n"
  "        PYTHONIOENCODING environment variable to override this\n"
  "        detection.\n"
  "\n"
  "        This command affects files opened after setting the encoding\n"
  "        as well as imports.\n"
  "\n"
  "        See the online APSW documentation for more details.\n"
  "        \"\"\"\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"Encoding takes one argument\")\n"
  "        self.set_encoding(cmd[0])\n"
  "\n"
  "    def command_exceptions(self, cmd):\n"
  "        \"\"\"exceptions ON|OFF: If ON then detailed tracebacks are shown on exceptions (default OFF)\n"
  "\n"
  "        Normally when an exception occurs the error string only is\n"
  "        displayed.  However it is sometimes useful to get a full\n"
  "        traceback.  An example would be when you are developing\n"
  "        virtual tables and using the shell to exercise them.  In\n"
  "        addition to displaying each stack frame, the local variables\n"
  "        within each frame are also displayed.\n"
  "        \"\"\"\n"
  "        self.exceptions=self._boolean_command(\"exceptions\", cmd)\n"
  "\n"
  "\n"
  "    def command_exit(self, cmd):\n"
  "        \"\"\"exit:Exit this program\"\"\"\n"
  "        if len(cmd):\n"
  "            raise self.Error(\"Exit doesn't take any parameters\")\n"
  "        sys.exit(0)\n"
  "\n"
  "    def command_quit(self, cmd):\n"
  "        \"\"\"quit:Exit this program\"\"\"\n"
  "        if len(cmd):\n"
  "            raise self.Error(\"Quit doesn't take any parameters\")\n"
  "        sys.exit(0)\n"
  "\n"
  "    def command_explain(self, cmd):\n"
  "        \"\"\"explain ON|OFF: Set output mode suitable for explain (default OFF)\n"
  "\n"
  "        Explain shows the underlying SQLite virtual machine code for a\n"
  "        statement.  You need to prefix the SQL with explain.  For example:\n"
  "\n"
  "           explain select * from table;\n"
  "\n"
  "        This output mode formats the explain output nicely.  If you do\n"
  "        '.explain OFF' then the output mode and settings in place when\n"
  "        you did '.explain ON' are restored.\n"
  "        \"\"\"\n"
  "        if len(cmd)==0 or self._boolean_command(\"explain\", cmd):\n"
  "            self.push_output()\n"
  "            self.header=True\n"
  "            self.widths=[4,13,4,4,4,13,2,13]\n"
  "            self.truncate=False\n"
  "            self.output=self.output_column\n"
  "        else:\n"
  "            self.pop_output()\n"
  "\n"
  "    def command_find(self, cmd):\n"
  "        \"\"\"find what ?TABLE?: Searches all columns of all tables for a value\n"
  "\n"
  "        The find command helps you locate data across your database\n"
  "        for example to find a string or any references to an id.\n"
  "\n"
  "        You can specify a like pattern to limit the search to a subset\n"
  "        of tables (eg specifying 'CUSTOMER%' for all tables beginning\n"
  "        with CUSTOMER).\n"
  "\n"
  "        The what value will be treated as a string and/or integer if\n"
  "        possible.  If what contains % or _ then it is also treated as\n"
  "        a like pattern.\n"
  "\n"
  "        This command will take a long time to execute needing to read\n"
  "        all of the relevant tables.\n"
  "        \"\"\"\n"
  "        if len(cmd)<1 or len(cmd)>2:\n"
  "            raise self.Error(\"At least one argument required and at most two accepted\")\n"
  "        tablefilter=\"%\"\n"
  "        if len(cmd)==2:\n"
  "            tablefilter=cmd[1]\n"
  "        querytemplate=[]\n"
  "        queryparams=[]\n"
  "        def qp(): # binding for current queryparams\n"
  "            return \"?\"+str(len(queryparams))\n"
  "        s=cmd[0]\n"
  "        if '%' in s or '_' in s:\n"
  "            queryparams.append(s)\n"
  "            querytemplate.append(\"%s LIKE \"+qp())\n"
  "        queryparams.append(s)\n"
  "        querytemplate.append(\"%s = \"+qp())\n"
  "        try:\n"
  "            i=int(s)\n"
  "            queryparams.append(i)\n"
  "            querytemplate.append(\"%s = \"+qp())\n"
  "        except ValueError:\n"
  "            pass\n"
  "        querytemplate=\" OR \".join(querytemplate)\n"
  "        for (table,) in self.db.cursor().execute(\"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE ?1\", (tablefilter,)):\n"
  "            t=self._fmt_sql_identifier(table)\n"
  "            query=\"SELECT * from %s WHERE \" % (t,)\n"
  "            colq=[]\n"
  "            for _,column,_,_,_,_ in self.db.cursor().execute(\"pragma table_info(%s)\" % (t,)):\n"
  "                colq.append(querytemplate % ((self._fmt_sql_identifier(column),)*len(queryparams)))\n"
  "            query=query+\" OR \".join(colq)\n"
  "            self.process_sql(query, queryparams, internal=True, summary=(\"Table \"+table+\"\\n\", \"\\n\"))\n"
  "\n"
  "    def command_header(self, cmd):\n"
  "        \"\"\"header(s) ON|OFF: Display the column names in output (default OFF)\n"
  "\n"
  "        \"\"\"\n"
  "        self.header=self._boolean_command(\"header\", cmd)\n"
  "\n"
  "    command_headers=command_header\n"
  "\n"
  "    _help_info=None\n"
  "\n"
  "    def command_help(self, cmd):\n"
  "        \"\"\"help ?COMMAND?: Shows list of commands and their usage.  If COMMAND is specified then shows detail about that COMMAND.  ('.help all' will show detailed help about all commands.)\n"
  "        \"\"\"\n"
  "        if not self._help_info:\n"
  "            self._help_info={}\n"
  "            for c in dir(self):\n"
  "                if not c.startswith(\"command_\"):\n"
  "                    continue\n"
  "                d=getattr(self, c).__doc__\n"
  "                assert d, c+\" command must have documentation\"\n"
  "                c=c[len(\"command_\"):]\n"
  "                if c in (\"headers\", \"color\"): continue\n"
  "                while d[0]==\"\\n\":\n"
  "                    d=d[1:]\n"
  "                parts=d.split(\"\\n\", 1)\n"
  "                firstline=parts[0].strip().split(\":\", 1)\n"
  "                assert len(firstline)==2, c+\" command must have usage: description doc\"\n"
  "                if len(parts)==1 or len(parts[1].strip())==0: # work around textwrap bug\n"
  "                    multi=\"\"\n"
  "                else:\n"
  "                    multi=textwrap.dedent(parts[1])\n"
  "                if c==\"mode\":\n"
  "                    if not self._output_modes:\n"
  "                        self._cache_output_modes()\n"
  "                    firstline[1]=firstline[1]+\" \"+\" \".join(self._output_modes)\n"
  "                    multi=multi+\"\\n\\n\"+\"\\n\\n\".join(self._output_modes_detail)\n"
  "                if c==\"colour\":\n"
  "                    colours=list(self._colours.keys())\n"
  "                    colours.sort()\n"
  "                    firstline[1]=firstline[1]+\" from \"+\", \".join(colours)\n"
  "                if len(multi.strip())==0: # All whitespace\n"
  "                    multi=None\n"
  "                else:\n"
  "                    multi=multi.strip(\"\\n\")\n"
  "                    multi=multi.replace(\"\\n\\n\", \"\\x00\")\n"
  "                    multi=multi.replace(\"\\n\", \" \")\n"
  "                    multi=multi.replace(\"\\x00\", \"\\n\\n\")\n"
  "                    multi=multi.split(\"\\n\\n\")\n"
  "                self._help_info[c]=('.'+firstline[0].strip(), firstline[1].strip(), multi)\n"
  "\n"
  "        self.write(self.stderr, \"\\n\")\n"
  "\n"
  "        tw=self._terminal_width()\n"
  "        if tw<32:\n"
  "            tw=32\n"
  "        if len(cmd)==0:\n"
  "            commands=list(self._help_info.keys())\n"
  "            commands.sort()\n"
  "            w=0\n"
  "            for command in commands:\n"
  "                if len(self._help_info[command][0])>w:\n"
  "                    w=len(self._help_info[command][0])\n"
  "            out=[]\n"
  "            for command in commands:\n"
  "                hi=self._help_info[command]\n"
  "                out.append(hi[0])\n"
  "                out.append(\" \"*(2+w-len(hi[0])))\n"
  "                out.append((\"\\n\"+\" \"*(2+w)).join(textwrap.wrap(hi[1], tw-w-2)))\n"
  "                out.append(\"\\n\")\n"
  "            self.write(self.stderr, \"\".join(out))\n"
  "        else:\n"
  "            if cmd[0]==\"all\":\n"
  "                cmd=list(self._help_info.keys())\n"
  "                cmd.sort()\n"
  "            w=0\n"
  "            for command in self._help_info:\n"
  "                if len(self._help_info[command][0])>w:\n"
  "                    w=len(self._help_info[command][0])\n"
  "\n"
  "            for command in cmd:\n"
  "                if command==\"headers\": command=\"header\"\n"
  "                if command not in self._help_info:\n"
  "                    raise self.Error(\"No such command \\\"%s\\\"\" % (command,))\n"
  "                out=[]\n"
  "                hi=self._help_info[command]\n"
  "                out.append(hi[0])\n"
  "                out.append(\" \"*(2+w-len(hi[0])))\n"
  "                out.append((\"\\n\"+\" \"*(2+w)).join(textwrap.wrap(hi[1], tw-w-2))+\"\\n\")\n"
  "                if hi[2]:\n"
  "                    out.append(\"\\n\")\n"
  "                    for i,para in enumerate(hi[2]):\n"
  "                        out.append(textwrap.fill(para, tw)+\"\\n\")\n"
  "                        if i<len(hi[2])-1:\n"
  "                            out.append(\"\\n\")\n"
  "                if command!=cmd[0]:\n"
  "                    self.write(self.stderr, \"\\n\"+\"=\"*tw+\"\\n\")\n"
  "                self.write(self.stderr, \"\".join(out))\n"
  "        self.write(self.stderr, \"\\n\")\n"
  "\n"
  "    def command_import(self, cmd):\n"
  "        \"\"\"import FILE TABLE: Imports separated data from FILE into TABLE\n"
  "\n"
  "        Reads data from the file into the named table using the\n"
  "        current separator and encoding.  For example if the separator\n"
  "        is currently a comma then the file should be CSV (comma\n"
  "        separated values).\n"
  "\n"
  "        All values read in are supplied to SQLite as strings.  If you\n"
  "        want SQLite to treat them as other types then declare your\n"
  "        columns appropriately.  For example declaring a column 'REAL'\n"
  "        will result in the values being stored as floating point if\n"
  "        they can be safely converted.  See this page for more details:\n"
  "\n"
  "          https://sqlite.org/datatype3.html\n"
  "\n"
  "        Another alternative is to create a tempory table, insert the\n"
  "        values into that and then use casting.\n"
  "\n"
  "          CREATE TEMPORARY TABLE import(a,b,c);\n"
  "\n"
  "          .import filename import\n"
  "\n"
  "          CREATE TABLE final AS SELECT cast(a as BLOB), cast(b as INTEGER), cast(c as CHAR) from import;\n"
  "\n"
  "          DROP TABLE import;\n"
  "\n"
  "        You can also get more sophisticated using the SQL CASE\n"
  "        operator.  For example this will turn zero length strings into\n"
  "        null:\n"
  "\n"
  "          SELECT CASE col WHEN '' THEN null ELSE col END FROM ...\n"
  "        \"\"\"\n"
  "        if len(cmd)!=2:\n"
  "            raise self.Error(\"import takes two parameters\")\n"
  "\n"
  "        try:\n"
  "            final=None\n"
  "            self.db.cursor().execute(\"BEGIN IMMEDIATE\")\n"
  "            final=\"ROLLBACK\"\n"
  "\n"
  "            ncols=len(self.db.cursor().execute(\"pragma table_info(\"+self._fmt_sql_identifier(cmd[1])+\")\").fetchall())\n"
  "            if ncols<1:\n"
  "                raise self.Error(\"No such table '%s'\" % (cmd[1],))\n"
  "\n"
  "            cur=self.db.cursor()\n"
  "            sql=\"insert into %s values(%s)\" % (self._fmt_sql_identifier(cmd[1]), \",\".join(\"?\"*ncols))\n"
  "\n"
  "            kwargs={}\n"
  "            if self.separator==\",\":\n"
  "                kwargs[\"dialect\"]=\"excel\"\n"
  "            elif self.separator==\"\\t\":\n"
  "                kwargs[\"dialect\"]=\"excel-tab\"\n"
  "            else:\n"
  "                kwargs[\"quoting\"]=csv.QUOTE_NONE\n"
  "                kwargs[\"delimiter\"]=self.separator\n"
  "                kwargs[\"doublequote\"]=False\n"
  "                kwargs[\"quotechar\"]=\"\\x00\"\n"
  "            row=1\n"
  "            for line in self._csvin_wrapper(cmd[0], kwargs):\n"
  "                if len(line)!=ncols:\n"
  "                    raise self.Error(\"row %d has %d columns but should have %d\" % (row, len(line), ncols))\n"
  "                try:\n"
  "                    cur.execute(sql, line)\n"
  "                except:\n"
  "                    self.write(self.stderr, \"Error inserting row %d\" % (row,))\n"
  "                    raise\n"
  "                row+=1\n"
  "            self.db.cursor().execute(\"COMMIT\")\n"
  "\n"
  "        except:\n"
  "            if final:\n"
  "                self.db.cursor().execute(final)\n"
  "            raise\n"
  "\n"
  "    def _csvin_wrapper(self, filename, dialect):\n"
  "\n"
  "        if sys.version_info>=(3,0):\n"
  "            thefile=codecs.open(filename, \"r\", self.encoding[0])\n"
  "            for line in csv.reader(thefile, **dialect.copy()):\n"
  "                yield line\n"
  "            thefile.close()\n"
  "            return\n"
  "\n"
  "        if self.encoding[0].lower()==\"utf8\": # no need for tempfile\n"
  "            thefile=open(filename, \"rb\")\n"
  "        else:\n"
  "            import tempfile\n"
  "            thefile=tempfile.TemporaryFile(prefix=\"apsw_import\")\n"
  "            thefile.write(codecs.open(filename, \"r\", self.encoding[0]).read().encode(\"utf8\"))\n"
  "            thefile.seek(0,0)\n"
  "\n"
  "        for k,v in dialect.items():\n"
  "            if isinstance(v, unicode):\n"
  "                dialect[k]=v.encode(\"utf8\")\n"
  "        for line in csv.reader(thefile, **dialect):\n"
  "            yield [x.decode(\"utf8\") for x in line]\n"
  "        thefile.close()\n"
  "\n"
  "    def command_autoimport(self, cmd):\n"
  "        \"\"\"autoimport FILENAME ?TABLE?: Imports filename creating a table and automatically working out separators and data types (alternative to .import command)\n"
  "\n"
  "        The import command requires that you precisely pre-setup the\n"
  "        table and schema, and set the data separators (eg commas or\n"
  "        tabs).  In many cases this information can be automatically\n"
  "        deduced from the file contents which is what this command\n"
  "        does.  There must be at least two columns and two rows.\n"
  "\n"
  "        If the table is not specified then the basename of the file\n"
  "        will be used.\n"
  "\n"
  "        Additionally the type of the contents of each column is also\n"
  "        deduced - for example if it is a number or date.  Empty values\n"
  "        are turned into nulls.  Dates are normalized into YYYY-MM-DD\n"
  "        format and DateTime are normalized into ISO8601 format to\n"
  "        allow easy sorting and searching.  4 digit years must be used\n"
  "        to detect dates.  US (swapped day and month) versus rest of\n"
  "        the world is also detected providing there is at least one\n"
  "        value that resolves the ambiguity.\n"
  "\n"
  "        Care is taken to ensure that columns looking like numbers are\n"
  "        only treated as numbers if they do not have unnecessary\n"
  "        leading zeroes or plus signs.  This is to avoid treating phone\n"
  "        numbers and similar number like strings as integers.\n"
  "\n"
  "        This command can take quite some time on large files as they\n"
  "        are effectively imported twice.  The first time is to\n"
  "        determine the format and the types for each column while the\n"
  "        second pass actually imports the data.\n"
  "        \"\"\"\n"
  "        if len(cmd)<1 or len(cmd)>2:\n"
  "            raise self.Error(\"Expected one or two parameters\")\n"
  "        if not os.path.exists(cmd[0]):\n"
  "            raise self.Error(\"File \\\"%s\\\" does not exist\" % (cmd[0],))\n"
  "        if len(cmd)==2:\n"
  "            tablename=cmd[1]\n"
  "        else:\n"
  "            tablename=None\n"
  "        try:\n"
  "            final=None\n"
  "            c=self.db.cursor()\n"
  "            c.execute(\"BEGIN IMMEDIATE\")\n"
  "            final=\"ROLLBACK\"\n"
  "\n"
  "            if not tablename:\n"
  "                tablename=os.path.splitext(os.path.basename(cmd[0]))[0]\n"
  "\n"
  "            if c.execute(\"pragma table_info(%s)\" % (self._fmt_sql_identifier(tablename),)).fetchall():\n"
  "                raise self.Error(\"Table \\\"%s\\\" already exists\" % (tablename,))\n"
  "\n"
  "            def DateUS(v): # US formatted date with wrong ordering of day and month\n"
  "                return DateWorld(v, switchdm=True)\n"
  "            def DateWorld(v, switchdm=False): # Sensibly formatted date as used anywhere else in the world\n"
  "                y,m,d=self._getdate(v)\n"
  "                if switchdm: m,d=d,m\n"
  "                if m<1 or m>12 or d<1 or d>31:\n"
  "                    raise ValueError\n"
  "                return \"%d-%02d-%02d\" % (y,m,d)\n"
  "            def DateTimeUS(v): # US date and time\n"
  "                return DateTimeWorld(v, switchdm=True)\n"
  "            def DateTimeWorld(v, switchdm=False): # Sensible date and time\n"
  "                y,m,d,h,M,s=self._getdatetime(v)\n"
  "                if switchdm: m,d=d,m\n"
  "                if m<1 or m>12 or d<1 or d>31 or h<0 or h>23 or M<0 or M>59 or s<0 or s>65:\n"
  "                    raise ValueError\n"
  "                return \"%d-%02d-%02dT%02d:%02d:%02d\" % (y,m,d,h,M,s)\n"
  "            def Number(v): # we really don't want phone numbers etc to match\n"
  "                if re.search(r\"\\s\", v):\n"
  "                    raise ValueError\n"
  "                if v==\"0\": return 0\n"
  "                if v[0]==\"+\": # idd prefix\n"
  "                    raise ValueError\n"
  "                if re.match(\"^[0-9]+$\", v):\n"
  "                    if v[0]==\"0\": raise ValueError # also a phone number\n"
  "                    return int(v)\n"
  "                if v[0]==\"0\" and not v.startswith(\"0.\"): # deceptive not a number\n"
  "                    raise ValueError\n"
  "                return float(v)\n"
  "\n"
  "            formats=[\n"
  "                {\"dialect\": \"excel\"},\n"
  "                {\"dialect\": \"excel-tab\"}]\n"
  "            seps=[\"|\", \";\", \":\"]\n"
  "            if self.separator not in seps:\n"
  "                seps.append(self.separator)\n"
  "            for sep in seps:\n"
  "                formats.append(\n"
  "                    {\"quoting\": csv.QUOTE_NONE,\n"
  "                     \"delimiter\": sep,\n"
  "                     \"doublequote\": False,\n"
  "                     \"quotechar\": \"\\x00\"}\n"
  "                    )\n"
  "            possibles=[]\n"
  "            errors=[]\n"
  "            encodingissue=False\n"
  "            for format in formats:\n"
  "                ncols=-1\n"
  "                lines=0\n"
  "                try:\n"
  "                    for line in self._csvin_wrapper(cmd[0], format.copy()):\n"
  "                        if lines==0:\n"
  "                            lines=1\n"
  "                            ncols=len(line)\n"
  "                            datas=[]\n"
  "                            for i in range(ncols):\n"
  "                                datas.append([DateUS, DateWorld, DateTimeUS, DateTimeWorld, Number])\n"
  "                            allblanks=[True]*ncols\n"
  "                            continue\n"
  "                        if len(line)!=ncols:\n"
  "                            raise ValueError(\"Expected %d columns - got %d\" % (ncols, len(line)))\n"
  "                        lines+=1\n"
  "                        for i in range(ncols):\n"
  "                            if not line[i]:\n"
  "                                continue\n"
  "                            allblanks[i]=False\n"
  "                            if not datas[i]:\n"
  "                                continue\n"
  "                            d=[]\n"
  "                            for dd in datas[i]:\n"
  "                                try:\n"
  "                                    dd(line[i])\n"
  "                                    d.append(dd)\n"
  "                                except ValueError:\n"
  "                                    pass\n"
  "                            datas[i]=d\n"
  "                    if ncols>1 and lines>1:\n"
  "                        for i in range(ncols):\n"
  "                            if allblanks[i]:\n"
  "                                datas[i]=[]\n"
  "                        possibles.append((format.copy(), ncols, lines, datas))\n"
  "                except UnicodeDecodeError:\n"
  "                    encodingissue=True\n"
  "                except:\n"
  "                    s=str(sys.exc_info()[1])\n"
  "                    if s not in errors:\n"
  "                        errors.append(s)\n"
  "\n"
  "            if len(possibles)==0:\n"
  "                if encodingissue:\n"
  "                    raise self.Error(\"The file is probably not in the current encoding \\\"%s\\\" and didn't match a known file format\" % (self.encoding[0],))\n"
  "                v=\"File doesn't appear to match a known type.\"\n"
  "                if len(errors):\n"
  "                    v+=\"  Errors reported:\\n\"+\"\\n\".join([\"  \"+e for e in errors])\n"
  "                raise self.Error(v)\n"
  "            if len(possibles)>1:\n"
  "                raise self.Error(\"File matches more than one type!\")\n"
  "            format, ncols, lines, datas=possibles[0]\n",
  "            fmt=format.get(\"dialect\", None)\n"
  "            if fmt is None:\n"
  "                fmt=\"(delimited by \\\"%s\\\")\" % (format[\"delimiter\"],)\n"
  "            self.write(self.stdout, \"Detected Format %s  Columns %d  Rows %d\\n\" % (fmt, ncols, lines))\n"
  "            reader=self._csvin_wrapper(cmd[0], format)\n"
  "            for header in reader:\n"
  "                break\n"
  "            identity=lambda x:x\n"
  "            for i in range(ncols):\n"
  "                if len(datas[i])>1:\n"
  "                    raise self.Error(\"Column #%d \\\"%s\\\" has ambiguous data format - %s\" % (i+1, header[i], \", \".join([d.__name__ for d in datas[i]])))\n"
  "                if datas[i]:\n"
  "                    datas[i]=datas[i][0]\n"
  "                else:\n"
  "                    datas[i]=identity\n"
  "            sql=\"CREATE TABLE %s(%s)\" % (self._fmt_sql_identifier(tablename), \", \".join([self._fmt_sql_identifier(h) for h in header]))\n"
  "            c.execute(sql)\n"
  "            sql=\"INSERT INTO %s VALUES(%s)\" % (self._fmt_sql_identifier(tablename), \",\".join([\"?\"]*ncols))\n"
  "            for line in reader:\n"
  "                vals=[]\n"
  "                for i in range(ncols):\n"
  "                    l=line[i]\n"
  "                    if not l:\n"
  "                        vals.append(None)\n"
  "                    else:\n"
  "                        vals.append(datas[i](l))\n"
  "                c.execute(sql, vals)\n"
  "\n"
  "            c.execute(\"COMMIT\")\n"
  "            self.write(self.stdout, \"Auto-import into table \\\"%s\\\" complete\\n\" % (tablename,))\n"
  "        except:\n"
  "            if final:\n"
  "                self.db.cursor().execute(final)\n"
  "            raise\n"
  "\n"
  "    def _getdate(self, v):\n"
  "        m=re.match(r\"^([0-9]+)[^0-9]([0-9]+)[^0-9]([0-9]+)$\", v)\n"
  "        if not m:\n"
  "            raise ValueError\n"
  "        y,m,d=int(m.group(1)), int(m.group(2)), int(m.group(3))\n"
  "        if d>1000: # swap order\n"
  "            y,m,d=d,m,y\n"
  "        if y<1000 or y>9999:\n"
  "            raise ValueError\n"
  "        return y,m,d\n"
  "\n"
  "    def _getdatetime(self, v):\n"
  "        m=re.match(r\"^([0-9]+)[^0-9]([0-9]+)[^0-9]([0-9]+)[^0-9]+([0-9]+)[^0-9]([0-9]+)([^0-9]([0-9]+))?$\", v)\n"
  "        if not m:\n"
  "            raise ValueError\n"
  "        items=list(m.group(1,2,3,4,5,7))\n"
  "        for i in range(len(items)):\n"
  "            if items[i] is None:\n"
  "                items[i]=0\n"
  "        items=[int(i) for i in items]\n"
  "        if items[2]>1000:\n"
  "            items=[items[2], items[1], items[0]]+items[3:]\n"
  "        if items[0]<1000 or items[0]>9999:\n"
  "            raise ValueError\n"
  "        return items\n"
  "\n"
  "    def command_indices(self, cmd):\n"
  "        \"\"\"indices TABLE: Lists all indices on table TABLE\n"
  "\n"
  "        \"\"\"\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"indices takes one table name\")\n"
  "        self.push_output()\n"
  "        self.header=False\n"
  "        self.output=self.output_list\n"
  "        try:\n"
  "            self.process_sql(\"SELECT name FROM sqlite_master WHERE type='index' AND tbl_name LIKE ?1 \"\n"
  "                             \"UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' AND tbl_name LIKE \"\n"
  "                             \"?1 ORDER by name\", cmd, internal=True)\n"
  "        finally:\n"
  "            self.pop_output()\n"
  "\n"
  "    def command_load(self, cmd):\n"
  "        \"\"\"load FILE ?ENTRY?: Loads a SQLite extension library\n"
  "\n"
  "        Note: Extension loading may not be enabled in the SQLite\n"
  "        library version you are using.\n"
  "\n"
  "        Extensions are an easy way to add new functions and\n"
  "        functionality.  For a useful extension look at the bottom of\n"
  "        https://sqlite.org/contrib\n"
  "\n"
  "        By default sqlite3_extension_init is called in the library but\n"
  "        you can specify an alternate entry point.\n"
  "\n"
  "        If you get an error about the extension not being found you\n"
  "        may need to explicitly specify the directory.  For example if\n"
  "        it is in the current directory then use:\n"
  "\n"
  "          .load ./extension.so\n"
  "        \"\"\"\n"
  "        if len(cmd)<1 or len(cmd)>2:\n"
  "            raise self.Error(\"load takes one or two parameters\")\n"
  "        try:\n"
  "            self.db.enableloadextension(True)\n"
  "        except:\n"
  "            raise self.Error(\"Extension loading is not supported\")\n"
  "\n"
  "        self.db.loadextension(*cmd)\n"
  "\n"
  "    _output_modes=None\n"
  "\n"
  "    def command_mode(self, cmd):\n"
  "        \"\"\"mode MODE ?TABLE?: Sets output mode to one of\"\"\"\n"
  "        if len(cmd) in (1,2):\n"
  "            w=cmd[0]\n"
  "            if w==\"tabs\":\n"
  "                w=\"list\"\n"
  "            m=getattr(self, \"output_\"+w, None)\n"
  "            if w!=\"insert\":\n"
  "                if len(cmd)==2:\n"
  "                    raise self.Error(\"Output mode %s doesn't take parameters\" % (cmd[0]))\n"
  "            if m:\n"
  "                self.output=m\n"
  "                self.truncate=True\n"
  "                if cmd[0]==\"csv\":\n"
  "                    self.separator=\",\"\n"
  "                elif cmd[0]==\"tabs\":\n"
  "                    self.separator=\"\\t\"\n"
  "                else:\n"
  "                    pass\n"
  "                if w==\"insert\":\n"
  "                    if len(cmd)==2:\n"
  "                        self._output_table=cmd[1]\n"
  "                    else:\n"
  "                        self._output_table=\"table\"\n"
  "                    self._output_table=self._fmt_sql_identifier(self._output_table)\n"
  "                return\n"
  "        if not self._output_modes:\n"
  "            self._cache_output_modes()\n"
  "        raise self.Error(\"Expected a valid output mode: \"+\", \".join(self._output_modes))\n"
  "\n"
  "    def _cache_output_modes(self):\n"
  "        modes=[m[len(\"output_\"):] for m in dir(self) if m.startswith(\"output_\")]\n"
  "        modes.append(\"tabs\")\n"
  "        modes.sort()\n"
  "        self._output_modes=modes\n"
  "\n"
  "        detail=[]\n"
  "\n"
  "        for m in modes:\n"
  "            if m=='tabs': continue\n"
  "            d=getattr(self, \"output_\"+m).__doc__\n"
  "            assert d, \"output mode \"+m+\" needs doc\"\n"
  "            d=d.replace(\"\\n\", \" \").strip()\n"
  "            while \"  \" in d:\n"
  "                d=d.replace(\"  \", \" \")\n"
  "            detail.append(m+\": \"+d)\n"
  "        self._output_modes_detail=detail\n"
  "\n"
  "    def command_nullvalue(self, cmd):\n"
  "        \"\"\"nullvalue STRING: Print STRING in place of null values\n"
  "\n"
  "        This affects textual output modes like column and list and\n"
  "        sets how SQL null values are shown.  The default is a zero\n"
  "        length string.  Insert mode and dumps are not affected by this\n"
  "        setting.  You can use double quotes to supply a zero length\n"
  "        string.  For example:\n"
  "\n"
  "          .nullvalue \"\"         # the default\n"
  "          .nullvalue <NULL>     # rather obvious\n"
  "          .nullvalue \" \\\\t \"     # A tab surrounded by spaces\n"
  "        \"\"\"\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"nullvalue takes exactly one parameter\")\n"
  "        self.nullvalue=self.fixup_backslashes(cmd[0])\n"
  "\n"
  "    def command_open(self, cmd):\n"
  "        \"\"\"open ?OPTIONS? ?FILE?: Closes existing database and opens a different one\n"
  "\n"
  "        Options are: --new which deletes the file if it already exists\n"
  "\n"
  "        If FILE is omitted then a memory database is opened\n"
  "        \"\"\"\n"
  "        new=False\n"
  "        dbname=None\n"
  "        c=cmd\n"
  "        while c:\n"
  "            p=c.pop(0)\n"
  "            if p.startswith(\"--\"):\n"
  "                if p==\"--new\":\n"
  "                    new=True\n"
  "                    continue\n"
  "                raise self.Error(\"Unknown open param: \"+p)\n"
  "            if dbname:\n"
  "                raise self.Error(\"Too many arguments: \"+p)\n"
  "            dbname=p\n"
  "\n"
  "        if new and dbname:\n"
  "            self.db=(None, None)\n"
  "            for suffix in \"\", \"-journal\", \"-wal\", \"-shm\":\n"
  "                fn=dbname+suffix\n"
  "                for retry in range(1, 5):\n"
  "                    try:\n"
  "                        os.remove(fn)\n"
  "                        break\n"
  "                    except OSError:\n"
  "                        if not os.path.isfile(fn):\n"
  "                            break\n"
  "                        import gc ; gc.collect(2)\n"
  "                        time.sleep(.05*retry)\n"
  "                else:\n"
  "                    os.rename(fn, fn+\"-DELETEME\")\n"
  "\n"
  "        self.db=(None, dbname)\n"
  "\n"
  "    def command_output(self, cmd):\n"
  "        \"\"\"output FILENAME: Send output to FILENAME (or stdout)\n"
  "\n"
  "        If the FILENAME is stdout then output is sent to standard\n"
  "        output from when the shell was started.  The file is opened\n"
  "        using the current encoding (change with .encoding command).\n"
  "        \"\"\"\n"
  "        self.stdout.flush()\n"
  "        self.stderr.flush()\n"
  "        if hasattr(self.stdin, \"flush\"):\n"
  "            try:\n"
  "                self.stdin.flush()\n"
  "            except IOError: # see issue 117\n"
  "                pass\n"
  "\n"
  "\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"You must specify a filename\")\n"
  "\n"
  "        try:\n"
  "            fname=cmd[0]\n"
  "            if fname==\"stdout\":\n"
  "                old=None\n"
  "                if self.stdout!=self._original_stdout:\n"
  "                    old=self.stdout\n"
  "                self.stdout=self._original_stdout\n"
  "                if old is not None: # done here in case close raises exception\n"
  "                    old.close()\n"
  "                return\n"
  "\n"
  "            newf=codecs.open(fname, \"w\", self.encoding[0], self.encoding[1])\n"
  "            old=None\n"
  "            if self.stdout!=self._original_stdout:\n"
  "                old=self.stdout\n"
  "            self.stdout=newf\n"
  "            if old is not None:\n"
  "                old.close()\n"
  "        finally:\n"
  "            self._out_colour()\n"
  "\n"
  "    def command_print(self, cmd):\n"
  "        \"\"\"print STRING: print the literal STRING\n"
  "\n"
  "        If more than one argument is supplied then they are printed\n"
  "        space separated.  You can use backslash escapes such as \\\\n\n"
  "        and \\\\t.\n"
  "        \"\"\"\n"
  "        self.write(self.stdout, \" \".join([self.fixup_backslashes(i) for i in cmd])+\"\\n\")\n"
  "\n"
  "    def command_prompt(self, cmd):\n"
  "        \"\"\"prompt MAIN ?CONTINUE?: Changes the prompts for first line and continuation lines\n"
  "\n"
  "        The default is to print 'sqlite> ' for the main prompt where\n"
  "        you can enter a dot command or a SQL statement.  If the SQL\n"
  "        statement is complete (eg not ; terminated) then you are\n"
  "        prompted for more using the continuation prompt which defaults\n"
  "        to ' ..> '.  Example:\n"
  "\n"
  "          .prompt \"Yes, Master> \" \"More, Master> \"\n"
  "\n"
  "        You can use backslash escapes such as \\\\n and \\\\t.\n"
  "        \"\"\"\n"
  "        if len(cmd)<1 or len(cmd)>2:\n"
  "            raise self.Error(\"prompt takes one or two arguments\")\n"
  "        self.prompt=self.fixup_backslashes(cmd[0])\n"
  "        if len(cmd)==2:\n"
  "            self.moreprompt=self.fixup_backslashes(cmd[1])\n"
  "\n"
  "    def command_read(self, cmd):\n"
  "        \"\"\"read FILENAME: Processes SQL and commands in FILENAME (or Python if FILENAME ends with .py)\n"
  "\n"
  "        Treats the specified file as input (a mixture or SQL and/or\n"
  "        dot commands).  If the filename ends in .py then it is treated\n"
  "        as Python code instead.\n"
  "\n"
  "        For Python code the symbol 'shell' refers to the instance of\n"
  "        the shell and 'apsw' is the apsw module.\n"
  "        \"\"\"\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"read takes a single filename\")\n"
  "        if cmd[0].lower().endswith(\".py\"):\n"
  "            g={}\n"
  "            g.update({'apsw': apsw, 'shell': self})\n"
  "            if sys.version_info<(3,0):\n"
  "                execfile(cmd[0], g, g)\n"
  "            else:\n"
  "                exec(compile(open(cmd[0]).read(), cmd[0], 'exec'), g, g)\n"
  "        else:\n"
  "            f=codecs.open(cmd[0], \"rU\", self.encoding[0])\n"
  "            try:\n"
  "                try:\n"
  "                    self.push_input()\n"
  "                    self.stdin=f\n"
  "                    self.interactive=False\n"
  "                    self.input_line_number=0\n"
  "                    while True:\n"
  "                        line=self.getcompleteline()\n"
  "                        if line is None:\n"
  "                            break\n"
  "                        self.process_complete_line(line)\n"
  "                except:\n"
  "                    eval=sys.exc_info()[1]\n"
  "                    if not isinstance(eval, SystemExit):\n"
  "                        self._append_input_description()\n"
  "                    raise\n"
  "\n"
  "            finally:\n"
  "                self.pop_input()\n"
  "                f.close()\n"
  "\n"
  "    def command_restore(self, cmd):\n"
  "        \"\"\"restore ?DB? FILE: Restore database from FILE into DB (default \"main\")\n"
  "\n"
  "        Copies the contents of FILE to the current database (default \"main\").\n"
  "        The backup is done at the page level - SQLite copies the pages as\n"
  "        is.  There is no round trip through SQL code.\n"
  "        \"\"\"\n"
  "        dbname=\"main\"\n"
  "        if len(cmd)==1:\n"
  "            fname=cmd[0]\n"
  "        elif len(cmd)==2:\n"
  "            dbname=cmd[0]\n"
  "            fname=cmd[1]\n"
  "        else:\n"
  "            raise self.Error(\"Restore takes one or two parameters\")\n"
  "        input=apsw.Connection(fname)\n"
  "        b=self.db.backup(dbname, input, \"main\")\n"
  "        try:\n"
  "            while not b.done:\n"
  "                b.step()\n"
  "        finally:\n"
  "            b.finish()\n"
  "            input.close()\n"
  "\n"
  "    def command_schema(self, cmd):\n"
  "        \"\"\"schema ?TABLE? [TABLE...]: Shows SQL for table\n"
  "\n"
  "        If you give one or more tables then their schema is listed\n"
  "        (including indices).  If you don't specify any then all\n"
  "        schemas are listed. TABLE is a like pattern so you can % for\n"
  "        wildcards.\n"
  "        \"\"\"\n"
  "        self.push_output()\n"
  "        self.output=self.output_list\n"
  "        self.header=False\n"
  "        try:\n"
  "            if len(cmd)==0:\n"
  "                cmd=['%']\n"
  "            for n in cmd:\n"
  "                self.process_sql(\"SELECT sql||';' FROM \"\n"
  "                                 \"(SELECT sql sql, type type, tbl_name tbl_name, name name \"\n"
  "                                 \"FROM sqlite_master UNION ALL \"\n"
  "                                 \"SELECT sql, type, tbl_name, name FROM sqlite_temp_master) \"\n"
  "                                 \"WHERE tbl_name LIKE ?1 AND type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' \"\n"
  "                                 \"ORDER BY substr(type,2,1), name\", (n,), internal=True)\n"
  "        finally:\n"
  "            self.pop_output()\n"
  "\n"
  "    def command_separator(self, cmd):\n"
  "        \"\"\"separator STRING: Change separator for output mode and .import\n"
  "\n"
  "        You can use quotes and backslashes.  For example to set the\n"
  "        separator to space tab space you can use:\n"
  "\n"
  "          .separator \" \\\\t \"\n"
  "\n"
  "        The setting is automatically changed when you switch to csv or\n"
  "        tabs output mode.  You should also set it before doing an\n"
  "        import (ie , for CSV and \\\\t for TSV).\n"
  "        \"\"\"\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"separator takes exactly one parameter\")\n"
  "        self.separator=self.fixup_backslashes(cmd[0])\n"
  "\n"
  "    _shows=(\"echo\", \"explain\", \"headers\", \"mode\", \"nullvalue\", \"output\", \"separator\", \"width\", \"exceptions\", \"encoding\")\n"
  "\n"
  "    def command_show(self, cmd):\n"
  "        \"\"\"show: Show the current values for various settings.\"\"\"\n"
  "        if len(cmd)>1:\n"
  "            raise self.Error(\"show takes at most one parameter\")\n"
  "        if len(cmd):\n"
  "            what=cmd[0]\n"
  "            if what not in self._shows:\n"
  "                raise self.Error(\"Unknown show: '%s'\" % (what,))\n"
  "        else:\n"
  "            what=None\n"
  "\n"
  "        outs=[]\n"
  "        for i in self._shows:\n"
  "            k=i\n"
  "            if what and i!=what:\n"
  "                continue\n"
  "            if i in (\"echo\", \"headers\", \"exceptions\"):\n"
  "                if i==\"headers\": i=\"header\"\n"
  "                v=\"off\"\n"
  "                if getattr(self, i):\n"
  "                    v=\"on\"\n"
  "            elif i==\"explain\":\n"
  "                v=\"on\"\n"
  "                if self.truncate:\n"
  "                    v=\"off\"\n"
  "            elif i in (\"nullvalue\", \"separator\"):\n"
  "                v=self._fmt_c_string(getattr(self, i))\n"
  "            elif i==\"mode\":\n"
  "                if not self._output_modes:\n"
  "                    self._cache_output_modes()\n"
  "                for v in self._output_modes:\n"
  "                    if self.output==getattr(self, \"output_\"+v):\n"
  "                        break\n"
  "                else:\n"
  "                    assert False, \"Bug: didn't find output mode\"\n"
  "            elif i==\"output\":\n"
  "                if self.stdout is self._original_stdout:\n"
  "                    v=\"stdout\"\n"
  "                else:\n"
  "                    v=getattr(self.stdout, \"name\", \"<unknown stdout>\")\n"
  "            elif i==\"width\":\n"
  "                v=\" \".join([\"%d\"%(i,) for i in self.widths])\n"
  "            elif i==\"encoding\":\n"
  "                v=self.encoding[0]\n"
  "                if self.encoding[1]:\n"
  "                    v+=\" (Errors \"+self.encoding[1]+\")\"\n"
  "            else:\n"
  "                assert False, \"Bug: unknown show handling\"\n"
  "            outs.append( (k,v) )\n"
  "\n"
  "        l=0\n"
  "        for k,v in outs:\n"
  "            if len(k)>l:\n"
  "                l=len(k)\n"
  "\n"
  "        for k,v in outs:\n"
  "            self.write(self.stderr, \"%*.*s: %s\\n\" % (l,l, k, v))\n"
  "\n"
  "    def command_tables(self, cmd):\n"
  "        \"\"\"tables ?PATTERN?: Lists names of tables matching LIKE pattern\n"
  "\n"
  "        This also returns views.\n"
  "        \"\"\"\n"
  "        self.push_output()\n"
  "        self.output=self.output_list\n"
  "        self.header=False\n"
  "        try:\n"
  "            if len(cmd)==0:\n"
  "                cmd=['%']\n"
  "\n"
  "            for n in cmd:\n"
  "                self.process_sql(\"SELECT name FROM sqlite_master \"\n"
  "                                 \"WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' \"\n"
  "                                 \"AND name like ?1 \"\n"
  "                                 \"UNION ALL \"\n"
  "                                 \"SELECT name FROM sqlite_temp_master \"\n"
  "                                 \"WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' \"\n"
  "                                 \"ORDER BY 1\", (n,), internal=True)\n"
  "        finally:\n"
  "            self.pop_output()\n"
  "\n"
  "    def command_timeout(self, cmd):\n"
  "        \"\"\"timeout MS: Try opening locked tables for MS milliseconds\n"
  "\n"
  "        If a database is locked by another process SQLite will keep\n"
  "        retrying.  This sets how many thousandths of a second it will\n"
  "        keep trying for.  If you supply zero or a negative number then\n"
  "        all busy handlers are disabled.\n"
  "        \"\"\"\n"
  "        if len(cmd)!=1:\n"
  "            raise self.Error(\"timeout takes a number\")\n"
  "        try:\n"
  "            t=int(cmd[0])\n"
  "        except:\n"
  "            raise self.Error(\"%s is not a number\" % (cmd[0],))\n"
  "        self.db.setbusytimeout(t)\n"
  "\n"
  "    def command_timer(self, cmd):\n"
  "        \"\"\"timer ON|OFF: Control printing of time and resource usage after each query\n"
  "\n"
  "        The values displayed are in seconds when shown as floating\n"
  "        point or an absolute count.  Only items that have changed\n"
  "        since starting the query are shown.  On non-Windows platforms\n"
  "        considerably more information can be shown.\n"
  "        \"\"\"\n"
  "        if self._boolean_command(\"timer\", cmd):\n"
  "            try:\n"
  "                self.get_resource_usage()\n"
  "            except:\n"
  "                raise self.Error(\"Timing not supported by this Python version/platform\")\n"
  "            self.timer=True\n"
  "        else:\n"
  "            self.timer=False\n"
  "\n"
  "    def command_width(self, cmd):\n"
  "        \"\"\"width NUM NUM ...: Set the column widths for \"column\" mode\n"
  "\n"
  "        In \"column\" output mode, each column is a fixed width with values truncated to\n"
  "        fit.  Specify new widths using this command.  Use a negative number\n"
  "        to right justify and zero for default column width.\n"
  "        \"\"\"\n"
  "        if len(cmd)==0:\n"
  "            raise self.Error(\"You need to specify some widths!\")\n"
  "        w=[]\n"
  "        for i in cmd:\n"
  "            try:\n"
  "                w.append(int(i))\n"
  "            except:\n"
  "                raise self.Error(\"'%s' is not a valid number\" % (i,))\n"
  "        self.widths=w\n"
  "\n"
  "    def _terminal_width(self):\n"
  "        \"\"\"Works out the terminal width which is used for word wrapping\n"
  "        some output (eg .help)\"\"\"\n"
  "        try:\n"
  "            if sys.platform==\"win32\":\n"
  "                import ctypes, struct\n"
  "                h=ctypes.windll.kernel32.GetStdHandle(-12) # -12 is stderr\n"
  "                buf=ctypes.create_string_buffer(22)\n"
  "                if ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, buf):\n"
  "                    _,_,_,_,_,left,top,right,bottom,_,_=struct.unpack(\"hhhhHhhhhhh\", buf.raw)\n"
  "                    return right-left\n"
  "                raise Exception()\n"
  "            else:\n"
  "                import struct, fcntl, termios\n"
  "                s=struct.pack('HHHH', 0,0,0,0)\n"
  "                x=fcntl.ioctl(2, termios.TIOCGWINSZ, s)\n"
  "                return struct.unpack('HHHH', x)[1]\n"
  "        except:\n"
  "            try:\n"
  "                v=int(os.getenv(\"COLUMNS\"))\n"
  "                if v<10:\n"
  "                    return 80\n"
  "                return v\n"
  "            except:\n"
  "                return 80\n"
  "\n"
  "    def push_output(self):\n"
  "        \"\"\"Saves the current output settings onto a stack.  See\n"
  "        :meth:`pop_output` for more details as to why you would use\n"
  "        this.\"\"\"\n"
  "        o={}\n"
  "        for k in \"separator\", \"header\", \"nullvalue\", \"output\", \"widths\", \"truncate\":\n"
  "            o[k]=getattr(self, k)\n"
  "        self._output_stack.append(o)\n"
  "\n"
  "    def pop_output(self):\n"
  "        \"\"\"Restores most recently pushed output.  There are many\n"
  "        output parameters such as nullvalue, mode\n"
  "        (list/tcl/html/insert etc), column widths, header etc.  If you\n"
  "        temporarily need to change some settings then\n"
  "        :meth:`push_output`, change the settings and then pop the old\n"
  "        ones back.\n"
  "\n"
  "        A simple example is implementing a command like .dump.  Push\n"
  "        the current output, change the mode to insert so we get SQL\n"
  "        inserts printed and then pop to go back to what was there\n"
  "        before.\n"
  "\n"
  "        \"\"\"\n"
  "        assert len(self._output_stack)\n"
  "        if len(self._output_stack)==1:\n"
  "            o=self._output_stack[0]\n"
  "        else:\n"
  "            o=self._output_stack.pop()\n"
  "        for k,v in o.items():\n"
  "            setattr(self,k,v)\n"
  "\n"
  "    def _append_input_description(self):\n"
  "        \"\"\"When displaying an error in :meth:`handle_exception` we\n"
  "        want to give context such as when the commands being executed\n"
  "        came from a .read command (which in turn could execute another\n"
  "        .read).\n"
  "        \"\"\"\n"
  "        if self.interactive:\n"
  "            return\n"
  "        res=[]\n"
  "        res.append(\"Line %d\" % (self.input_line_number,))\n"
  "        res.append(\": \"+getattr(self.stdin, \"name\", \"<stdin>\"))\n"
  "        self._input_descriptions.append(\" \".join(res))\n"
  "\n"
  "    def fixup_backslashes(self, s):\n"
  "        \"\"\"Implements the various backlash sequences in s such as\n"
  "        turning backslash t into a tab.\n"
  "\n"
  "        This function is needed because shlex does not do it for us.\n"
  "        \"\"\"\n"
  "        if \"\\\\\" not in s: return s\n"
  "        res=[]\n"
  "        i=0\n"
  "        while i<len(s):\n"
  "            if s[i]!=\"\\\\\":\n"
  "                res.append(s[i])\n"
  "                i+=1\n"
  "                continue\n"
  "            i+=1\n"
  "            if i>=len(s):\n"
  "                raise self.Error(\"Backslash with nothing following\")\n"
  "            c=s[i]\n"
  "            res.append({\n"
  "                \"\\\\\": \"\\\\\",\n"
  "                \"r\": \"\\r\",\n"
  "                \"n\": \"\\n\",\n"
  "                \"t\": \"\\t\"\n"
  "                }.get(c, None))\n"
  "            i+=1 # advance again\n"
  "            if res[-1] is None:\n"
  "                raise self.Error(\"Unknown backslash sequence \\\\\"+c)\n"
  "        return \"\".join(res)\n"
  "\n"
  "    if sys.version_info<(3,0):\n"
  "        def write(self, dest, text):\n"
  "            \"\"\"Writes text to dest.  dest will typically be one of self.stdout or self.stderr.\"\"\"\n"
  "            if type(text)!=unicode:\n"
  "                text=unicode(text)\n"
  "            try:\n"
  "                dest.write(text)\n"
  "            except UnicodeEncodeError:\n"
  "                ev=sys.exc_info()[1]\n"
  "                if ev.args[0]==\"ascii\" and dest.encoding and ev.args[0]!=dest.encoding and hasattr(dest, \"fileno\") and \\\n"
  "                   isinstance(dest.fileno(), int) and dest.fileno()>=0:\n"
  "                    args=[dest.encoding,]\n"
  "                    if dest.errors:\n"
  "                        args.append(dest.errors)\n"
  "                    dest.write(text.encode(*args))\n"
  "                else:\n"
  "                    raise\n"
  "\n"
  "        _raw_input=raw_input\n"
  "    else:\n"
  "        def write(self, dest, text):\n"
  "            \"Writes text to dest.  dest will typically be one of self.stdout or self.stderr.\"\n"
  "            dest.write(text)\n"
  "        _raw_input=input\n"
  "\n"
  "    def getline(self, prompt=\"\"):\n"
  "        \"\"\"Returns a single line of input (may be incomplete SQL) from self.stdin.\n"
  "\n"
  "        If EOF is reached then return None.  Do not include trailing\n"
  "        newline in return.\n"
  "        \"\"\"\n"
  "        self.stdout.flush()\n"
  "        self.stderr.flush()\n"
  "        try:\n"
  "            if self.interactive:\n"
  "                if self.stdin is sys.stdin:\n"
  "                    c=self.colour.prompt, self.colour.prompt_\n"
  "                    if self._using_readline and sys.platform!=\"win32\":\n"
  "                        c=\"\\x01\"+c[0]+\"\\x02\", \"\\x01\"+c[1]+\"\\x02\",\n"
  "                    line=self._raw_input(c[0]+prompt+c[1])+\"\\n\" # raw_input excludes newline\n"
  "                else:\n"
  "                    self.write(self.stdout, prompt)\n"
  "                    line=self.stdin.readline()  # includes newline unless last line of file doesn't have one\n"
  "            else:\n"
  "                line=self.stdin.readline()  # includes newline unless last line of file doesn't have one\n"
  "            self.input_line_number+=1\n"
  "            if sys.version_info<(3,0):\n"
  "                if type(line)!=unicode:\n"
  "                    enc=getattr(self.stdin, \"encoding\", self.encoding[0])\n"
  "                    if not enc: enc=self.encoding[0]\n"
  "                    line=line.decode(enc)\n"
  "        except EOFError:\n"
  "            return None\n"
  "        if len(line)==0: # always a \\n on the end normally so this is EOF\n"
  "            return None\n"
  "        if line[-1]==\"\\n\":\n"
  "            line=line[:-1]\n"
  "        return line\n"
  "\n"
  "    def getcompleteline(self):\n"
  "        \"\"\"Returns a complete input.\n"
  "\n"
  "        For dot commands it will be one line.  For SQL statements it\n"
  "        will be as many as is necessary to have a\n"
  "        :meth:`~apsw.complete` statement (ie semicolon terminated).\n"
  "        Returns None on end of file.\"\"\"\n"
  "        try:\n"
  "            self._completion_first=True\n"
  "            command=self.getline(self.prompt)\n"
  "            if command is None:\n"
  "                return None\n"
  "            if len(command.strip())==0:\n"
  "                return \"\"\n"
  "            if command[0]==\"?\": command=\".help \"+command[1:]\n"
  "            while command[0]!=\".\" and not apsw.complete(command):\n"
  "                self._completion_first=False\n"
  "                line=self.getline(self.moreprompt)\n"
  "                if line is None: # unexpected eof\n"
  "                    raise self.Error(\"Incomplete SQL (line %d of %s): %s\\n\" % (self.input_line_number, getattr(self.stdin, \"name\", \"<stdin>\"), command))\n"
  "                if line in (\"go\", \"/\"):\n"
  "                    break\n"
  "                command=command+\"\\n\"+line\n"
  "            return command\n"
  "        except KeyboardInterrupt:\n"
  "            self.handle_interrupt()\n"
  "            return \"\"\n"
  "\n"
  "    def handle_interrupt(self):\n"
  "        \"\"\"Deal with keyboard interrupt (typically Control-C).  It\n"
  "        will :meth:`~Connection.interrupt` the database and print\"^C\" if interactive.\"\"\"\n"
  "        self.db.interrupt()\n"
  "        if not self.bail and self.interactive:\n"
  "            self.write(self.stderr, \"^C\\n\")\n"
  "            return\n"
  "        raise\n"
  "\n"
  "    def process_complete_line(self, command):\n"
  "        \"\"\"Given some text will call the appropriate method to process\n"
  "        it (eg :meth:`process_sql` or :meth:`process_command`)\"\"\"\n"
  "        try:\n"
  "            if len(command.strip())==0:\n"
  "                return\n"
  "            if command[0]==\".\":\n"
  "                self.process_command(command)\n"
  "            else:\n"
  "                self.process_sql(command)\n"
  "        except KeyboardInterrupt:\n"
  "            self.handle_interrupt()\n"
  "\n"
  "    def push_input(self):\n"
  "        \"\"\"Saves the current input parameters to a stack.  See :meth:`pop_input`.\"\"\"\n"
  "        d={}\n"
  "        for i in \"interactive\", \"stdin\", \"input_line_number\":\n"
  "            d[i]=getattr(self, i)\n"
  "        self._input_stack.append(d)\n"
  "\n"
  "    def pop_input(self):\n"
  "        \"\"\"Restore most recently pushed input parameters (interactive,\n"
  "        self.stdin, linenumber etc).  Use this if implementing a\n"
  "        command like read.  Push the current input, read the file and\n"
  "        then pop the input to go back to before.\n"
  "        \"\"\"\n"
  "        assert(len(self._input_stack))>1\n"
  "        d=self._input_stack.pop()\n"
  "        for k,v in d.items():\n"
  "            setattr(self, k, v)\n"
  "\n"
  "    def complete(self, token, state):\n"
  "        \"\"\"Return a possible completion for readline\n"
  "\n"
  "        This function is called with state starting at zero to get the\n"
  "        first completion, then one/two/three etc until you return None.  The best\n"
  "        implementation is to generate the list when state==0, save it,\n"
  "        and provide members on each increase.\n"
  "\n"
  "        The default implementation extracts the current full input\n"
  "        from readline and then calls :meth:`complete_command` or\n"
  "        :meth:`complete_sql` as appropriate saving the results for\n"
  "        subsequent calls.\n"
  "        \"\"\"\n"
  "        if state==0:\n"
  "            import readline\n"
  "            line=readline.get_line_buffer()\n"
  "            beg=readline.get_begidx()\n"
  "            end=readline.get_endidx()\n"
  "            try:\n"
  "                if self._completion_first and line.startswith(\".\"):\n"
  "                    self.completions=self.complete_command(line, token, beg, end)\n"
  "                else:\n"
  "                    self.completions=self.complete_sql(line, token, beg, end)\n"
  "            except:\n"
  "                import traceback; traceback.print_exc()\n"
  "                raise\n"
  "\n"
  "        if state>len(self.completions):\n"
  "            return None\n"
  "        return self.completions[state]\n"
  "\n"
  "    _sqlite_keywords=\"\"\"ABORT ACTION ADD AFTER ALL ALTER ANALYZE AND AS ASC ATTACH\n"
  "    AUTOINCREMENT BEFORE BEGIN BETWEEN BY CASCADE CASE CAST CHECK\n"
  "    COLLATE COLUMN COMMIT CONFLICT CONSTRAINT CREATE CROSS\n"
  "    CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP DATABASE DEFAULT\n"
  "    DEFERRABLE DEFERRED DELETE DESC DETACH DISTINCT DROP EACH ELSE END\n"
  "    ESCAPE EXCEPT EXCLUSIVE EXISTS EXPLAIN FAIL FOR FOREIGN FROM FULL\n"
  "    GLOB GROUP HAVING IF IGNORE IMMEDIATE IN INDEX INDEXED INITIALLY\n"
  "    INNER INSERT INSTEAD INTERSECT INTO IS ISNULL JOIN KEY LEFT LIKE\n"
  "    LIMIT MATCH NATURAL NO NOT NOTNULL NULL OF OFFSET ON OR ORDER\n"
  "    OUTER PLAN PRAGMA PRIMARY QUERY RAISE RECURSIVE REFERENCES REGEXP\n"
  "    REINDEX RELEASE RENAME REPLACE RESTRICT RIGHT ROLLBACK ROW\n"
  "    SAVEPOINT SELECT SET TABLE TEMP TEMPORARY THEN TO TRANSACTION\n"
  "    TRIGGER UNION UNIQUE UPDATE USING VACUUM VALUES VIEW VIRTUAL WHEN\n"
  "    WHERE WITH WITHOUT\"\"\".split()\n"
  "\n"
  "    _sqlite_keywords.extend(getattr(apsw, \"keywords\", []))\n"
  "\n"
  "    _sqlite_reserved=_sqlite_keywords\n"
  "    _sqlite_keywords=[x+(\" \", \"(\")[x in (\"VALUES\", \"CAST\")] for x in _sqlite_keywords]\n"
  "\n"
  "    _sqlite_special_names=\"\"\"_ROWID_ OID ROWID SQLITE_MASTER\n"
  "           SQLITE_SEQUENCE\"\"\".split()\n"
  "\n"
  "    _sqlite_functions=\"\"\"abs( changes() char( coalesce( glob( ifnull( hex( instr(\n"
  "           last_insert_rowid() length( like( likelihood( likely(\n"
  "           load_extension( lower( ltrim( max( min( nullif( printf(\n"
  "           quote( random() randomblob( replace( round( rtrim( soundex(\n"
  "           sqlite_compileoption_get( sqlite_compileoption_used(\n"
  "           sqlite_source_id() sqlite_version() substr( total_changes()\n"
  "           trim( typeof( unlikely( unicode( upper( zeroblob( date(\n"
  "           time( datetime( julianday( strftime( avg( count(\n"
  "           group_concat( sum( total(\"\"\".split()\n"
  "\n"
  "    _pragmas_bool=(\"yes\", \"true\", \"on\", \"no\", \"false\", \"off\")\n"
  "    _pragmas={\"application_id\": None,\n"
  "              \"auto_vacuum=\": (\"NONE\", \"FULL\", \"INCREMENTAL\"),\n"
  "              \"automatic_index=\": _pragmas_bool,\n"
  "              \"busy_timeout=\": None,\n"
  "              \"cache_size=\": None,\n"
  "              \"case_sensitive_like=\": _pragmas_bool,\n"
  "              \"cache_spill=\": _pragmas_bool,\n"
  "              \"cell_size_check=\": _pragmas_bool,\n"
  "              \"checkpoint_fullfsync=\": _pragmas_bool,\n"
  "              \"collation_list\": None,\n"
  "              \"compile_options\": None,\n"
  "              \"data_version\": None,\n"
  "              \"database_list\": None,\n"
  "              \"defer_foreign_keys=\": _pragmas_bool,\n"
  "              \"encoding=\": None,\n"
  "              \"foreign_key_check\": None,\n"
  "              \"foreign_key_list(\": None,\n"
  "              \"foreign_keys\": _pragmas_bool,\n"
  "              \"freelist_count\": None,\n"
  "              \"fullfsync=\": _pragmas_bool,\n"
  "              \"ignore_check_constraints\": _pragmas_bool,\n"
  "              \"incremental_vacuum(\": None,\n"
  "              \"index_info(\": None,\n"
  "              \"index_list(\": None,\n"
  "              \"index_xinfo(\": None,\n"
  "              \"integrity_check\": None,\n"
  "              \"journal_mode=\": (\"DELETE\", \"TRUNCATE\", \"PERSIST\", \"MEMORY\", \"OFF\", \"WAL\"),\n"
  "              \"journal_size_limit=\": None,\n"
  "              \"legacy_file_format=\": _pragmas_bool,\n"
  "              \"locking_mode=\": (\"NORMAL\", \"EXCLUSIVE\"),\n"
  "              \"max_page_count=\": None,\n"
  "              \"mmap_size=\": None,\n"
  "              \"optimize(\": None,\n"
  "              \"page_count;\": None,\n"
  "              \"page_size=\": None,\n"
  "              \"query_only=\": _pragmas_bool,\n"
  "              \"quick_check\": None,\n"
  "              \"read_uncommitted=\": _pragmas_bool,\n"
  "              \"recursive_triggers=\": _pragmas_bool,\n"
  "              \"reverse_unordered_selects=\": _pragmas_bool,\n"
  "              \"schema_version\": None,\n"
  "              \"secure_delete=\": _pragmas_bool,\n",
  "              \"shrink_memory\": None,\n"
  "              \"soft_heap_limit=\": None,\n"
  "              \"synchronous=\": (\"OFF\", \"NORMAL\", \"FULL\"),\n"
  "              \"table_info(\": None,\n"
  "              \"temp_store=\": (\"DEFAULT\", \"FILE\", \"MEMORY\"),\n"
  "              \"threads=\": None,\n"
  "              \"user_version=\": None,\n"
  "              \"wal_autocheckpoint=\": None,\n"
  "              \"wal_checkpoint\": None,\n"
  "              \"writable_schema\": _pragmas_bool,\n"
  "              }\n"
  "\n"
  "    def _get_prev_tokens(self, line, end):\n"
  "        \"Returns the tokens prior to pos end in the line\"\n"
  "        return re.findall(r'\"?\\w+\"?', line[:end])\n"
  "\n"
  "\n"
  "    def complete_sql(self, line, token, beg, end):\n"
  "        \"\"\"Provide some completions for SQL\n"
  "\n"
  "        :param line: The current complete input line\n"
  "        :param token: The word readline is looking for matches\n"
  "        :param beg: Integer offset of token in line\n"
  "        :param end: Integer end of token in line\n"
  "        :return: A list of completions, or an empty list if none\n"
  "        \"\"\"\n"
  "        if self._completion_cache is None:\n"
  "            cur=self.db.cursor()\n"
  "            collations=[row[1] for row in cur.execute(\"pragma collation_list\")]\n"
  "            databases=[row[1] for row in cur.execute(\"pragma database_list\")]\n"
  "            other=[]\n"
  "            for db in databases:\n"
  "                if db==\"temp\":\n"
  "                    master=\"sqlite_temp_master\"\n"
  "                else:\n"
  "                    master=\"[%s].sqlite_master\" % (db,)\n"
  "                for row in cur.execute(\"select * from \"+master).fetchall():\n"
  "                    for col in (1,2):\n"
  "                        if row[col] not in other and not row[col].startswith(\"sqlite_\"):\n"
  "                            other.append(row[col])\n"
  "                    if row[0]==\"table\":\n"
  "                        try:\n"
  "                            for table in cur.execute(\"pragma [%s].table_info([%s])\" % (db, row[1],)).fetchall():\n"
  "                                if table[1] not in other:\n"
  "                                    other.append(table[1])\n"
  "                                for item in table[2].split():\n"
  "                                    if item not in other:\n"
  "                                        other.append(item)\n"
  "                        except apsw.SQLError:\n"
  "                            pass\n"
  "\n"
  "            self._completion_cache=[self._sqlite_keywords, self._sqlite_functions, self._sqlite_special_names, collations, databases, other]\n"
  "            for i in range(len(self._completion_cache)):\n"
  "                self._completion_cache[i].sort()\n"
  "\n"
  "        if \"pragma \" in line.lower():\n"
  "            t=self._get_prev_tokens(line.lower(), end)\n"
  "\n"
  "            if len(t)>2 and t[-3]==\"pragma\":\n"
  "                for p in self._pragmas:\n"
  "                    if p.replace(\"=\",\"\")==t[-2]:\n"
  "                        vals=self._pragmas[p]\n"
  "                        if not vals:\n"
  "                            return []\n"
  "                        return [x+\";\" for x in vals if x.startswith(token)]\n"
  "            if len(t)>1 and t[-2]==\"pragma\" and line[:end].replace(\" \",\"\").endswith(\"=\"):\n"
  "                for p in self._pragmas:\n"
  "                    if p.replace(\"=\",\"\")==t[-1]:\n"
  "                        vals=self._pragmas[p]\n"
  "                        if not vals:\n"
  "                            return []\n"
  "                        return vals\n"
  "            if len(t)>1 and t[-2]==\"pragma\":\n"
  "                res=[x for x in self._pragmas.keys() if x.startswith(token)]\n"
  "                res.sort()\n"
  "                return res\n"
  "\n"
  "            if len(t) and t[-1]==\"pragma\":\n"
  "                res=list(self._pragmas.keys())\n"
  "                res.sort()\n"
  "                return res\n"
  "\n"
  "        res=[]\n"
  "        ut=token.upper()\n"
  "        for corpus in self._completion_cache:\n"
  "            for word in corpus:\n"
  "                if word.upper().startswith(ut):\n"
  "                    if word.startswith(token): # exact\n"
  "                        if word not in res:\n"
  "                            res.append(word)\n"
  "                    elif word.lower().startswith(token): # lower\n"
  "                        if word.lower() not in res:\n"
  "                            res.append(word.lower())\n"
  "                    elif word.upper().startswith(token): # upper\n"
  "                        if word.upper() not in res:\n"
  "                            res.append(word.upper())\n"
  "                    else:\n"
  "                        w=token+word[len(token):]\n"
  "                        if w not in res:\n"
  "                            res.append(w)\n"
  "        return res\n"
  "\n"
  "    _builtin_commands=None\n"
  "\n"
  "    def complete_command(self, line, token, beg, end):\n"
  "        \"\"\"Provide some completions for dot commands\n"
  "\n"
  "        :param line: The current complete input line\n"
  "        :param token: The word readline is looking for matches\n"
  "        :param beg: Integer offset of token in line\n"
  "        :param end: Integer end of token in line\n"
  "        :return: A list of completions, or an empty list if none\n"
  "        \"\"\"\n"
  "        if not self._builtin_commands:\n"
  "            self._builtin_commands=[\".\"+x[len(\"command_\"):] for x in dir(self) if x.startswith(\"command_\") and x!=\"command_headers\"]\n"
  "        if beg==0:\n"
  "            return [x+\" \" for x in self._builtin_commands if x.startswith(token)]\n"
  "        return None\n"
  "\n"
  "    def get_resource_usage(self):\n"
  "        \"\"\"Return a dict of various numbers (ints or floats).  The\n"
  "        .timer command shows the difference between before and after\n"
  "        results of what this returns by calling :meth:`display_timing`\"\"\"\n"
  "        if sys.platform==\"win32\":\n"
  "            import ctypes, time, platform\n"
  "            ctypes.windll.kernel32.GetProcessTimes.argtypes=[\n"
  "                platform.architecture()[0]=='64bit' and ctypes.c_int64 or ctypes.c_int32,\n"
  "                ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]\n"
  "\n"
  "            dummy=ctypes.c_ulonglong()\n"
  "            utime=ctypes.c_ulonglong()\n"
  "            stime=ctypes.c_ulonglong()\n"
  "            rc=ctypes.windll.kernel32.GetProcessTimes(\n"
  "                ctypes.windll.kernel32.GetCurrentProcess(),\n"
  "                ctypes.byref(dummy),  # creation time\n"
  "                ctypes.byref(dummy),  # exit time\n"
  "                ctypes.byref(stime),\n"
  "                ctypes.byref(utime))\n"
  "            if rc:\n"
  "                return {'Wall clock': time.time(),\n"
  "                        'User time': float(utime.value)/10000000,\n"
  "                        'System time': float(stime.value)/10000000}\n"
  "            return {}\n"
  "        else:\n"
  "            import resource, time\n"
  "            r=resource.getrusage(resource.RUSAGE_SELF)\n"
  "            res={'Wall clock': time.time()}\n"
  "            for i,desc in ( (\"utime\", \"User time\"),\n"
  "                       (\"stime\", \"System time\"),\n"
  "                       (\"maxrss\", \"Max rss\"),\n"
  "                       (\"idrss\", \"Memory\"),\n"
  "                       (\"isrss\", \"Stack\"),\n"
  "                       (\"ixrss\", \"Shared Memory\"),\n"
  "                       (\"minflt\", \"PF (no I/O)\"),\n"
  "                       (\"majflt\", \"PF (I/O)\"),\n"
  "                       (\"inblock\", \"Blocks in\"),\n"
  "                       (\"oublock\", \"Blocks out\"),\n"
  "                       (\"nsignals\", \"Signals\"),\n"
  "                       (\"nvcsw\", \"Voluntary context switches\"),\n"
  "                       (\"nivcsw\", \"Involunary context switches\"),\n"
  "                       (\"msgrcv\", \"Messages received\"),\n"
  "                       (\"msgsnd\", \"Messages sent\"),\n"
  "                       (\"nswap\", \"Swaps\"),\n"
  "                       ):\n"
  "                f=\"ru_\"+i\n"
  "                if hasattr(r, f):\n"
  "                    res[desc]=getattr(r,f)\n"
  "            return res\n"
  "\n"
  "    def display_timing(self, b4, after):\n"
  "        \"\"\"Writes the difference between b4 and after to self.stderr.\n"
  "        The data is dictionaries returned from\n"
  "        :meth:`get_resource_usage`.\"\"\"\n"
  "        v=list(b4.keys())\n"
  "        for i in after:\n"
  "            if i not in v:\n"
  "                v.append(i)\n"
  "        v.sort()\n"
  "        for k in v:\n"
  "            if k in b4 and k in after:\n"
  "                one=b4[k]\n"
  "                two=after[k]\n"
  "                val=two-one\n"
  "                if val:\n"
  "                    if type(val)==float:\n"
  "                        self.write(self.stderr, \"+ %s: %.4f\\n\" % (k, val))\n"
  "                    else:\n"
  "                        self.write(self.stderr, \"+ %s: %d\\n\" % (k, val))\n"
  "\n"
  "\n"
  "    def _out_colour(self):\n"
  "        if getattr(self.stdout, \"isatty\", False) and self.stdout.isatty():\n"
  "            self.colour=self._colours[self.colour_scheme]\n"
  "        else:\n"
  "            self.colour=self._colours[\"off\"]\n"
  "\n"
  "    class _colourscheme:\n"
  "        def __init__(self, **kwargs):\n"
  "            for k,v in kwargs.items():\n"
  "                setattr(self, k, v)\n"
  "        def __nonzero__(self): return True\n"
  "        def __str__(self): return \"_colourscheme(\"+str(self.__dict__)+\")\"\n"
  "        def __getattr__(self, k):\n"
  "            return \"\"\n"
  "        def colour_value(self, val, formatted):\n"
  "            c=self.colour\n"
  "            if val is None:\n"
  "                return self.vnull+formatted+self.vnull_\n"
  "            if isinstance(val, Shell._basestring):\n"
  "                return self.vstring+formatted+self.vstring_\n"
  "            if isinstance(val, Shell._binary_type):\n"
  "                return self.vblob+formatted+self.vblob_\n"
  "            return self.vnumber+formatted+self.vnumber_\n"
  "\n"
  "    d=_colourscheme(**dict([(v, \"\\x1b[\"+str(n)+\"m\") for n,v in {0: \"reset\", 1: \"bold\", 4: \"underline\", 22: \"bold_\", 24: \"underline_\",\n"
  "     7: \"inverse\", 27: \"inverse_\",\n"
  "     30: \"fg_black\", 31: \"fg_red\", 32: \"fg_green\", 33: \"fg_yellow\", 34: \"fg_blue\", 35: \"fg_magenta\", 36: \"fg_cyan\", 37: \"fg_white\", 39: \"fg_\",\n"
  "     40: \"bg_black\", 41: \"bg_red\", 42: \"bg_green\", 43: \"bg_yellow\", 44: \"bg_blue\", 45: \"bg_magenta\", 46: \"bg_cyan\", 47: \"bg_white\", 49: \"bg_\"}.items()]))\n"
  "\n"
  "    _colours={\"off\": _colourscheme(colour_value=lambda x,y: y)}\n"
  "\n"
  "    _colours[\"default\"]=_colourscheme(prompt=d.bold, prompt_=d.bold_,\n"
  "                                      error=d.fg_red+d.bold, error_=d.bold_+d.fg_,\n"
  "                                      intro=d.fg_blue+d.bold, intro_=d.bold_+d.fg_,\n"
  "                                      summary=d.fg_blue+d.bold, summary_=d.bold_+d.fg_,\n"
  "                                      header=sys.platform==\"win32\" and d.inverse or d.underline,\n"
  "                                      header_=sys.platform==\"win32\" and d.inverse_ or d.underline_,\n"
  "                                      vnull=d.fg_red, vnull_=d.fg_,\n"
  "                                      vstring=d.fg_yellow, vstring_=d.fg_,\n"
  "                                      vblob=d.fg_blue, vblob_=d.fg_,\n"
  "                                      vnumber=d.fg_magenta, vnumber_=d.fg_)\n"
  "    if sys.platform==\"win32\":\n"
  "        if not _win_colour:\n"
  "            for k in _colours:\n"
  "                _colours[k]=_colours[\"off\"]\n"
  "    del d\n"
  "    del _colourscheme\n"
  "    try:\n"
  "        del n\n"
  "        del x\n"
  "        del v\n"
  "    except:\n"
  "        pass\n"
  "\n"
  "def main():\n"
  "    \"\"\"\n"
  "    Call this to run the interactive shell.  It automatically passes\n"
  "    in sys.argv[1:] and exits Python when done.\n"
  "\n"
  "    \"\"\"\n"
  "    try:\n"
  "        s=Shell()\n"
  "        _,_,cmds=s.process_args(sys.argv[1:])\n"
  "        if len(cmds)==0:\n"
  "            s.cmdloop()\n"
  "    except:\n"
  "        v=sys.exc_info()[1]\n"
  "        if getattr(v, \"_handle_exception_saw_this\", False):\n"
  "            pass\n"
  "        else:\n"
  "            import traceback; traceback.print_exc()\n"
  "        sys.exit(1)\n"
  "\n"