diff options
author | AlexSm <alex@ydb.tech> | 2024-03-05 10:40:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-05 12:40:59 +0300 |
commit | 1ac13c847b5358faba44dbb638a828e24369467b (patch) | |
tree | 07672b4dd3604ad3dee540a02c6494cb7d10dc3d /contrib/tools/python3/Lib/sqlite3 | |
parent | ffcca3e7f7958ddc6487b91d3df8c01054bd0638 (diff) | |
download | ydb-1ac13c847b5358faba44dbb638a828e24369467b.tar.gz |
Library import 16 (#2433)
Co-authored-by: robot-piglet <robot-piglet@yandex-team.com>
Co-authored-by: deshevoy <deshevoy@yandex-team.com>
Co-authored-by: robot-contrib <robot-contrib@yandex-team.com>
Co-authored-by: thegeorg <thegeorg@yandex-team.com>
Co-authored-by: robot-ya-builder <robot-ya-builder@yandex-team.com>
Co-authored-by: svidyuk <svidyuk@yandex-team.com>
Co-authored-by: shadchin <shadchin@yandex-team.com>
Co-authored-by: robot-ratatosk <robot-ratatosk@yandex-team.com>
Co-authored-by: innokentii <innokentii@yandex-team.com>
Co-authored-by: arkady-e1ppa <arkady-e1ppa@yandex-team.com>
Co-authored-by: snermolaev <snermolaev@yandex-team.com>
Co-authored-by: dimdim11 <dimdim11@yandex-team.com>
Co-authored-by: kickbutt <kickbutt@yandex-team.com>
Co-authored-by: abdullinsaid <abdullinsaid@yandex-team.com>
Co-authored-by: korsunandrei <korsunandrei@yandex-team.com>
Co-authored-by: petrk <petrk@yandex-team.com>
Co-authored-by: miroslav2 <miroslav2@yandex-team.com>
Co-authored-by: serjflint <serjflint@yandex-team.com>
Co-authored-by: akhropov <akhropov@yandex-team.com>
Co-authored-by: prettyboy <prettyboy@yandex-team.com>
Co-authored-by: ilikepugs <ilikepugs@yandex-team.com>
Co-authored-by: hiddenpath <hiddenpath@yandex-team.com>
Co-authored-by: mikhnenko <mikhnenko@yandex-team.com>
Co-authored-by: spreis <spreis@yandex-team.com>
Co-authored-by: andreyshspb <andreyshspb@yandex-team.com>
Co-authored-by: dimaandreev <dimaandreev@yandex-team.com>
Co-authored-by: rashid <rashid@yandex-team.com>
Co-authored-by: robot-ydb-importer <robot-ydb-importer@yandex-team.com>
Co-authored-by: r-vetrov <r-vetrov@yandex-team.com>
Co-authored-by: ypodlesov <ypodlesov@yandex-team.com>
Co-authored-by: zaverden <zaverden@yandex-team.com>
Co-authored-by: vpozdyayev <vpozdyayev@yandex-team.com>
Co-authored-by: robot-cozmo <robot-cozmo@yandex-team.com>
Co-authored-by: v-korovin <v-korovin@yandex-team.com>
Co-authored-by: arikon <arikon@yandex-team.com>
Co-authored-by: khoden <khoden@yandex-team.com>
Co-authored-by: psydmm <psydmm@yandex-team.com>
Co-authored-by: robot-javacom <robot-javacom@yandex-team.com>
Co-authored-by: dtorilov <dtorilov@yandex-team.com>
Co-authored-by: sennikovmv <sennikovmv@yandex-team.com>
Co-authored-by: hcpp <hcpp@ydb.tech>
Diffstat (limited to 'contrib/tools/python3/Lib/sqlite3')
-rw-r--r-- | contrib/tools/python3/Lib/sqlite3/__init__.py | 70 | ||||
-rw-r--r-- | contrib/tools/python3/Lib/sqlite3/__main__.py | 127 | ||||
-rw-r--r-- | contrib/tools/python3/Lib/sqlite3/dbapi2.py | 108 | ||||
-rw-r--r-- | contrib/tools/python3/Lib/sqlite3/dump.py | 88 |
4 files changed, 393 insertions, 0 deletions
diff --git a/contrib/tools/python3/Lib/sqlite3/__init__.py b/contrib/tools/python3/Lib/sqlite3/__init__.py new file mode 100644 index 0000000000..927267cf0b --- /dev/null +++ b/contrib/tools/python3/Lib/sqlite3/__init__.py @@ -0,0 +1,70 @@ +# pysqlite2/__init__.py: the pysqlite2 package. +# +# Copyright (C) 2005 Gerhard Häring <gh@ghaering.de> +# +# This file is part of pysqlite. +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. + +""" +The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant +interface to the SQLite library, and requires SQLite 3.7.15 or newer. + +To use the module, start by creating a database Connection object: + + import sqlite3 + cx = sqlite3.connect("test.db") # test.db will be created or opened + +The special path name ":memory:" can be provided to connect to a transient +in-memory database: + + cx = sqlite3.connect(":memory:") # connect to a database in RAM + +Once a connection has been established, create a Cursor object and call +its execute() method to perform SQL queries: + + cu = cx.cursor() + + # create a table + cu.execute("create table lang(name, first_appeared)") + + # insert values into a table + cu.execute("insert into lang values (?, ?)", ("C", 1972)) + + # execute a query and iterate over the result + for row in cu.execute("select * from lang"): + print(row) + + cx.close() + +The sqlite3 module is written by Gerhard Häring <gh@ghaering.de>. +""" + +from sqlite3.dbapi2 import * +from sqlite3.dbapi2 import (_deprecated_names, + _deprecated_version_info, + _deprecated_version) + + +def __getattr__(name): + if name in _deprecated_names: + from warnings import warn + + warn(f"{name} is deprecated and will be removed in Python 3.14", + DeprecationWarning, stacklevel=2) + return globals()[f"_deprecated_{name}"] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/contrib/tools/python3/Lib/sqlite3/__main__.py b/contrib/tools/python3/Lib/sqlite3/__main__.py new file mode 100644 index 0000000000..3b59763375 --- /dev/null +++ b/contrib/tools/python3/Lib/sqlite3/__main__.py @@ -0,0 +1,127 @@ +"""A simple SQLite CLI for the sqlite3 module. + +Apart from using 'argparse' for the command-line interface, +this module implements the REPL as a thin wrapper around +the InteractiveConsole class from the 'code' stdlib module. +""" +import sqlite3 +import sys + +from argparse import ArgumentParser +from code import InteractiveConsole +from textwrap import dedent + + +def execute(c, sql, suppress_errors=True): + """Helper that wraps execution of SQL code. + + This is used both by the REPL and by direct execution from the CLI. + + 'c' may be a cursor or a connection. + 'sql' is the SQL string to execute. + """ + + try: + for row in c.execute(sql): + print(row) + except sqlite3.Error as e: + tp = type(e).__name__ + try: + print(f"{tp} ({e.sqlite_errorname}): {e}", file=sys.stderr) + except AttributeError: + print(f"{tp}: {e}", file=sys.stderr) + if not suppress_errors: + sys.exit(1) + + +class SqliteInteractiveConsole(InteractiveConsole): + """A simple SQLite REPL.""" + + def __init__(self, connection): + super().__init__() + self._con = connection + self._cur = connection.cursor() + + def runsource(self, source, filename="<input>", symbol="single"): + """Override runsource, the core of the InteractiveConsole REPL. + + Return True if more input is needed; buffering is done automatically. + Return False is input is a complete statement ready for execution. + """ + match source: + case ".version": + print(f"{sqlite3.sqlite_version}") + case ".help": + print("Enter SQL code and press enter.") + case ".quit": + sys.exit(0) + case _: + if not sqlite3.complete_statement(source): + return True + execute(self._cur, source) + return False + + +def main(*args): + parser = ArgumentParser( + description="Python sqlite3 CLI", + prog="python -m sqlite3", + ) + parser.add_argument( + "filename", type=str, default=":memory:", nargs="?", + help=( + "SQLite database to open (defaults to ':memory:'). " + "A new database is created if the file does not previously exist." + ), + ) + parser.add_argument( + "sql", type=str, nargs="?", + help=( + "An SQL query to execute. " + "Any returned rows are printed to stdout." + ), + ) + parser.add_argument( + "-v", "--version", action="version", + version=f"SQLite version {sqlite3.sqlite_version}", + help="Print underlying SQLite library version", + ) + args = parser.parse_args(*args) + + if args.filename == ":memory:": + db_name = "a transient in-memory database" + else: + db_name = repr(args.filename) + + # Prepare REPL banner and prompts. + if sys.platform == "win32" and "idlelib.run" not in sys.modules: + eofkey = "CTRL-Z" + else: + eofkey = "CTRL-D" + banner = dedent(f""" + sqlite3 shell, running on SQLite version {sqlite3.sqlite_version} + Connected to {db_name} + + Each command will be run using execute() on the cursor. + Type ".help" for more information; type ".quit" or {eofkey} to quit. + """).strip() + sys.ps1 = "sqlite> " + sys.ps2 = " ... " + + con = sqlite3.connect(args.filename, isolation_level=None) + try: + if args.sql: + # SQL statement provided on the command-line; execute it directly. + execute(con, args.sql, suppress_errors=False) + else: + # No SQL provided; start the REPL. + console = SqliteInteractiveConsole(con) + console.interact(banner, exitmsg="") + finally: + con.close() + + sys.exit(0) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/contrib/tools/python3/Lib/sqlite3/dbapi2.py b/contrib/tools/python3/Lib/sqlite3/dbapi2.py new file mode 100644 index 0000000000..56fc0461e6 --- /dev/null +++ b/contrib/tools/python3/Lib/sqlite3/dbapi2.py @@ -0,0 +1,108 @@ +# pysqlite2/dbapi2.py: the DB-API 2.0 interface +# +# Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de> +# +# This file is part of pysqlite. +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. + +import datetime +import time +import collections.abc + +from _sqlite3 import * +from _sqlite3 import _deprecated_version + +_deprecated_names = frozenset({"version", "version_info"}) + +paramstyle = "qmark" + +apilevel = "2.0" + +Date = datetime.date + +Time = datetime.time + +Timestamp = datetime.datetime + +def DateFromTicks(ticks): + return Date(*time.localtime(ticks)[:3]) + +def TimeFromTicks(ticks): + return Time(*time.localtime(ticks)[3:6]) + +def TimestampFromTicks(ticks): + return Timestamp(*time.localtime(ticks)[:6]) + +_deprecated_version_info = tuple(map(int, _deprecated_version.split("."))) +sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) + +Binary = memoryview +collections.abc.Sequence.register(Row) + +def register_adapters_and_converters(): + from warnings import warn + + msg = ("The default {what} is deprecated as of Python 3.12; " + "see the sqlite3 documentation for suggested replacement recipes") + + def adapt_date(val): + warn(msg.format(what="date adapter"), DeprecationWarning, stacklevel=2) + return val.isoformat() + + def adapt_datetime(val): + warn(msg.format(what="datetime adapter"), DeprecationWarning, stacklevel=2) + return val.isoformat(" ") + + def convert_date(val): + warn(msg.format(what="date converter"), DeprecationWarning, stacklevel=2) + return datetime.date(*map(int, val.split(b"-"))) + + def convert_timestamp(val): + warn(msg.format(what="timestamp converter"), DeprecationWarning, stacklevel=2) + datepart, timepart = val.split(b" ") + year, month, day = map(int, datepart.split(b"-")) + timepart_full = timepart.split(b".") + hours, minutes, seconds = map(int, timepart_full[0].split(b":")) + if len(timepart_full) == 2: + microseconds = int('{:0<6.6}'.format(timepart_full[1].decode())) + else: + microseconds = 0 + + val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds) + return val + + + register_adapter(datetime.date, adapt_date) + register_adapter(datetime.datetime, adapt_datetime) + register_converter("date", convert_date) + register_converter("timestamp", convert_timestamp) + +register_adapters_and_converters() + +# Clean up namespace + +del(register_adapters_and_converters) + +def __getattr__(name): + if name in _deprecated_names: + from warnings import warn + + warn(f"{name} is deprecated and will be removed in Python 3.14", + DeprecationWarning, stacklevel=2) + return globals()[f"_deprecated_{name}"] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/contrib/tools/python3/Lib/sqlite3/dump.py b/contrib/tools/python3/Lib/sqlite3/dump.py new file mode 100644 index 0000000000..1cf8759f89 --- /dev/null +++ b/contrib/tools/python3/Lib/sqlite3/dump.py @@ -0,0 +1,88 @@ +# Mimic the sqlite3 console shell's .dump command +# Author: Paul Kippes <kippesp@gmail.com> + +# Every identifier in sql is quoted based on a comment in sqlite +# documentation "SQLite adds new keywords from time to time when it +# takes on new features. So to prevent your code from being broken by +# future enhancements, you should normally quote any identifier that +# is an English language word, even if you do not have to." + +def _iterdump(connection): + """ + Returns an iterator to the dump of the database in an SQL text format. + + Used to produce an SQL dump of the database. Useful to save an in-memory + database for later restoration. This function should not be called + directly but instead called from the Connection method, iterdump(). + """ + + writeable_schema = False + cu = connection.cursor() + yield('BEGIN TRANSACTION;') + + # sqlite_master table contains the SQL CREATE statements for the database. + q = """ + SELECT "name", "type", "sql" + FROM "sqlite_master" + WHERE "sql" NOT NULL AND + "type" == 'table' + ORDER BY "name" + """ + schema_res = cu.execute(q) + sqlite_sequence = [] + for table_name, type, sql in schema_res.fetchall(): + if table_name == 'sqlite_sequence': + rows = cu.execute('SELECT * FROM "sqlite_sequence";').fetchall() + sqlite_sequence = ['DELETE FROM "sqlite_sequence"'] + sqlite_sequence += [ + f'INSERT INTO "sqlite_sequence" VALUES(\'{row[0]}\',{row[1]})' + for row in rows + ] + continue + elif table_name == 'sqlite_stat1': + yield('ANALYZE "sqlite_master";') + elif table_name.startswith('sqlite_'): + continue + elif sql.startswith('CREATE VIRTUAL TABLE'): + if not writeable_schema: + writeable_schema = True + yield('PRAGMA writable_schema=ON;') + yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','{0}','{0}',0,'{1}');".format( + table_name.replace("'", "''"), + sql.replace("'", "''"), + )) + else: + yield('{0};'.format(sql)) + + # Build the insert statement for each row of the current table + table_name_ident = table_name.replace('"', '""') + res = cu.execute('PRAGMA table_info("{0}")'.format(table_name_ident)) + column_names = [str(table_info[1]) for table_info in res.fetchall()] + q = """SELECT 'INSERT INTO "{0}" VALUES({1})' FROM "{0}";""".format( + table_name_ident, + ",".join("""'||quote("{0}")||'""".format(col.replace('"', '""')) for col in column_names)) + query_res = cu.execute(q) + for row in query_res: + yield("{0};".format(row[0])) + + # Now when the type is 'index', 'trigger', or 'view' + q = """ + SELECT "name", "type", "sql" + FROM "sqlite_master" + WHERE "sql" NOT NULL AND + "type" IN ('index', 'trigger', 'view') + """ + schema_res = cu.execute(q) + for name, type, sql in schema_res.fetchall(): + yield('{0};'.format(sql)) + + if writeable_schema: + yield('PRAGMA writable_schema=OFF;') + + # gh-79009: Yield statements concerning the sqlite_sequence table at the + # end of the transaction. + for row in sqlite_sequence: + yield('{0};'.format(row)) + + yield('COMMIT;') |