diff -Nru fdb-2.0.0/debian/changelog fdb-2.0.1/debian/changelog --- fdb-2.0.0/debian/changelog 2019-12-31 03:53:40.000000000 +0000 +++ fdb-2.0.1/debian/changelog 2020-08-05 21:30:22.000000000 +0000 @@ -1,3 +1,17 @@ +fdb (2.0.1-2) unstable; urgency=medium + + * QA upload + * Set maintainer to Debian QA group + * Drop Python 2 again (was reintroduced in 2.0.1-1) (Closes: #936508) + + -- Moritz Muehlenhoff Wed, 05 Aug 2020 23:30:22 +0200 + +fdb (2.0.1-1) unstable; urgency=low + + * New upstream version + + -- Russell Stuart Tue, 21 Apr 2020 21:20:34 +1000 + fdb (2.0.0-1.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru fdb-2.0.0/debian/compat fdb-2.0.1/debian/compat --- fdb-2.0.0/debian/compat 2014-06-24 10:48:14.000000000 +0000 +++ fdb-2.0.1/debian/compat 2020-04-21 11:20:34.000000000 +0000 @@ -1 +1 @@ -9 +12 diff -Nru fdb-2.0.0/debian/control fdb-2.0.1/debian/control --- fdb-2.0.0/debian/control 2019-12-31 03:48:38.000000000 +0000 +++ fdb-2.0.1/debian/control 2020-08-05 21:30:22.000000000 +0000 @@ -1,15 +1,16 @@ Source: fdb Section: python -Maintainer: Russell Stuart +Maintainer: Debian QA Group Priority: optional -Build-Depends: debhelper (>= 9) +Build-Depends: debhelper (>= 12) Build-Depends-Indep: python3-all, python3-sphinx, python3-sphinx-bootstrap-theme, python3-setuptools, - libjs-sphinxdoc, + libjs-sphinxdoc, fonts-glyphicons-halflings, + libjs-bootstrap, libjs-sphinxdoc, dh-python -Standards-Version: 3.9.8 +Standards-Version: 4.5.0 Homepage: https://pypi.python.org/pypi/fdb/ Package: python3-fdb @@ -29,7 +30,10 @@ Package: python-fdb-doc Architecture: all Section: doc -Depends: ${misc:Depends}, libjs-sphinxdoc +Depends: ${misc:Depends}, ${sphinxdoc:Depends}, + fonts-glyphicons-halflings, + libjs-bootstrap, + libjs-sphinxdoc Recommends: python3-fdb Description: Python DB-API driver for Firebird documentation FDB is a Python library package that implements Python Database API diff -Nru fdb-2.0.0/debian/patches/backport-to-future-0.15.patch fdb-2.0.1/debian/patches/backport-to-future-0.15.patch --- fdb-2.0.0/debian/patches/backport-to-future-0.15.patch 2019-02-07 10:43:34.000000000 +0000 +++ fdb-2.0.1/debian/patches/backport-to-future-0.15.patch 2020-04-21 11:20:34.000000000 +0000 @@ -4,12 +4,12 @@ --- a/setup.py +++ b/setup.py -@@ -52,7 +52,7 @@ - ], - keywords='Firebird', # Optional +@@ -54,7 +54,7 @@ packages=find_packages(), # Required -- install_requires=['future>=0.16.0'], # Optional -+ install_requires=['future>=0.15.0'], # Optional + install_requires=['future>=0.16.0'], # Optional python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4', - #test_suite='nose.collector', +- #test_suite='nose.collector', ++ test_suite='nose.collector', project_urls={ + 'Documentation': 'http://fdb2.readthedocs.io/en/latest/', + 'Bug Reports': 'http://tracker.firebirdsql.org/browse/PYFB', diff -Nru fdb-2.0.0/debian/python-fdb-doc.lintian-overrides fdb-2.0.1/debian/python-fdb-doc.lintian-overrides --- fdb-2.0.0/debian/python-fdb-doc.lintian-overrides 2014-06-25 13:21:43.000000000 +0000 +++ fdb-2.0.1/debian/python-fdb-doc.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -# -# This is not a license file. It is part of documentation's source. -# -python-fdb-doc: extra-license-file usr/share/doc/python-fdb-doc/html/_sources/license.txt diff -Nru fdb-2.0.0/debian/ras-sphinxdoc.sh fdb-2.0.1/debian/ras-sphinxdoc.sh --- fdb-2.0.0/debian/ras-sphinxdoc.sh 2014-09-28 00:54:30.000000000 +0000 +++ fdb-2.0.1/debian/ras-sphinxdoc.sh 2020-04-21 11:20:34.000000000 +0000 @@ -8,10 +8,25 @@ find "debian/${1}" -name "*.js" | while read pkg_js_file do - dpkg --listfiles libjs-sphinxdoc | + dpkg --listfiles libjs-bootstrap libjs-sphinxdoc | while read sphinx_js do [ ."${pkg_js_file##*/}" = ."${sphinx_js##*/}" ] || continue - ln --symbolic --force "${sphinx_js}" "${pkg_js_file}" + ln --relative --symbolic --force "${sphinx_js}" "${pkg_js_file}" done done + +# +# Ditto for fonts in fonts-glyphicons-halflings. +# +find "debian/${1}" -name "glyphicons-halflings-regular.*" | + while read pkg_font_file + do + dpkg --listfiles fonts-glyphicons-halflings | + while read sphinx_font + do + [ ."${pkg_font_file##*/}" = ."${sphinx_font##*/}" ] || continue + ln --relative --symbolic --force "${sphinx_font}" "${pkg_font_file}" + done + done + diff -Nru fdb-2.0.0/debian/rules fdb-2.0.1/debian/rules --- fdb-2.0.0/debian/rules 2019-12-31 03:53:20.000000000 +0000 +++ fdb-2.0.1/debian/rules 2020-08-05 21:30:22.000000000 +0000 @@ -24,8 +24,8 @@ # Test doesn't work without root. override_dh_installdocs: - dh_installdocs --no-package=$(DOC_PACKAGE) README.rst - dh_installdocs --package=$(DOC_PACKAGE) html + dh_installdocs README.rst + dh_installdocs --package=$(DOC_PACKAGE) --doc-main-package=$(DOC_PACKAGE) html dh_sphinxdoc --package=$(DOC_PACKAGE) $(DOC_DIR) debian/ras-sphinxdoc.sh $(DOC_PACKAGE)/$(DOC_DIR) diff -Nru fdb-2.0.0/debian/watch fdb-2.0.1/debian/watch --- fdb-2.0.0/debian/watch 2015-08-13 11:47:03.000000000 +0000 +++ fdb-2.0.1/debian/watch 2020-04-21 11:20:34.000000000 +0000 @@ -1,4 +1,4 @@ version=3 opts=dversionmangle=s/\+dfsg\d*$//,repacksuffix=+dfsg1 \ - http://pypi.debian.net/fdb/fdb-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) + https://pypi.debian.net/fdb/fdb-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) diff -Nru fdb-2.0.0/fdb/fbcore.py fdb-2.0.1/fdb/fbcore.py --- fdb-2.0.0/fdb/fbcore.py 2018-04-27 11:40:21.000000000 +0000 +++ fdb-2.0.1/fdb/fbcore.py 2019-07-13 09:49:16.000000000 +0000 @@ -30,7 +30,10 @@ import decimal import weakref import threading -from builtins import dict +try: + from builtins import dict +except ImportError: + from __builtin__ import dict from . import ibase from . import schema @@ -67,7 +70,9 @@ isc_dpb_sweep_interval, isc_dpb_sys_user_name, isc_dpb_sys_user_name_enc, isc_dpb_trace, isc_dpb_user_name, isc_dpb_verify, isc_dpb_version1, - isc_dpb_working_directory, isc_dpb_no_db_triggers, isc_dpb_nolinger, + isc_dpb_working_directory, isc_dpb_no_db_triggers, isc_dpb_trusted_auth, + isc_dpb_trusted_role, isc_dpb_utf8_filename, + isc_dpb_auth_plugin_list, isc_dpb_auth_plugin_name, isc_dpb_specific_auth_data, isc_dpb_nolinger, isc_info_active_tran_count, isc_info_end, isc_info_truncated, isc_info_sql_stmt_type, isc_info_sql_get_plan, isc_info_sql_records, isc_info_req_select_count, isc_info_req_insert_count, @@ -151,7 +156,7 @@ PYTHON_MAJOR_VER = sys.version_info[0] #: Current driver version -__version__ = '2.0.0' +__version__ = '2.0.1' apilevel = '2.0' threadsafety = 1 @@ -169,8 +174,9 @@ def add_hook(hook_type, func): """Instals hook function for specified hook_type. - :param hook_type: One from HOOK_* constants - :param func: Hook routine to be installed + Args: + hook_type (int): One from `HOOK_*` constants + func (callable): Hook routine to be installed .. important:: @@ -184,8 +190,9 @@ """Uninstalls previously installed hook function for specified hook_type. - :param hook_type: One from HOOK_* constants - :param func: Hook routine to be uninstalled + Args: + hook_type (int): One from `HOOK_*` constants + func (callable): Hook routine to be uninstalled If hook routine wasn't previously installed, it does nothing. """ @@ -197,8 +204,11 @@ def get_hooks(hook_type): """Returns list of installed hook routines for specified hook_type. - :param hook_type: One from HOOK_* constants - :returns: List of installed hook routines. + Args: + hook_type (int): One from `HOOK_*` constants + + Returns: + List of installed hook routines. """ return hooks.get(hook_type, list()) @@ -206,15 +216,16 @@ """Initializes bindings to Firebird Client Library unless they are already initialized. Called automatically by :func:`fdb.connect` and :func:`fdb.create_database`. - :param string fb_library_name: (optional) Path to Firebird Client Library. - When it's not specified, FDB does its best to locate appropriate client library. + Args: + fb_library_name (str): (optional) Path to Firebird Client Library. + When it's not specified, FDB does its best to locate appropriate client library. - :returns: :class:`fdb.ibase.fbclient_API` instance. + Returns: + :class:`~fdb.ibase.fbclient_API` instance. Hooks: - - Event HOOK_API_LOADED: Executed after api is initialized. Hook routine must - have signature: hook_func(api). Any value returned by hook is ignored. + Event HOOK_API_LOADED: Executed after api is initialized. Hook routine must + have signature: hook_func(api). Any value returned by hook is ignored. """ if not hasattr(sys.modules[__name__], 'api'): setattr(sys.modules[__name__], 'api', ibase.fbclient_API(fb_library_name)) @@ -239,10 +250,6 @@ class DatabaseError(Error): "Exception raised for errors that are related to the database." pass - #def __init__(self,msg, sqlcode=0,error_code=0): - #self.sqlcode = sqlcode - #self.error_code = error_code - #self.msg = msg class DataError(DatabaseError): """Exception raised for errors that are due to problems with @@ -611,14 +618,16 @@ def add_parameter_code(self, code): """Add parameter code to parameter buffer. - :param code: Firebird code for the parameter + Args: + code (int): Firebird code for the parameter """ self.items.append(struct.pack('c', int2byte(code))) def add_string_parameter(self, code, value): """Add string to parameter buffer. - :param code: Firebird code for the parameter - :param string value: Parameter value + Args: + code (int): Firebird code for the parameter + value (str): Parameter value """ if PYTHON_MAJOR_VER == 3 or isinstance(value, UnicodeType): value = value.encode(charset_map.get(self.charset, self.charset)) @@ -630,8 +639,9 @@ def add_byte_parameter(self, code, value): """Add byte value to parameter buffer. - :param code: Firebird code for the parameter - :param value: Parameter value (0-255) + Args: + code (int): Firebird code for the parameter + value (int): Parameter value (0-255) """ if not isinstance(value, (int, mylong)) or value < 0 or value > 255: raise ProgrammingError("The value must be an int or long value between 0 and 255.") @@ -639,8 +649,9 @@ def add_integer_parameter(self, code, value): """Add integer value to parameter buffer. - :param code: Firebird code for the parameter - :param int value: Parameter value + Args: + code (int): Firebird code for the parameter + value (int): Parameter value """ if not isinstance(value, (int, mylong)): raise ProgrammingError("The value for an integer DPB code must be an int or long.") @@ -648,19 +659,22 @@ def add_byte(self, byte): """Add byte value to buffer. - :param byte: Value to be added. + Args: + byte (int): Value to be added. """ self.items.append(struct.pack('b', byte)) def add_word(self, word): """Add two byte value to buffer. - :param word: Value to be added. + Args: + word (int): Value to be added. """ self.items.append(struct.pack('= 256: @@ -672,7 +686,8 @@ def get_buffer(self): """Get parameter buffer content. - :returns: Byte string with all inserted parameters. + Returns: + bytes: Byte string with all inserted parameters. """ return b('').join(self.items) def clear(self): @@ -689,71 +704,70 @@ force_write=None, no_reserve=None, db_key_scope=None, isolation_level=ISOLATION_LEVEL_READ_COMMITED, connection_class=None, fb_library_name=None, - no_gc=None, no_db_triggers=None, no_linger=None): + no_gc=None, no_db_triggers=None, no_linger=None, utf8params=False): """Establish a connection to database. - :param dsn: Connection string in format [host[/port]]:database - :param string user: User name. If not specified, fdb attempts to use ISC_USER envar. - :param string password: User password. If not specified, fdb attempts to use ISC_PASSWORD envar. - :param string host: Server host machine specification. - :param integer port: Port used by Firebird server. - :param string database: Database specification (file spec. or alias) - :param sql_dialect: SQL Dialect for connection. - :type sql_dialect): 1, 2 or 3 - :param string role: User role. - :param string charset: Character set for connection. - :param integer buffers: Page case size override for connection. - :param integer force_writes: Forced writes override for connection. - :param integer no_reserve: Page space reservation override for connection. - :param integer db_key_scope: DBKEY scope override for connection. - :param isolation_level: Default transaction isolation level for connection **(not used)**. - :type isolation_level: 0, 1, 2 or 3 - :param connection_class: Custom connection class - :type connection_class: subclass of :class:`Connection` - :param string fb_library_name: Full path to Firebird client library. See :func:`~fdb.load_api` for details. - :param integer no_gc: No Garbage Collection flag. - :param integer no_db_triggers: No database triggers flag (FB 2.1). - :param integer no_linger: No linger flag (FB3). - - :returns: Connection to database. - :rtype: :class:`Connection` instance. - - :raises `~fdb.ProgrammingError`: For bad parameter values. - :raises `~fdb.DatabaseError`: When connection cannot be established. + Keyword Args: + dsn: Connection string in format [host[/port]]:database + user (str): User name. If not specified, fdb attempts to use ISC_USER envar. + password (str): User password. If not specified, fdb attempts to use ISC_PASSWORD envar. + host (str): Server host machine specification. + port (int): Port used by Firebird server. + database (str): Database specification (file spec. or alias) + sql_dialect (int): SQL Dialect for connection (1, 2 or 3). + role (str): User role. + charset (str): Character set for connection. + buffers (int): Page case size override for connection. + force_writes (int): Forced writes override for connection. + no_reserve (int): Page space reservation override for connection. + db_key_scope (int): DBKEY scope override for connection. + isolation_level (int): Default transaction isolation level for connection **(not used)** (0, 1, 2 or 3). + connection_class (subclass of :class:`Connection`): Custom connection class + fb_library_name (str): Full path to Firebird client library. See :func:`~fdb.load_api` for details. + no_gc (int): No Garbage Collection flag. + no_db_triggers (int): No database triggers flag (FB 2.1). + no_linger (int): No linger flag (FB3). + utf8params (bool): Notify server that database specification and other string parameters are in UTF-8. + + Returns: + :class:`Connection`: attached database. + + Raises: + fdb.ProgrammingError: For bad parameter values. + fdb.DatabaseError: When connection cannot be established. .. important:: You may specify the database using either `dns` or `database` (with optional `host`), but not both. - **Examples:** - - .. code-block:: python - - con = fdb.connect(dsn='host:/path/database.fdb', user='sysdba', - password='pass', charset='UTF8') - con = fdb.connect(host='myhost', database='/path/database.fdb', - user='sysdba', password='pass', charset='UTF8') - - **Hooks:** - - Event `HOOK_DATABASE_ATTACH_REQUEST`: Executed after all parameters - are preprocessed and before :class:`Connection` is created. Hook - must have signature: hook_func(dsn, dpb) where `dpb` is - :class:`ParameterBuffer` instance. + Examples: + .. code-block:: python - Hook may return :class:`Connection` (or subclass) instance or None. - First instance returned by any hook will become the return value - of this function and other hooks are not called. + con = fdb.connect(dsn='host:/path/database.fdb', user='sysdba', + password='pass', charset='UTF8') + con = fdb.connect(host='myhost', database='/path/database.fdb', + user='sysdba', password='pass', charset='UTF8') - Event `HOOK_DATABASE_ATTACHED`: Executed before :class:`Connection` - (or subclass) instance is returned. Hook must have signature: - hook_func(connection). Any value returned by hook is ignored. + Hooks: + Event `HOOK_DATABASE_ATTACH_REQUEST`: Executed after all parameters + are preprocessed and before :class:`Connection` is created. Hook + must have signature: hook_func(dsn, dpb) where `dpb` is + :class:`ParameterBuffer` instance. + + Hook may return :class:`Connection` (or subclass) instance or None. + First instance returned by any hook will become the return value + of this function and other hooks are not called. + + Event `HOOK_DATABASE_ATTACHED`: Executed before :class:`Connection` + (or subclass) instance is returned. Hook must have signature: + hook_func(connection). Any value returned by hook is ignored. """ def build_dpb(user, password, sql_dialect, role, charset, buffers, force_write, no_reserve, db_key_scope, no_gc, no_db_triggers, no_linger): - dpb = ParameterBuffer(charset) + param_encoding = 'utf8' if utf8params else charset + dpb = ParameterBuffer(param_encoding) dpb.add_parameter_code(isc_dpb_version1) if user: dpb.add_string_parameter(isc_dpb_user_name, user) @@ -775,6 +789,8 @@ dpb.add_byte_parameter(isc_dpb_dbkey_scope, db_key_scope) if no_gc: dpb.add_byte_parameter(isc_dpb_no_garbage_collect, no_gc) + if utf8params: + dpb.add_byte_parameter(isc_dpb_utf8_filename, 1) if no_db_triggers: dpb.add_byte_parameter(isc_dpb_no_db_triggers, no_db_triggers) if no_linger: @@ -818,7 +834,10 @@ else: dsn = database - dsn = b(dsn, _FS_ENCODING) + if utf8params: + dsn = b(dsn, 'utf8') + else: + dsn = b(dsn, _FS_ENCODING) if charset: charset = charset.upper() # @@ -863,41 +882,39 @@ Creates a new database. Parameters could be specified either by supplied "CREATE DATABASE" statement, or set of database parameters. - :param sql: "CREATE DATABASE" statement. - :param sql_dialect: SQL Dialect for newly created database. - :type sql_dialect: 1 or 3 - :param dsn: Connection string in format [host[/port]]:database - :param string user: User name. If not specified, fdb attempts to use ISC_USER envar. - :param string password: User password. If not specified, fdb attempts to use ISC_PASSWORD envar. - :param string host: Server host machine specification. - :param integer port: Port used by Firebird server. - :param string database: Database specification (file spec. or alias) - :param integer page_size: Database page size. - :param integer length: Database size in pages. - :param string charset: Character set for connection. - :param string files: Specification of secondary database files. - :param connection_class: Custom connection class - :type connection_class: subclass of :class:`Connection` - :param string fb_library_name: Full path to Firebird client library. See :func:`~fdb.load_api` for details. - - :returns: Connection to the newly created database. - :rtype: :class:`Connection` instance. - - :raises `~fdb.ProgrammingError`: For bad parameter values. - :raises `~fdb.DatabaseError`: When database creation fails. - - **Example:** - - .. code-block:: python - - con = fdb.create_database("create database '/temp/db.fdb' user 'sysdba' password 'pass'") - con = fdb.create_database(dsn='/temp/db.fdb',user='sysdba',password='pass',page_size=8192) - - **Hooks:** - - Event` HOOK_DATABASE_ATTACHED`: Executed before :class:`Connection` - (or subclass) instance is returned. Hook must have signature: - hook_func(connection). Any value returned by hook is ignored. + Keyword Args: + sql (str): "CREATE DATABASE" statement. + sql_dialect (int): SQL Dialect for newly created database (1 or 3). + dsn (str): Connection string in format [host[/port]]:database + user (str): User name. If not specified, fdb attempts to use ISC_USER envar. + password (str): User password. If not specified, fdb attempts to use ISC_PASSWORD envar. + host (str): Server host machine specification. + port (int): Port used by Firebird server. + database (str): Database specification (file spec. or alias) + page_size (int): Database page size. + length (int): Database size in pages. + charset (str): Character set for connection. + files (str): Specification of secondary database files. + connection_class (subclass of :class:`Connection`): Custom connection class + fb_library_name (str): Full path to Firebird client library. See :func:`~fdb.load_api` for details. + + Returns: + :class:`Connection`: the newly created database. + + Raises: + fdb.ProgrammingError: For bad parameter values. + fdb.DatabaseError: When database creation fails. + + Example: + .. code-block:: python + + con = fdb.create_database("create database '/temp/db.fdb' user 'sysdba' password 'pass'") + con = fdb.create_database(dsn='/temp/db.fdb',user='sysdba',password='pass',page_size=8192) + + Hooks: + Event` HOOK_DATABASE_ATTACHED`: Executed before :class:`Connection` + (or subclass) instance is returned. Hook must have signature: + hook_func(connection). Any value returned by hook is ignored. """ load_api(fb_library_name) if connection_class is None: @@ -1000,19 +1017,23 @@ Performs `rollback` if exception is thrown inside code block, otherwise performs `commit` at the end of block. - .. note: :class:`~fdb.Transaction` acts as context manager and supports `with` statement directly. + Note: + :class:`~fdb.Transaction` acts as context manager and supports `with` statement directly. - Example:: + Examples: + .. code-block:: python - with TransactionContext(my_transaction): - cursor.execute('insert into tableA (x,y) values (?,?)',(x,y)) - cursor.execute('insert into tableB (x,y) values (?,?)',(x,y)) + with TransactionContext(my_transaction): + cursor.execute('insert into tableA (x,y) values (?,?)',(x,y)) + cursor.execute('insert into tableB (x,y) values (?,?)',(x,y)) """ #: Transaction-like object this instance manages. transaction = None def __init__(self, transaction): - ":param transaction: Any object that supports `begin()`, `commit()` and `rollback()`." + """ + Args: + transaction: Any object that supports `begin()`, `commit()` and `rollback()`.""" self.transaction = transaction def __enter__(self): self.transaction.begin() @@ -1050,10 +1071,14 @@ def __init__(self, db_handle, dpb=None, sql_dialect=3, charset=None, isolation_level=ISOLATION_LEVEL_READ_COMMITED): """ - :param db_handle: Database handle provided by factory function. - :param dpb: Database Parameter Block associated with database handle. - :param integer sql_dialect: SQL Dialect associated with database handle. - :param string charset: Character set associated with database handle. + Args: + db_handle: Database handle provided by factory function. + + Keyword Args: + dpb: Database Parameter Block associated with database handle. + sql_dialect (int): SQL Dialect associated with database handle. + charset (str): Character set associated with database handle. + isolation_level (bytes): Default TPB """ if charset: self.__charset = charset.upper() @@ -1343,8 +1368,9 @@ Unlike plain file deletion, this method behaves responsibly, in that it removes shadow files and other ancillary files for this database. - :raises `~fdb.ProgrammingError`: When connection is a member of a :class:`ConnectionGroup`. - :raises `~fdb.DatabaseError`: When error is returned from server. + Raises: + fdb.ProgrammingError: When connection is a member of a :class:`ConnectionGroup`. + fdb.DatabaseError: When error is returned from server. """ self.__ensure_group_membership(False, "Cannot drop database via" " connection that is part of a ConnectionGroup.") @@ -1361,7 +1387,8 @@ Automatically starts transaction if it's not already started. - :param string sql: SQL statement to execute. + Args: + sql (str): SQL statement to execute. .. important:: @@ -1371,10 +1398,9 @@ create a cursor using the connection’s cursor method, then execute the statement using one of the cursor’s execute methods. - :param string sql: SQL statement to execute. - - :raises `~fdb.ProgrammingError`: When connection is closed. - :raises `~fdb.DatabaseError`: When error is returned from server. + Raises: + fdb.ProgrammingError: When connection is closed. + fdb.DatabaseError: When error is returned from server. """ self.__check_attached() self.main_transaction.execute_immediate(sql) @@ -1395,21 +1421,27 @@ would need to handle a multitude of special cases in order to cover all possible isc_info_* items. - :param integer info_code: One of the `isc_info_*` constants. - :param string result_type: Must be either ‘b’ if you expect a binary string result, - or ‘i’ if you expect an integer result. - :param integer page_number: Page number for `fb_info_page_contents` info code. - - :raises `~fdb.DatabaseError`: When error is returned from server. - :raises `~fdb.OperationalError`: When returned information is bigger than SHRT_MAX. - :raises `~fdb.InternalError`: On unexpected processing condition. - :raises `ValueError`: On illegal `result_type` value. + Args: + info_code (int): One of the `isc_info_*` constants. + result_type (str): Must be either ‘b’ if you expect a binary string result, + or ‘i’ if you expect an integer result. + + Keyword Args: + page_number (int): Page number for `fb_info_page_contents` info code. + + Raises: + fdb.DatabaseError: When error is returned from server. + fdb.OperationalError: When returned information is bigger than SHRT_MAX. + fdb.InternalError: On unexpected processing condition. + ValueError: On illegal `result_type` value. - .. seealso:: Extracting data with the database_info function is rather + See also: + Extracting data with the database_info function is rather clumsy. See :meth:`db_info` for higher-level means of accessing the same information. - .. note:: Some of the information available through this method would be + Note: + Some of the information available through this method would be more easily retrieved with the Services API (see submodule :mod:`fdb.services`). """ @@ -1472,11 +1504,15 @@ that parses the output of `database_info` into Python-friendly objects instead of returning raw binary buffers in the case of complex result types. - :param request: Single `fdb.isc_info_*` info request code or a sequence - of such codes. - :returns: Mapping of (info request code -> result). - :raises `ValueError`: When requested code is not recognized. - :raises `~fdb.OperationalError`: On unexpected processing condition. + Args: + request: Single `fdb.isc_info_*` info request code or a sequence of such codes. + + Returns: + dist: Mapping of (info request code -> result). + + Raises: + ValueError: When requested code is not recognized. + fdb.OperationalError: On unexpected processing condition. """ def _extract_database_info_counts(buf): # Extract a raw binary sequence @@ -1654,13 +1690,17 @@ """Returns information about active transaction. Thin wrapper around Firebird API `isc_transaction_info` call. Operates on :attr:`main_transaction`. - See :meth:`Transaction.transaction_info` for details. + + See Also: + :meth:`Transaction.transaction_info` for details. """ return self._main_transaction.transaction_info(info_code, result_type) def trans_info(self, request): """Pythonic wrapper around :meth:`transaction_info()` call. Operates on :attr:`main_transaction`. - See :meth:`Transaction.trans_info` for details. + + See Also: + :meth:`Transaction.trans_info` for details. """ return self._main_transaction.trans_info(request) def trans(self, default_tpb=None): @@ -1668,11 +1708,12 @@ of this connection. Cursors can be created within that Transaction via its :meth:`~Transaction.cursor()` method. - :param default_tpb: (optional) Transaction Parameter Block for newly created - Transaction. If not specified, :attr:`default_tpb` is used. - :type default_tpb: :class:`TPB` instance, list/tuple of `isc_tpb_*` constants - or `bytestring` - :raises `~fdb.ProgrammingError`: If Connection is :attr:`closed`. + Keyword Args: + default_tpb (:class:`TPB` instance, list/tuple of `isc_tpb_*` constants or `bytestring`): Transaction Parameter Block + for newly created Transaction. If not specified, :attr:`default_tpb` is used. + + Raises: + fdb.ProgrammingError: If Connection is :attr:`closed`. """ self.__check_attached() if default_tpb: @@ -1692,17 +1733,17 @@ Also closes all :class:`EventConduit`, :class:`Cursor` and :class:`Transaction` instances associated with this connection. - :raises `~fdb.ProgrammingError`: When connection is a member of a :class:`ConnectionGroup`. + Raises: + fdb.ProgrammingError: When connection is a member of a :class:`ConnectionGroup`. - **Hooks:** - - Event HOOK_DATABASE_DETACH_REQUEST: Executed before connection - is closed. Hook must have signature: hook_func(connection). - If any hook function returns True, connection is not closed. - - Event HOOK_DATABASE_CLOSED: Executed after connection - is closed. Hook must have signature: hook_func(connection). - Any value returned by hook is ignored. + Hooks: + Event `HOOK_DATABASE_DETACH_REQUEST`: Executed before connection + is closed. Hook must have signature: hook_func(connection). + If any hook function returns True, connection is not closed. + + Event `HOOK_DATABASE_CLOSED`: Executed after connection + is closed. Hook must have signature: hook_func(connection). + Any value returned by hook is ignored. """ self.__ensure_group_membership(False, "Cannot close a connection that" " is a member of a ConnectionGroup.") @@ -1719,10 +1760,9 @@ Operates on :attr:`main_transaction`. See :meth:`Transaction.begin` for details. - :param tpb: (Optional) Transaction Parameter Buffer for newly started - transaction. If not specified, :attr:`default_tpb` is used. - :type tpb: :class:`TPB` instance, list/tuple of `isc_tpb_*` constants - or `bytestring` + Keyword Args: + tpb (:class:`TPB` instance, list/tuple of `isc_tpb_*` constants or `bytestring`): Transaction Parameter Buffer + for newly started transaction. If not specified, :attr:`default_tpb` is used. """ self.__check_attached() self._main_transaction.begin(tpb) @@ -1731,16 +1771,18 @@ Operates on :attr:`main_transaction`. See :meth:`Transaction.savepoint` for details. - :param string name: Name for savepoint. - :raises `~fdb.ProgrammingError`: If Connection is :attr:`closed`. + Args: + name (str): Name for savepoint. - **Example:** + Raises: + fdb.ProgrammingError: If Connection is :attr:`closed`. - .. code-block:: python + Example: + .. code-block:: python - con.savepoint('BEGINNING_OF_SOME_SUBTASK') - ... - con.rollback(savepoint='BEGINNING_OF_SOME_SUBTASK') + con.savepoint('BEGINNING_OF_SOME_SUBTASK') + ... + con.rollback(savepoint='BEGINNING_OF_SOME_SUBTASK') """ self.__check_attached() return self._main_transaction.savepoint(name) @@ -1749,10 +1791,12 @@ Operates on :attr:`main_transaction`. See :meth:`Transaction.commit` for details. - :param boolean retaining: (Optional) Indicates whether the transactional - context of the transaction being resolved - should be recycled. - :raises `~fdb.ProgrammingError`: If Connection is :attr:`closed`. + Keyword Args: + retaining (bool): Indicates whether the transactional context + of the transaction being resolved should be recycled. + + Raises: + fdb.ProgrammingError: If Connection is :attr:`closed`. """ self.__check_attached() self._main_transaction.commit(retaining) @@ -1761,13 +1805,14 @@ Operates on :attr:`main_transaction`. See :meth:`Transaction.rollback` for details. - :param boolean retaining: (Optional) Indicates whether the transactional - context of the transaction being resolved - should be recycled. - :param string savepoint: (Optional) Causes the transaction to roll back - only as far as the designated savepoint, rather - than rolling back entirely. - :raises `~fdb.ProgrammingError`: If Connection is :attr:`closed`. + Keyword Args: + retaining (bool): Indicates whether the transactional context of the transaction being resolved + should be recycled. + savepoint (str): Causes the transaction to roll back only as far as the designated savepoint, rather + than rolling back entirely. + + Raises: + fdb.ProgrammingError: If Connection is :attr:`closed`. """ self.__check_attached() self._main_transaction.rollback(retaining, savepoint) @@ -1776,7 +1821,8 @@ associated with :attr:`main_transaction`. See :meth:`Transaction.cursor` for details. - :raises `~fdb.ProgrammingError`: If Connection is :attr:`closed`. + Raises: + fdb.ProgrammingError: If Connection is :attr:`closed`. """ self.__check_attached() return self.main_transaction.cursor() @@ -1784,8 +1830,11 @@ """Creates a conduit through which database event notifications will flow into the Python program. - :param event_names: A sequence of string event names. - :returns: An :class:`EventConduit` instance. + Args: + event_names (list of str): A sequence of string event names. + + Returns: + :class:`EventConduit`: """ conduit = EventConduit(self._db_handle, event_names) self.__conduits.append(conduit) @@ -1804,7 +1853,8 @@ def get_page_contents(self, page_number): """Return content of specified database page as binary string. - :param int page_number: Page sequence number. + Args: + page_number (int): Page sequence number. """ buf = self.database_info(fb_info_page_contents, 'b', page_number) str_len = bytes_to_uint(buf[1:3]) @@ -1818,7 +1868,8 @@ def get_table_access_stats(self): """Return current stats for access to tables. - :returns: List of :class:`fbcore._TableAccessStats` instances.""" + Returns: + list: of :class:`~fbcore._TableAccessStats` instances.""" tables = {} info_codes = [isc_info_read_seq_count, isc_info_read_idx_count, isc_info_insert_count, isc_info_update_count, @@ -1832,96 +1883,96 @@ return list(tables.values()) - #: (Read Only) (int) Internal ID (server-side) for connection. + #: int: (R/O) Internal ID (server-side) for connection. attachment_id = property(__get_attachment_id) - #: (Read Only) (int) SQL dialect for this connection. + #: int: (R/O) SQL dialect for this connection. sql_dialect = property(__get_sql_dialect) - #: (Read Only) (int) SQL dialect of attached database. + #: int: (R/O) SQL dialect of attached database. database_sql_dialect = property(__get_database_sql_dialect) - #: (Read Only) (string) Database name (filename or alias). + #: str: (R/O) Database name (filename or alias). database_name = property(__get_database_name) - #: (Read Only) (string) Database site name. + #: str: (R/O) Database site name. site_name = property(__get_site_name) - #: (Read Only) :class:`ConnectionGroup` this Connection belongs to, or None. + #: (R/O) :class:`ConnectionGroup` this Connection belongs to, or None. group = property(__get_group) - #: (Read Only) (string) Connection Character set name. + #: str: (R/O) Connection Character set name. charset = property(__get_charset, __set_charset) - #: (Read Only) (tuple) :class:`Transaction` instances associated with this connection. + #: tuple of :class:`Transaction`: Instances associated with this connection. transactions = property(__get_transactions) - #: (Read Only) Main :class:`Transaction` instance for this connection + #: :class:`Transaction`: Main transaction for this connection. #: Connection methods :meth:`begin`, :meth:`savepoint`, :meth:`commit` and #: :meth:`rollback` are delegated to this transaction object. main_transaction = property(__get_main_transaction) - #: (Read Only) Special "query" :class:`Transaction` instance for this connection. + #: :class:`Transaction`: Special "query" transaction for this connection. #: This is ReadOnly ReadCommitted transaction that could be active indefinitely #: without blocking garbage collection. It's used internally to query metadata, #: but it's generally useful. query_transaction = property(__get_query_transaction) - #: (Read/Write) Deafult Transaction Parameter Block used for all newly started transactions. + #: bytes: (R/W) Deafult Transaction Parameter Block used for all newly started transactions. default_tpb = property(__get_default_tpb, __set_default_tpb) - #: (Read Only) (bool) True if connection is closed. + #: bool: (R/O) True if connection is closed. closed = property(__get_closed) - #: (Read Only) (string) Version string returned by server for this connection. + #: str: (R/O) Version string returned by server for this connection. #: This version string contains InterBase-friendly engine version number, i.e. #: version that takes into account inherited IB version number. #: For example it's 'LI-V6.3.2.26540 Firebird 2.5' for Firebird 2.5.2 server_version = property(__get_server_version) - #: (Read Only) (string) Version string returned by server for this connection. + #: str: (R/O) Version string returned by server for this connection. #: This version string contains Firebird engine version number, i.e. #: version that DOES NOT takes into account inherited IB version number. #: For example it's 'LI-V2.5.2.26540 Firebird 2.5' for Firebird 2.5.2 firebird_version = property(__get_firebird_version) - #: (Read Only) (string) Firebird version number string of connected server. + #: str: (R/O) Firebird version number string of connected server. #: Uses Firebird version numbers in form: major.minor.subrelease.build version = property(__get_version) - #: (Read Only) (float) Firebird version number of connected server. Only major.minor version. + #: float: (R/O) Firebird version number of connected server. Only major.minor version. engine_version = property(__get_engine_version) - #: (Read Only) (int) Server implementation ID + #: int: (R/O) Server implementation ID implementation_id = property(__get_implementation_id) - #: (Read Only) (int) Server provider ID + #: int: (R/O) Server provider ID provider_id = property(__get_provider_id) - #: (Read Only) (int) Database class ID + #: int: (R/O Database class ID db_class_id = property(__get_db_class_id) - #: (Read Only) (:class:`~fdb.schema.Schema`) Database metadata object. + #: :class:`~fdb.schema.Schema`: Database metadata object. schema = utils.LateBindingProperty(_get_schema) - #: (Read Only) (datetime.datetime) Database creation date & time. + #: datetime.datetime: (R/O) Database creation date & time. creation_date = property(__get_creation_date) - #: (Read Only) (float) On-Disk Structure (ODS). + #: float: (R/O) On-Disk Structure (ODS). ods = property(__get_ods) - #: (Read Only) (int) On-Disk Structure (ODS) major version number. + #: int: (R/O) On-Disk Structure (ODS) major version number. ods_version = property(__get_ods_version) - #: (Read Only) (int) On-Disk Structure (ODS) minor version number. + #: int: (R/O) On-Disk Structure (ODS) minor version number. ods_minor_version = property(__get_ods_minor_version) - #: (Read Only) (int) Database page size in bytes. + #: int: (R/O) Database page size in bytes. page_size = property(__get_page_size) - #: (Read Only) (int) Size of page cache in pages. + #: int: (R/O) Size of page cache in pages. page_cache_size = property(__get_page_cache_size) - #: (Read Only) (int) Number of database pages allocated. + #: int: (R/O) Number of database pages allocated. pages_allocated = property(__get_pages_allocated) - #: (Read Only) (int) Sweep interval. + #: int: (R/O) Sweep interval. sweep_interval = property(__get_sweep_interval) - #: (Read Only) (bool) When True 20% page space is reserved for holding backup versions of modified records. + #: bool: (R/O) When True 20% page space is reserved for holding backup versions of modified records. space_reservation = property(__get_space_reservation) - #: (Read Only) (bool) Mode in which database writes are performed: True=sync, False=async. + #: bool: (R/O) Mode in which database writes are performed (True=sync, False=async). forced_writes = property(__get_forced_writes) - #: (Read Only) Dictionary with I/O stats (reads,writes,fetches,marks) + #: dict: (R/O) Dictionary with I/O stats (reads,writes,fetches,marks) #: Keys are `isc_info_reads`, `isc_info_writes`, `isc_info_fetches` and `isc_info_marks` constants. io_stats = property(__get_io_stats) - #: (Read Only) (int) Amount of server memory (in bytes) currently in use. + #: int: (R/O) Amount of server memory (in bytes) currently in use. current_memory = property(__get_current_memory) - #: (Read Only) (int) Maximum amount of memory (in bytes) used at one time since the first process + #: int: (R/O) Maximum amount of memory (in bytes) used at one time since the first process #: attached to the database. max_memory = property(__get_max_memory) - #: (Read Only) (int) ID of Oldest Interesting Transaction. + #: int: (R/O) ID of Oldest Interesting Transaction. oit = property(__get_oit) - #: (Read Only) (int) ID of Oldest Active Transaction. + #: int: (R/O) ID of Oldest Active Transaction. oat = property(__get_oat) - #: (Read Only) (int) ID of Oldest Snapshot Transaction. + #: int: (R/O) ID of Oldest Snapshot Transaction. ost = property(__get_ost) - #: (Read Only) (int) ID of Next Transaction. + #: int: (R/O) ID of Next Transaction. next_transaction = property(__get_next_transaction) - #: (Read Only) (:class:`~fdb.monitor.Monitor`) Database monitoring object. + #: :class:`~fdb.monitor.Monitor`: Database monitoring object. monitor = utils.LateBindingProperty(_get_monitor) def isreadonly(self): @@ -1935,10 +1986,12 @@ :meth:`~fdb.schema.Schema.close` and :meth:`~fdb.schema.Schema.bind`, and those attributes that are already defined by Connection class. - .. note:: - + Note: Use `connection_class` parametr of :func:`connect` or :func:`create_database` to create connections with direct schema interface. + + See Also: + :class:`fdb.schema.Schema` for list of methods that extend this class. """ def __init__(self, db_handle, dpb=None, sql_dialect=3, charset=None, isolation_level=ISOLATION_LEVEL_READ_COMMITED): @@ -1963,15 +2016,15 @@ .. warning: Internaly used class not intended for direct use. """ - #: List of registered event names + #: list: Registered event names event_names = [] - #: length of internal event buffer + #: int: length of internal event buffer buf_length = 0 - #: Event ID + #: int: Event ID event_id = 0 - #: Event buffer + #: bytes: Event buffer event_buf = None - #: Result buffer + #: bytes: Result buffer result_buf = None def __init__(self, queue, db_handle, event_names): self.__first = True @@ -2038,7 +2091,7 @@ return self.__closed def __del__(self): self.close() - #: (ReadOnly) True if block is closed for business + #: bool: (R/O)True if block is closed for business closed = property(__get_closed) @@ -2062,17 +2115,17 @@ :meth:`close` automatically. Example: + .. code-block:: python - .. code-block:: python - - with connection.event_conduit( ('event_a', 'event_b') ) as conduit: - events = conduit.wait() - process_events(events) + with connection.event_conduit( ('event_a', 'event_b') ) as conduit: + events = conduit.wait() + process_events(events) """ def __init__(self, db_handle, event_names): """ - :param db_handle: Database handle. - :param event_names: List of strings that represent event names. + Args: + db_handle: Database handle. + event_names (list): List of strings that represent event names. """ self._db_handle = db_handle self._isc_status = ISC_STATUS_ARRAY(0) @@ -2122,25 +2175,26 @@ Blocks the calling thread until at least one of the events occurs, or the specified timeout (if any) expires. - :param timeout: Number of seconds (use a float to indicate fractions of - seconds). If not even one of the relevant events has - occurred after timeout seconds, this method will unblock - and return None. The default timeout is infinite. - :type timeout: integer or float - :returns: `None` if the wait timed out, otherwise a dictionary that maps - `event_name -> event_occurrence_count`. + Keyword Args: + timeout (int or float): Number of seconds (use a float to indicate fractions of + seconds). If not even one of the relevant events has + occurred after timeout seconds, this method will unblock + and return None. The default timeout is infinite. + + Returns: + `None` if the wait timed out, otherwise a dictionary that maps + `event_name -> event_occurrence_count`. Example: + .. code-block:: python - .. code-block:: python - - >>>conduit = connection.event_conduit( ('event_a', 'event_b') ) - >>>conduit.begin() - >>>conduit.wait() - { - 'event_a': 1, - 'event_b': 0 - } + >>>conduit = connection.event_conduit( ('event_a', 'event_b') ) + >>>conduit.begin() + >>>conduit.wait() + { + 'event_a': 1, + 'event_b': 0 + } In the example above `event_a` occurred once and `event_b` did not occur at all. @@ -2186,8 +2240,7 @@ DO NOT create instances of this class directly! Use only :meth:`Cursor.prep` to get PreparedStatement instances. - .. note:: - + Note: PreparedStatements are bound to :class:`Cursor` instance that created them, and using them with other Cursor would report an error. """ @@ -3378,17 +3431,17 @@ """Specify a BLOB column(s) to work in `stream` mode instead classic, materialized mode. - :param blob_spec: Single name or sequence of column names. Name must - be in format as it's stored in database (refer - to :attr:`description` for real value). - :type blob_spec: string or list + Args: + blob_spec (str or list): Single name or sequence of column names. Name must + be in format as it's stored in database (refer + to :attr:`description` for real value). - .. important:: + .. important:: - BLOB name is **permanently** added to the list of BLOBs handled - as `stream` BLOBs by this instance. + BLOB name is **permanently** added to the list of BLOBs handled + as `stream` BLOBs by this instance. - :param string blob_spec: Name of BLOB column. + blob_spec (str): Name of BLOB column. """ if isinstance(blob_spec, ibase.StringType): self.__streamed_blobs.append(blob_spec) @@ -3400,7 +3453,8 @@ (:class:`BlobReader`) instead string. Value -1 means no size limit (use at your own risk). Default value is 64K - :param integer size: Max. size for materialized blob. + Args: + size (int): Max. size for materialized blob. """ self.__streamed_blob_treshold = size def __del__(self): @@ -3412,26 +3466,25 @@ """ self._free_handle() - #: (Read Only) (string) SQL command this PreparedStatement executes. + #: str: (R/O) SQL command this PreparedStatement executes. sql = property(__get_sql) - #: (Read Only) Sequence of 7-item sequences. - #: Each of these sequences contains information describing one result column: - #: (name, type_code, display_size,internal_size, precision, scale, null_ok) + #: Sequence of 7-item sequences: Each of these sequences contains information describing one + #: result column - (name, type_code, display_size,internal_size, precision, scale, null_ok) description = property(__get_description) - #: (Read Only) (integer) Specifies the number of rows that the last execution + #: int: (R/O) Specifies the number of rows that the last execution #: produced (for DQL statements like select) or affected (for DML statements #: like update or insert ). #: #: The attribute is -1 in case the statement was not yet executed #: or the rowcount of the operation is not determinable by the interface. rowcount = property(__get_rowcount) - #: (Read Only) (string) A string representation of the execution plan generated + #: str: (R/O) A string representation of the execution plan generated #: for this statement by the database engine’s optimizer. plan = property(__get_plan) - #: (Read/Write) (string) Name for the SQL cursor. This property can be + #: str: (R/O) Name for the SQL cursor. This property can be #: ignored entirely if you don’t need to use it. name = property(__get_name, __set_name) - #: (Read Only) (boolean) True if closed. Note that closed means that PS + #: bool: (R/O) True if closed. Note that closed means that PS #: statement handle was closed for further fetching, releasing server resources, #: but wasn't dropped, and couldbe still used for another execution. closed = property(__get_closed) @@ -3448,8 +3501,7 @@ :meth:`ConnectionGroup.cursor` to get Cursor instances that operate in desired context. - .. note:: - + Note: Cursor is actually a high-level wrapper around :class:`PreparedStatement` instance(s) that handle the actual SQL statement execution and result management. @@ -3459,7 +3511,7 @@ Cursor supports the iterator protocol, yielding tuples of values like :meth:`fetchone`. """ - #: (Read/Write) As required by the Python DB API 2.0 spec, the value of this + #: int: (R/W) As required by the Python DB API 2.0 spec, the value of this #: attribute is observed with respect to the :meth:`fetchmany` method. However, #: changing the value of this attribute does not make any difference in fetch #: efficiency because the database engine only supports fetching a single row @@ -3474,8 +3526,9 @@ :class:`Connection` is set when the Cursor is created, and cannot be changed during the lifetime of that Cursor. - :param connection: :class:`Connection` instance this cursor should be bound to. - :param transaction: :class:`Transaction` instance this cursor should be bound to. + Args: + connection (:class:`Connection`): instance this cursor should be bound to. + transaction (:class:`Transaction`): instance this cursor should be bound to. """ self._connection = connection self._transaction = transaction @@ -3483,7 +3536,8 @@ def next(self): """Return the next item from the container. Part of *iterator protocol*. - :raises StopIteration: If there are no further items. + Raises: + StopIteration: If there are no further items. """ row = self.fetchone() if row: @@ -3544,14 +3598,20 @@ The result of the call is available through the standard fetchXXX() methods. - :param string procname: Stored procedure name. - :param parameters: (Optional) Sequence of parameters. Must contain one + Args: + procname (str): Stored procedure name. + + Keyword Args: + parameters (iterable): Sequence of parameters. Must contain one entry for each argument that the procedure expects. - :type parameters: List or Tuple - :returns: parameters, as required by Python DB API 2.0 Spec. - :raises TypeError: When parameters is not List or Tuple. - :raises `~fdb.ProgrammingError`: When more parameters than expected are suplied. - :raises `~fdb.DatabaseError`: When error is returned by server. + + Returns: + `parameters` as required by Python DB API 2.0 Spec. + + Raises: + TypeError: When parameters is not List or Tuple. + fdb.ProgrammingError: When more parameters than expected are suplied. + fdb.DatabaseError: When error is returned by server. """ if not parameters: params = [] @@ -3571,8 +3631,7 @@ is still bound to :class:`Connection` and :class:`Transaction`, so it could be still used to execute SQL statements. - .. warning:: - + Warning: FDB's implementation of Cursor somewhat violates the Python DB API 2.0, which requires that cursor will be unusable after call to `close`; and an Error (or subclass) exception should be raised if any operation is @@ -3589,25 +3648,28 @@ def execute(self, operation, parameters=None): """Prepare and execute a database operation (query or command). - .. note:: - + Note: Execution is handled by :class:`PreparedStatement` that is either supplied as `operation` parameter, or created internally when `operation` is a string. Internally created PreparedStatements are stored in cache for later reuse, when the same `operation` string is used again. - :returns: self, so call to execute could be used as iterator. - :param operation: SQL command specification. - :type operation: string or :class:`PreparedStatement` instance - :param parameters: (Optional) Sequence of parameters. Must contain one - entry for each argument that the operation expects. - :type parameters: List or Tuple - :raises ValueError: When operation PreparedStatement belongs to different - Cursor instance. - :raises TypeError: When parameters is not List or Tuple. - :raises `~fdb.ProgrammingError`: When more parameters than expected are suplied. - :raises `~fdb.DatabaseError`: When error is returned by server. + Returns: + `self` so call to execute could be used as iterator. + + Args: + operation (str :class:`PreparedStatement`): SQL command specification. + + Keyword Args: + parameters (list or tuple): Sequence of parameters. Must contain one + entry for each argument that the operation expects. + + Raises: + ValueError: When operation PreparedStatement belongs to different Cursor instance. + TypeError: When parameters is not List or Tuple. + fdb.ProgrammingError: When more parameters than expected are suplied. + fdb.DatabaseError: When error is returned by server. """ if is_dead_proxy(self._ps): self._ps = None @@ -3630,16 +3692,20 @@ def prep(self, operation): """Create prepared statement for repeated execution. - .. note:: - + Note: Returned :class:`PreparedStatement` instance is bound to its Cursor instance via strong reference, and is not stored in Cursor's internal cache of prepared statements. - :param string operation: SQL command - :returns: :class:`PreparedStatement` instance. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.InternalError`: On unexpected processing condition. + Args: + operation (str): SQL command + + Returns: + :class:`PreparedStatement` + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.InternalError: On unexpected processing condition. """ if not self._transaction.active: self._transaction.begin() @@ -3649,28 +3715,28 @@ against all parameter sequences or mappings found in the sequence `seq_of_parameters`. - .. note:: - + Note: This function simply calls :meth:`execute` in a loop, feeding it with parameters from `seq_of_parameters`. Because `execute` caches `PreparedStatements`, calling `executemany` is equally efective as direct use of prepared statement and calling `execute` in a loop directly in application. - :returns: self, so call to executemany could be used as iterator. - :param operation: SQL command specification. - :type operation: string or :class:`PreparedStatement` instance - :param seq_of_parameters: Sequence of sequences of parameters. Must contain - one sequence of parameters for each execution - that has one entry for each argument that the - operation expects. - :type seq_of_parameters: List or Tuple - :raises ValueError: When operation PreparedStatement belongs to different - Cursor instance. - :raises TypeError: When seq_of_parameters is not List or Tuple. - :raises `~fdb.ProgrammingError`: When there are more parameters in any sequence - than expected. - :raises `~fdb.DatabaseError`: When error is returned by server. + Returns: + `self` so call to executemany could be used as iterator. + + Args: + operation (str ot :class:`PreparedStatement`): SQL command specification. + seq_of_parameters (list or tuple): Sequence of sequences of parameters. Must contain + one sequence of parameters for each execution + that has one entry for each argument that the + operation expects. + + Raises: + ValueError: When operation PreparedStatement belongs to different Cursor instance. + TypeError: When seq_of_parameters is not List or Tuple. + fdb.ProgrammingError: When there are more parameters in any sequence than expected. + fdb.DatabaseError: When error is returned by server. """ if not isinstance(operation, PreparedStatement): operation = self.prep(operation) @@ -3680,11 +3746,14 @@ def fetchone(self): """Fetch the next row of a query result set. - :returns: tuple of returned values, or None when no more data is available. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When underlying :class:`PreparedStatement` is - closed, statement was not yet executed, or - unknown status is returned by fetch operation. + Returns: + Tuple of returned values, or None when no more data is available. + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When underlying :class:`PreparedStatement` is + closed, statement was not yet executed, or + unknown status is returned by fetch operation. """ if self._ps: return self._ps._fetchone() @@ -3701,12 +3770,17 @@ the specified number of rows not being available, fewer rows may be returned. - :param integer size: Max. number of rows to fetch. - :returns: List of tuples, where each tuple is one row of returned values. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When underlying :class:`PreparedStatement` is - closed, statement was not yet executed, or - unknown status is returned by fetch operation. + Keyword Args: + size (int): Max. number of rows to fetch. + + Returns: + List of tuples, where each tuple is one row of returned values. + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When underlying :class:`PreparedStatement` is + closed, statement was not yet executed, or + unknown status is returned by fetch operation. """ i = 0 result = [] @@ -3721,11 +3795,14 @@ def fetchall(self): """Fetch all (remaining) rows of a query result. - :returns: List of tuples, where each tuple is one row of returned values. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When underlying :class:`PreparedStatement` is - closed, statement was not yet executed, or - unknown status is returned by fetch operation. + Returns: + List of tuples, where each tuple is one row of returned values. + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When underlying :class:`PreparedStatement` is + closed, statement was not yet executed, or + unknown status is returned by fetch operation. """ return [row for row in self] def fetchonemap(self): @@ -3733,12 +3810,14 @@ except that it returns a mapping of field name to field value, rather than a tuple. - :returns: :class:`fbcore._RowMapping` of returned values, or None when - no more data is available. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When underlying :class:`PreparedStatement` is - closed, statement was not yet executed, or - unknown status is returned by fetch operation. + Returns: + :class:`fbcore._RowMapping` of returned values, or None when no more data is available. + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When underlying :class:`PreparedStatement` is + closed, statement was not yet executed, or + unknown status is returned by fetch operation. """ row = self.fetchone() if row: @@ -3749,13 +3828,17 @@ except that it returns a list of mappings of field name to field value, rather than a list of tuples. - :param integer size: Max. number of rows to fetch. - :returns: List of :class:`fbcore._RowMapping` instances, one such instance for - each row. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When underlying :class:`PreparedStatement` is - closed, statement was not yet executed, or - unknown status is returned by fetch operation. + Keyword Args: + size (int): Max. number of rows to fetch. + + Returns: + List of :class:`fbcore._RowMapping` instances, one such instance for each row. + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When underlying :class:`PreparedStatement` is + closed, statement was not yet executed, or + unknown status is returned by fetch operation. """ i = 0 result = [] @@ -3772,27 +3855,30 @@ except that it returns a list of mappings of field name to field value, rather than a list of tuples. - :returns: List of :class:`fbcore._RowMapping` instances, one such instance for - each row. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When underlying :class:`PreparedStatement` is - closed, statement was not yet executed, or - unknown status is returned by fetch operation. + Returns: + List of :class:`fbcore._RowMapping` instances, one such instance for each row. + + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When underlying :class:`PreparedStatement` is + closed, statement was not yet executed, or + unknown status is returned by fetch operation. """ return [row for row in self.itermap()] def iter(self): """Equivalent to the :meth:`fetchall`, except that it returns iterator rather than materialized list. - :returns: Iterator that yields tuple of values like :meth:`fetchone`. + Returns: + iterator: that yields tuple of values like :meth:`fetchone`. """ return self def itermap(self): """Equivalent to the :meth:`fetchallmap`, except that it returns iterator rather than materialized list. - :returns: Iterator that yields :class:`fbcore._RowMapping` instance - like :meth:`fetchonemap`. + Returns: + Iterator that yields :class:`fbcore._RowMapping` instance like :meth:`fetchonemap`. """ return utils.Iterator(self.fetchonemap, None) def setinputsizes(self, sizes): @@ -3807,10 +3893,10 @@ """Specify a BLOB column(s) to work in `stream` mode instead classic, materialized mode for already executed statement. - :param blob_name: Single name or sequence of column names. Name must - be in format as it's stored in database (refer - to :attr:`description` for real value). - :type blob_name: string or list + Args: + blob_name (str or list): Single name or sequence of column names. Name must + be in format as it's stored in database (refer + to :attr:`description` for real value). .. important:: @@ -3819,8 +3905,11 @@ If instance is stored in internal cache of prepared statements, the same command executed repeatedly will retain this setting. - :param string blob_name: Name of BLOB column. - :raises `~fdb.ProgrammingError`: + Args: + blob_name (str): Name of BLOB column. + + Raises: + fdb.ProgrammingError: """ if self._ps: self._ps.set_stream_blob(blob_name) @@ -3832,7 +3921,8 @@ (:class:`BlobReader`) instead string. Value -1 means no size limit (use at your own risk). Default value is 64K - :param integer size: Max. size for materialized blob. + Args: + size (int): Max. size for materialized blob. """ if self._ps: self._ps.set_stream_blob_treshold(size) @@ -3840,21 +3930,20 @@ raise ProgrammingError def __del__(self): self.close() - #: (Read Only) Sequence of 7-item sequences. - #: Each of these sequences contains information describing one result column: + #: list: (R/O) List of tuples (with 7-item). + #: Each of these tuples contains information describing one result column: #: (name, type_code, display_size,internal_size, precision, scale, null_ok) #: #: If cursor doesn't have a prepared statement, the value is None. description = property(__get_description) - #: (Read Only) (integer) Specifies the number of rows that the last executeXXX() + #: int: (R/O) Specifies the number of rows that the last executeXXX() #: produced (for DQL statements like select) or affected (for DML statements #: like update or insert ). #: #: The attribute is -1 in case no executeXXX() has been performed on the cursor #: or the rowcount of the last operation is not determinable by the interface. #: - #: .. note:: - #: + #: Note: #: The database engine's own support for the determination of #: “rows affected”/”rows selected” is quirky. The database engine only #: supports the determination of rowcount for INSERT, UPDATE, DELETE, @@ -3868,17 +3957,17 @@ #: 1302 rows until the 1303rd row is fetched, result sets larger than 2604 #: rows until the 2605th row is fetched, and so on, in increments of 1302. rowcount = property(__get_rowcount) - #: (Read/Write) (string) Name for the SQL cursor. This property can be + #: str: (R/O) Name for the SQL cursor. This property can be #: ignored entirely if you don’t need to use it. name = property(__get_name, __set_name) - #: (Read Only) (string) A string representation of the execution plan + #: str: (R/O) A string representation of the execution plan #: for last executed statement generated by the database engine’s optimizer. #: `None` if no statement was executed. plan = property(__get_plan) - #: (Read Only) (:class:`Connection`) PEP 249 Extension. + #: :class:`Connection`: (R/O) PEP 249 Extension. #: Reference to the :class:`Connection` object on which the cursor was created. connection = property(__get_connection) - #: (Read Only) (:class:`Transaction`) + #: :class:`Transaction`: (R/O) #: Reference to the :class:`Transaction` object on which the cursor was created. transaction = property(__get_transaction) @@ -3903,15 +3992,19 @@ def __init__(self, connections, default_tpb=None, default_action='commit'): """ - :param iterable connections: Sequence of (up to 16) :class:`Connection` instances. - :param default_tpb: Transaction Parameter Block for this transaction. - If `None` is specified, uses `ISOLATION_LEVEL_READ_COMMITED`. - :type default_tpb: :class:`TPB` instance, list/tuple of `isc_tpb_*` constants - or `bytestring` - :param default_action: Action taken when active transaction is ended - automatically (during :meth:`close` or :meth:`begin`). - :type default_action: string 'commit' or 'rollback' - :raises `~fdb.ProgrammingError`: When zero or more than 16 connections are given. + Args: + connections (iterable): Sequence of (up to 16) :class:`Connection` instances. + + Keyword Args: + default_tpb (:class:`TPB` instance, iterable of `isc_tpb_*` constants or `bytestring`): + Transaction Parameter Block for this transaction. + If `None` is specified, uses `ISOLATION_LEVEL_READ_COMMITED`. + default_action (str): Action taken when active transaction is ended + automatically (during :meth:`close` or :meth:`begin`). Accepted values: + 'commit' or 'rollback' + + Raises: + fdb.ProgrammingError: When zero or more than 16 connections are given. """ if len(connections) > 16: raise ProgrammingError("Transaction can't accept more than 16 Connections") @@ -3980,19 +4073,19 @@ Automatically starts transaction if it's not already started. - :param string sql: SQL statement to execute. + Args: + sql (str): SQL statement to execute. .. important:: - **The statement must not be of a type that returns a result set.** - In most cases (especially cases in which the same statement – perhaps - a parameterized statement – is executed repeatedly), it is better to - create a cursor using the connection’s cursor method, then execute - the statement using one of the cursor’s execute methods. - - :param string sql: SQL statement to execute. + **The statement must not be of a type that returns a result set.** + In most cases (especially cases in which the same statement – perhaps + a parameterized statement – is executed repeatedly), it is better to + create a cursor using the connection’s cursor method, then execute + the statement using one of the cursor’s execute methods. - :raises `~fdb.DatabaseError`: When error is returned from server. + Raises: + fdb.DatabaseError: When error is returned from server. """ if not self.active: self.begin() @@ -4017,13 +4110,12 @@ def begin(self, tpb=None): """Starts a transaction explicitly. - :param tpb: (optional) Transaction Parameter Block for newly created - Transaction. If not specified, :attr:`default_tpb` is used. - :type tpb: :class:`TPB` instance, list/tuple of `isc_tpb_*` constants - or `bytestring` - - .. note:: + Keyword Args: + tpb (:class:`TPB` instance, iterable of `isc_tpb_*` constants or `bytestring`): + Transaction Parameter Block for newly created Transaction. + If not specified, :attr:`default_tpb` is used. + Note: Calling this method directly is never required; a transaction will be started implicitly if necessary. @@ -4033,9 +4125,10 @@ a :meth:`commit` or :meth:`rollback` will be performed first, accordingly to :attr:`default_action` value. - :raises `~fdb.DatabaseError`: When error is returned by server. - :raises `~fdb.ProgrammingError`: When TPB is in usupported format, or transaction - is permanently :attr:`closed`. + Raises: + fdb.DatabaseError: When error is returned by server. + fdb.ProgrammingError: When TPB is in usupported format, or transaction + is permanently :attr:`closed`. """ if self.__closed: raise ProgrammingError("Transaction is permanently closed.") @@ -4079,15 +4172,18 @@ def commit(self, retaining=False): """Commit any pending transaction to the database. - .. note:: + Note: If transaction is not active, this method does nothing, because the consensus among Python DB API experts is that transactions should always be started implicitly, even if that means allowing a `commit()` or `rollback()` without an actual transaction. - :param boolean retaining: Indicates whether the transactional context of - the transaction being resolved should be recycled. - :raises `~fdb.DatabaseError`: When error is returned by server as response to commit. + Keyword Args: + retaining (bool): Indicates whether the transactional context of + the transaction being resolved should be recycled. + + Raises: + fdb.DatabaseError: When error is returned by server as response to commit. """ if not self.active: return @@ -4104,21 +4200,24 @@ def rollback(self, retaining=False, savepoint=None): """Rollback any pending transaction to the database. - .. note:: + Note: If transaction is not active, this method does nothing, because the consensus among Python DB API experts is that transactions should always be started implicitly, even if that means allowing a `commit()` or `rollback()` without an actual transaction. - :param boolean retaining: Indicates whether the transactional context of - the transaction being resolved should be recycled. - Mutually exclusive with 'savepoint`. - :param string savepoint: Savepoint name. Causes the transaction to roll - back only as far as the designated savepoint, - rather than rolling back entirely. Mutually - exclusive with 'retaining`. - :raises `~fdb.ProgrammingError`: If both `savepoint` and `retaining` are specified. - :raises `~fdb.DatabaseError`: When error is returned by server as response to rollback. + Keyword Args: + retaining (bool): Indicates whether the transactional context of + the transaction being resolved should be recycled. + Mutually exclusive with 'savepoint`. + savepoint (str): Savepoint name. Causes the transaction to roll + back only as far as the designated savepoint, + rather than rolling back entirely. Mutually + exclusive with 'retaining`. + + Raises: + fdb.ProgrammingError: If both `savepoint` and `retaining` are specified. + fdb.DatabaseError: When error is returned by server as response to rollback. """ if not self.active: return @@ -4162,8 +4261,7 @@ def savepoint(self, name): """Establishes a savepoint with the specified name. - .. note:: - + Note: If transaction is bound to multiple connections, savepoint is created on all of them. @@ -4173,22 +4271,24 @@ such API call), but by executing `SAVEPOINT ` SQL statement, calling this method starts the transaction if it was not yet started. - :param string name: Savepoint name. + Args: + name (str): Savepoint name. """ self.execute_immediate('SAVEPOINT %s' % name) def cursor(self, connection=None): """Creates a new :class:`Cursor` that will operate in the context of this Transaction. - :param connection: **Required only when** Transaction is bound to multiple - `Connections`, to specify to which `Connection` the - returned Cursor should be bound. - :type connection: :class:`Connection` instance - - :raises `~fdb.ProgrammingError`: When transaction operates on multiple `Connections` - and: `connection` parameter is not specified, or - specified `connection` is not among `Connections` - this Transaction is bound to. + Keyword Args: + connection (:class:`Connection`): **Required only when** Transaction is bound to multiple + `Connections`, to specify to which `Connection` the + returned Cursor should be bound. + + Raises: + fdb.ProgrammingError: When transaction operates on multiple `Connections` + and: `connection` parameter is not specified, or + specified `connection` is not among `Connections` + this Transaction is bound to. """ if len(self._connections) > 1: if not connection: @@ -4206,12 +4306,15 @@ def trans_info(self, request): """Pythonic wrapper around :meth:`transaction_info` call. - :param request: One or more information request codes (see - :meth:`transaction_info` for details). Multiple codes - must be passed as tuple. - :returns: Decoded response(s) for specified request code(s). When - multiple requests are passed, returns a dictionary where key - is the request code and value is the response from server. + Args: + request: One or more information request codes (see + :meth:`transaction_info` for details). Multiple codes + must be passed as tuple. + + Returns: + Decoded response(s) for specified request code(s). When + multiple requests are passed, returns a dictionary where key + is the request code and value is the response from server. """ # We process request as a sequence of info codes, even if only one code # was supplied by the caller. @@ -4253,14 +4356,16 @@ This is very thin wrapper around Firebird API `isc_transaction_info` call. - :param integer info_code: One from the `isc_info_tra_*` constants. - :param result_type: Code for result type. - :type result_type: 'b' for binary string or 'i' for integer - :raises `~fdb.ProgrammingError`: If transaction is not active. - :raises `~fdb.OperationalError`: When result is too large to fit into buffer of - size SHRT_MAX. - :raises `~fdb.InternalError`: On unexpected processing condition. - :raises ValueError: When illegal result type code is specified. + Args: + info_code (int): One from the `isc_info_tra_*` constants. + result_type (str): Code for result type. + Accepted values: 'b' for binary string or 'i' for integer + + Raises: + fdb.ProgrammingError: If transaction is not active. + fdb.OperationalError: When result is too large to fit into buffer of size SHRT_MAX. + fdb.InternalError: On unexpected processing condition. + ValueError: When illegal result type code is specified. """ self.__check_active() request_buffer = bs([info_code]) @@ -4305,8 +4410,7 @@ def prepare(self): """Manually triggers the first phase of a two-phase commit (2PC). - .. note:: - + Note: Direct use of this method is optional; if preparation is not triggered manually, it will be performed implicitly by `commit()` in a 2PC. """ @@ -4323,30 +4427,30 @@ "Returns True if transaction is Read Only." return self.trans_info(isc_info_tra_access) == isc_info_tra_readonly - #: (Read Only) (int) Internal ID (server-side) for transaction. + #: int: (R/O) Internal ID (server-side) for transaction. transaction_id = property(__get_transaction_id) - #: (Read Only) True if transaction is closed. + #: bool: (R/O) True if transaction is closed. closed = property(__get_closed) - #: (Read Only) True if transaction is active. + #: bool: (R/O) True if transaction is active. active = property(__get_active) - #: (Read Only) List of :class:`Cursor` objects associated with this Transaction. + #: list: (R/O) List of :class:`Cursor` objects associated with this Transaction. cursors = property(__get_cursors) - #: (Read/Write) (string) 'commit' or 'rollback', action to be + #: str: (R/W) `commit` or `rollback`, action to be #: taken when physical transaction has to be ended automatically. - #: **Default is 'commit'**. + #: Default is `commit`. default_action = property(__get_default_action, __set_default_action) - #: (Read Only) (int) ID of Oldest Interesting Transaction when this transaction started. + #: int: (R/O) ID of Oldest Interesting Transaction when this transaction started. oit = property(__get_oit) - #: (Read Only) (int) ID of Oldest Active Transaction when this transaction started. + #: int: (R/O) ID of Oldest Active Transaction when this transaction started. oat = property(__get_oat) - #: (Read Only) (int) ID of Oldest Snapshot Transaction when this transaction started. + #: int: (R/O) ID of Oldest Snapshot Transaction when this transaction started. ost = property(__get_ost) - #: (Read Only) (int) or (tuple) Isolation level code [isc_info_tra_consistency, + #: int or tuple: (R/O) Isolation level code [isc_info_tra_consistency, # isc_info_tra_concurrency or isc_info_tra_read_committed]. For `isc_info_tra_read_committed` # return tuple where first item is `isc_info_tra_read_committed` and second one is # [isc_info_tra_no_rec_version or isc_info_tra_rec_version] isolation = property(__get_isolation) - #: (Read Only) (int) Lock timeout (seconds or -1 for unlimited). + #: int: (R/O) Lock timeout (seconds or -1 for unlimited). lock_timeout = property(__get_lock_timeout) class ConnectionGroup(object): @@ -4359,7 +4463,7 @@ """ # XXX: ConnectionGroup objects currently are not thread-safe. Since # separate Connections can be manipulated simultaneously by different - # threads in kinterbasdb, it would make sense for a container of multiple + # threads in fdb, it would make sense for a container of multiple # connections to be safely manipulable simultaneously by multiple threads. # XXX: Adding two connections to the same database freezes the DB client @@ -4370,9 +4474,11 @@ def __init__(self, connections=()): """ - :param iterable connections: Sequence of :class:`Connection` instances. + Args: + connections (iterable): Sequence of :class:`Connection` instances. - .. seealso:: See :meth:`add` for list of exceptions the constructor may throw. + See Also: + See :meth:`add` for list of exceptions the constructor may throw. """ self._cons = [] self._transaction = None @@ -4388,12 +4494,11 @@ def disband(self): """Forcefully deletes all connections from connection group. - .. note:: If transaction is active, it’s canceled (**rollback**). - - .. note:: + Note: + 1) If transaction is active, it’s canceled (**rollback**). - Any error during transaction finalization doesn't stop the disband - process, however the exception catched is eventually reported. + 2) Any error during transaction finalization doesn't stop the disband + process, however the exception catched is eventually reported. """ exc = None if self._transaction: @@ -4410,12 +4515,15 @@ def add(self, con): """Adds active connection to the group. - :param con: A :class:`Connection` instance to add to this group. - :raises TypeError: When `con` is not :class:`Connection` instance. - :raises `~fdb.ProgrammingError`: When `con` is already member of this or another - group, or :attr:`~Connection.closed`. - When this group has unresolved transaction or - contains 16 connections. + Args: + con: A :class:`Connection` instance to add to this group. + + Raises: + TypeError: When `con` is not :class:`Connection` instance. + fdb.ProgrammingError: When `con` is already member of this or another + group, or :attr:`~Connection.closed`. + When this group has unresolved transaction or + contains 16 connections. """ ### CONTRAINTS ON $con: ### # con must be an instance of kinterbasdb.Connection: @@ -4457,9 +4565,11 @@ def remove(self, con): """Removes specified connection from group. - :param con: A :class:`Connection` instance to remove. - :raises `~fdb.ProgrammingError`: When `con` doesn't belong to this group or - transaction is active. + Args: + con: A :class:`Connection` instance to remove. + + Raises: + fdb.ProgrammingError: When `con` doesn't belong to this group or transaction is active. """ if con not in self: raise ProgrammingError("con is not a member of this group.") @@ -4471,7 +4581,8 @@ def clear(self): """Removes all connections from group. - :raises `~fdb.ProgrammingError`: When transaction is active. + Raises: + fdb.ProgrammingError` When transaction is active. """ self.__require_transaction_state(False, "Cannot clear group that has an unresolved transaction.") self.__drop_transaction() @@ -4483,11 +4594,15 @@ distributed transaction and specific :class:`Connection` that belongs to this group. - .. note:: Automatically starts transaction if it's not already started. + Note: + Automatically starts transaction if it's not already started. + + Args: + connection (:class:`Connection`) Connection that should be responsible for Cursor. - :param connection: :class:`Connection` instance. - :raises `~fdb.ProgrammingError`: When group is empty or specified `connection` - doesn't belong to this group. + Raises: + fdb.ProgrammingError: When group is empty or specified `connection` + doesn't belong to this group. """ if not self._transaction: self.__require_non_empty_group('start') @@ -4502,7 +4617,8 @@ def contains(self, con): """Returns True if specified connection belong to this group. - :param con: :class:`Connection` instance. + Args: + con (:class:`Connection`): Connection that should be checked for presence. """ return con in self._cons __contains__ = contains # alias to support the 'in' operator @@ -4532,7 +4648,8 @@ Automatically starts transaction if it's not already started. - :param string sql: SQL statement to execute. + Args: + sql (str): SQL statement to execute. .. important:: @@ -4542,20 +4659,21 @@ create a cursor using the connection’s cursor method, then execute the statement using one of the cursor’s execute methods. - :param string sql: SQL statement to execute. - - :raises `~fdb.DatabaseError`: When error is returned from server. + Raises: + fdb.DatabaseError: When error is returned from server. """ self.__ensure_transaction() self._transaction.execute_immediate(sql) def begin(self, tpb=None): """Starts distributed transaction over member connections. - :param tpb: (Optional) Transaction Parameter Buffer for newly started - transaction. If not specified, :attr:`default_tpb` is used. - :type tpb: :class:`TPB` instance, list/tuple of `isc_tpb_*` constants - or `bytestring` - :raises `~fdb.ProgrammingError`: When group is empty or has active transaction. + Keyword Args: + tpb (:class:`TPB` instance, list/tuple of `isc_tpb_*` constants or `bytestring`): + Transaction Parameter Buffer for newly started + transaction. If not specified, :attr:`default_tpb` is used. + + Raises: + fdb.ProgrammingError: When group is empty or has active transaction. """ self.__require_transaction_state(False, "Must resolve current transaction before starting another.") self.__ensure_transaction() @@ -4564,8 +4682,11 @@ """Establishes a named SAVEPOINT on all member connections. See :meth:`Transaction.savepoint` for details. - :param string name: Name for savepoint. - :raises `~fdb.ProgrammingError`: When group is empty. + Args: + name (str): Name for savepoint. + + Raises: + fdb.ProgrammingError: When group is empty. """ self.__require_non_empty_group('savepoint') return self._transaction.savepoint(name) @@ -4579,15 +4700,18 @@ def commit(self, retaining=False): """Commits distributed transaction over member connections using 2PC. - .. note:: + Note: If transaction is not active, this method does nothing, because the consensus among Python DB API experts is that transactions should always be started implicitly, even if that means allowing a `commit()` or `rollback()` without an actual transaction. - :param boolean retaining: Indicates whether the transactional context of - the transaction being resolved should be recycled. - :raises `~fdb.ProgrammingError`: When group is empty. + Keyword Args: + retaining (bool): Indicates whether the transactional context of + the transaction being resolved should be recycled. + + Raises: + fdb.ProgrammingError: When group is empty. """ self.__require_non_empty_group('commit') # The consensus among Python DB API experts is that transactions should @@ -4599,15 +4723,22 @@ def rollback(self, retaining=False, savepoint=None): """Rollbacks distributed transaction over member connections. - .. note:: + Note: If transaction is not active, this method does nothing, because the consensus among Python DB API experts is that transactions should always be started implicitly, even if that means allowing a `commit()` or `rollback()` without an actual transaction. - :param boolean retaining: Indicates whether the transactional context of - the transaction being resolved should be recycled. - :raises `~fdb.ProgrammingError`: When group is empty. + Keyword Args: + retaining (bool): Indicates whether the transactional context of + the transaction being resolved should be recycled. + savepoint (str): Savepoint name. Causes the transaction to roll + back only as far as the designated savepoint, + rather than rolling back entirely. Mutually + exclusive with 'retaining`. + + Raises: + fdb.ProgrammingError: When group is empty. """ self.__require_non_empty_group('rollback') # The consensus among Python DB API experts is that transactions should @@ -4617,7 +4748,7 @@ return self._transaction.rollback(retaining, savepoint) - #: (Read/Write) Deafult Transaction Parameter Block used for transactions. + #: bytes: (R/W) Deafult Transaction Parameter Block used for transactions. default_tpb = property(__get_default_tpb, __set_default_tpb) @@ -4721,7 +4852,8 @@ def close(self): """Closes the Reader. Like :meth:`file.close`. - :raises `~fdb.DatabaseError`: When error is returned by server. + Raises: + fdb.DatabaseError: When error is returned by server. """ if self.__opened and not self.closed: self.__closed = True @@ -4737,7 +4869,8 @@ def next(self): """Return the next line from the BLOB. Part of *iterator protocol*. - :raises StopIteration: If there are no further lines. + Raises: + StopIteration: If there are no further lines. """ line = self.readline() if line: @@ -4754,10 +4887,10 @@ object. An empty string is returned when EOF is encountered immediately. Like :meth:`file.read`. - :raises `~fdb.ProgrammingError`: When reader is closed. - - .. note:: + Raises: + fdb.ProgrammingError: When reader is closed. + Note: Performs automatic conversion to `unicode` for TEXT BLOBs, if used Python is v3 or `connection charset` is defined. """ @@ -4794,10 +4927,10 @@ line). An empty string is returned when EOF is encountered immediately. Like :meth:`file.readline`. - :raises `~fdb.ProgrammingError`: When reader is closed. - - .. note:: + Raises: + fdb.ProgrammingError: When reader is closed. + Note: Performs automatic conversion to `unicode` for TEXT BLOBs, if used Python is v3 or `connection charset` is defined. """ @@ -4835,8 +4968,7 @@ the lines thus read. The optional sizehint argument (if present) is ignored. Like :meth:`file.readlines`. - .. note:: - + Note: Performs automatic conversion to `unicode` for TEXT BLOBs, if used Python is v3 or `connection charset` is defined. """ @@ -4850,14 +4982,16 @@ """Set the file’s current position, like stdio‘s `fseek()`. See :meth:`file.seek` details. - :param integer offset: Offset from specified position. - :param whence: (Optional) Context for offset. - :type whence: os.SEEK_SET, os.SEEK_CUR or os.SEEK_END + Args: + offset (int): Offset from specified position. - :raises `~fdb.ProgrammingError`: When reader is closed. + Keyword Args: + whence (int): Context for offset. Accepted values: os.SEEK_SET, os.SEEK_CUR or os.SEEK_END - .. warning:: + Raises: + fdb.ProgrammingError: When reader is closed. + Warning: If BLOB was NOT CREATED as `stream` BLOB, this method raises :exc:`DatabaseError` exception. This constraint is set by Firebird. """ @@ -4879,7 +5013,8 @@ def get_info(self): """Return information about BLOB. - :returns: Tuple with values: blob_length, segment_size, num_segments, blob_type + Returns: + tuple: tuple with items: blob_length, segment_size, num_segments, blob_type Meaning of individual values: @@ -4925,16 +5060,20 @@ offset += length + 2 # return (blob_length, segment_size, num_segments, blob_type) - def __get_closed(self): - return self.__closed - def __get_mode(self): - return self.__mode def __del__(self): self.close() - #: (Read Only) (boolean) True is BlobReader is closed. - closed = property(__get_closed) - #: (Read Only) (string) File mode - always "rb" - mode = property(__get_mode) + #: bool: (R/O) True is BlobReader is closed. + closed = property(lambda self: self.__closed, doc="True is BlobReader is closed") + #: str: (R/O) File mode - always "rb" + mode = property(lambda self: self.__mode, doc="File mode - always 'rb'") + #: ISC_QUAD: (R/O) BLOB ID + blob_id = property(lambda self: self.__blobid, doc="BLOB ID") + #: bool: (R/O) True if BLOB is a text BLOB + is_text = property(lambda self: self.__is_text, doc="True if BLOB is a text BLOB") + #: str: (R/O) BLOB character set + blob_charset = property(lambda self: self.__charset, doc="BLOB character set") + #: str: (R/O) Python character set for BLOB + charset = property(lambda self: self.__python_charset, doc="Python character set for BLOB") class _RowMapping(object): @@ -5108,7 +5247,8 @@ """Create valid `transaction parameter block` according to current values of member attributes. - :returns: (string) TPB block. + Returns: + bytes: binary Transaction Parameter Block for FB API calls """ # YYY: Optimization: Could memoize the rendered TPB str. self.clear() @@ -5138,7 +5278,7 @@ raise ValueError('Access mode must be one of (isc_tpb_read, isc_tpb_write).') self._access_mode = access_mode - #: (integer) Required access mode (`isc_tpb_read` or `isc_tpb_write`). + #: int: Required access mode (`isc_tpb_read` or `isc_tpb_write`). #: **Default:** `isc_tpb_write` access_mode = property(_get_access_mode, _set_access_mode) # isolation_level property: @@ -5170,7 +5310,7 @@ isolation_level = isolation_level, suboption self._isolation_level = isolation_level - #: (integer or tuple) Required Transaction Isolation Level. + #: int or tuple: Required Transaction Isolation Level. #: Single integer value equivalent to `isc_tpb_concurrency` or #: `isc_tpb_consistency`, or tuple of exactly two integer values, where #: the first one is `isc_tpb_read_committed` and second either @@ -5190,7 +5330,7 @@ raise ValueError('Lock resolution must be one of (isc_tpb_wait, isc_tpb_nowait).') self._lock_resolution = lock_resolution - #: (integer) Required lock resolution method. Either `isc_tpb_wait` or + #: int: Required lock resolution method. Either `isc_tpb_wait` or #: `isc_tpb_nowait`. #: #: **Default:** `isc_tpb_wait` @@ -5208,8 +5348,7 @@ ' %d.' % UINT_MAX) self._lock_timeout = lock_timeout - #: (integer) Required lock timeout or None. - #: + #: int: Required lock timeout or None. #: **Default:** `None` lock_timeout = property(_get_lock_timeout, _set_lock_timeout) @@ -5219,7 +5358,7 @@ self._table_reservation = TableReservation() return self._table_reservation - #: (:class:`TableReservation`) Table reservation specification. + #: :class:`TableReservation`: Table reservation specification. #: #: **Default:** `None`. #: @@ -5259,7 +5398,8 @@ """Create valid `table access parameter block` according to current key/value pairs. - :returns: (string) Table access definition block. + Returns: + str: Table access definition block. """ if not self: return b('') diff -Nru fdb-2.0.0/fdb/gstat.py fdb-2.0.1/fdb/gstat.py --- fdb-2.0.0/fdb/gstat.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/gstat.py 2018-05-03 10:58:43.000000000 +0000 @@ -60,200 +60,200 @@ class StatTable(object): "Statisctics for single database table." def __init__(self): - #: (str) Table name + #: str: Table name self.name = None - #: (int) Table ID + #: int: Table ID self.table_id = None - #: (int) Primary Pointer Page for table + #: int: Primary Pointer Page for table self.primary_pointer_page = None - #: (int) Index Root Page for table + #: int: Index Root Page for table self.index_root_page = None - #: (float) Average record length + #: float: Average record length self.avg_record_length = None - #: (int) Total number of record in table + #: int: Total number of record in table self.total_records = None - #: (float) Average record version length + #: float: Average record version length self.avg_version_length = None - #: (int) Total number of record versions + #: int: Total number of record versions self.total_versions = None - #: (int) Max number of versions for single record + #: int: Max number of versions for single record self.max_versions = None - #: (int) Number of data pages for table + #: int: Number of data pages for table self.data_pages = None - #: (int) Number of data page slots for table + #: int: Number of data page slots for table self.data_page_slots = None - #: (float) Average data page fill ratio + #: float: Average data page fill ratio self.avg_fill = None - #: (:class:`FillDistribution`) Data page fill distribution statistics + #: :class:`FillDistribution`: Data page fill distribution statistics self.distribution = None - #: (:class:`~fdb.utils.ObjectList`) Indices belonging to table + #: :class:`~fdb.utils.ObjectList`: Indices belonging to table self.indices = [] class StatTable3(StatTable): "Statisctics for single database table (Firebird 3 and above)." def __init__(self): super(StatTable3, self).__init__() - #: (int) Number of Pointer Pages + #: int: Number of Pointer Pages self.pointer_pages = None - #: (int) Number of record formats + #: int: Number of record formats self.total_formats = None - #: (int) Number of actually used record formats + #: int: Number of actually used record formats self.used_formats = None - #: (float) Average length of record fragments + #: float: Average length of record fragments self.avg_fragment_length = None - #: (int) Total number of record fragments + #: int: Total number of record fragments self.total_fragments = None - #: (int) Max number of fragments for single record + #: int: Max number of fragments for single record self.max_fragments = None - #: (float) Average length of unpacked record + #: float: Average length of unpacked record self.avg_unpacked_length = None - #: (float) Record compression ratio + #: float: Record compression ratio self.compression_ratio = None - #: (int) Number of Primary Data Pages + #: int: Number of Primary Data Pages self.primary_pages = None - #: (int) Number of Secondary Data Pages + #: int: Number of Secondary Data Pages self.secondary_pages = None - #: (int) Number of swept data pages + #: int: Number of swept data pages self.swept_pages = None - #: (int) Number of empty data pages + #: int: Number of empty data pages self.empty_pages = None - #: (int) Number of full data pages + #: int: Number of full data pages self.full_pages = None - #: (int) Number of BLOB values + #: int: Number of BLOB values self.blobs = None - #: (int) Total length of BLOB values (bytes) + #: int: Total length of BLOB values (bytes) self.blobs_total_length = None - #: (int) Number of BLOB pages + #: int: Number of BLOB pages self.blob_pages = None - #: (int) Number of Level 0 BLOB values + #: int: Number of Level 0 BLOB values self.level_0 = None - #: (int) Number of Level 1 BLOB values + #: int: Number of Level 1 BLOB values self.level_1 = None - #: (int) Number of Level 2 BLOB values + #: int: Number of Level 2 BLOB values self.level_2 = None class StatIndex(object): "Statisctics for single database index." def __init__(self, table): - #: (wekref.proxy) Proxy to parent :class:`TableStats` + #: wekref.proxy: Proxy to parent :class:`TableStats` self.table = weakref.proxy(table) table.indices.append(weakref.proxy(self)) - #: (str) Index name + #: str: Index name self.name = None - #: (int) Index ID + #: int: Index ID self.index_id = None - #: (int) Depth of index tree + #: int: Depth of index tree self.depth = None - #: (int) Number of leaft index tree buckets + #: int: Number of leaft index tree buckets self.leaf_buckets = None - #: (int) Number of index tree nodes + #: int: Number of index tree nodes self.nodes = None - #: (float) Average data length + #: float: Average data length self.avg_data_length = None - #: (int) Total number of duplicate keys + #: int: Total number of duplicate keys self.total_dup = None - #: (int) Max number of occurences for single duplicate key + #: int: Max number of occurences for single duplicate key self.max_dup = None - #: (:class:`FillDistribution`) Index page fill distribution statistics + #: :class:`FillDistribution`: Index page fill distribution statistics self.distribution = None class StatIndex3(StatIndex): "Statisctics for single database index (Firebird 3 and above)." def __init__(self, table): super(StatIndex3, self).__init__(table) - #: (int) Index Root page + #: int: Index Root page self.root_page = None - #: (float) Average node length + #: float: Average node length self.avg_node_length = None - #: (float) Average key length + #: float: Average key length self.avg_key_length = None - #: (float) Index key compression ratio + #: float: Index key compression ratio self.compression_ratio = None - #: (float) Average key prefix length + #: float: Average key prefix length self.avg_prefix_length = None - #: (float) Index clustering factor + #: float: Index clustering factor self.clustering_factor = None - #: (float) Ration + #: float: Ration self.ratio = None class StatDatabase(object): """Firebird database statistics (produced by gstat). """ def __init__(self): - #: (int) GSTAT version + #: int: GSTAT version self.gstat_version = None - #: (int) System change number (v3 only) + #: int: System change number (v3 only) self.system_change_number = None # ver3 - #: (datetime) gstat execution timestamp + #: datetime.datetime: gstat execution timestamp self.executed = None - #: (datetime) gstat completion timestamp + #: datetime.datetime; gstat completion timestamp self.completed = None # ver3 - #: (str) Database filename + #: str: Database filename self.filename = None - #: (int) Database flags + #: int: Database flags self.flags = 0 - #: (int) Checksum (v2 only) + #: int: Checksum (v2 only) self.checksum = 12345 # ver2 - #: (int) Database header generation + #: int: Database header generation self.generation = 0 - #: (int) Database page size + #: int: Database page size self.page_size = 0 #self.ods_version = None - #: (int) Oldest Interesting Transaction + #: int: Oldest Interesting Transaction self.oit = 0 - #: (int) Oldest Active Transaction + #: int: Oldest Active Transaction self.oat = 0 - #: (int) Oldest Snapshot Transaction + #: int: Oldest Snapshot Transaction self.ost = 0 - #: (int) Next Transaction + #: int: Next Transaction self.next_transaction = 0 - #: (int) Bumped Transaction (v2 only) + #: int: Bumped Transaction (v2 only) self.bumped_transaction = None # ver2 #self.sequence_number = 0 - #: (int) Next attachment ID + #: int: Next attachment ID self.next_attachment_id = 0 - #: (int) Implementation ID (v2 only) + #: int: Implementation ID (v2 only) self.implementation_id = 0 # ver2 - #: (str) Implementation (v3 only) + #: str: Implementation (v3 only) self.implementation = None # ver3 - #: (int) Number of shadows + #: int: Number of shadows self.shadow_count = 0 - #: (int) Number of page buffers + #: int: Number of page buffers self.page_buffers = 0 - #: (int) Next header page + #: int: Next header page self.next_header_page = 0 - #: (int) SQL Dialect + #: int: SQL Dialect self.database_dialect = 0 - #: (datetime) Database creation timestamp + #: datetime.datetime: Database creation timestamp self.creation_date = None - #: (list) Database attributes + #: list: Database attributes self.attributes = [] # Variable data - #: (int) Sweep interval (variable hdr item) + #: int: Sweep interval (variable hdr item) self.sweep_interval = None - #: (str) Continuation file (variable hdr item) + #: str: Continuation file (variable hdr item) self.continuation_file = None - #: (int) Last logical page (variable hdr item) + #: int: Last logical page (variable hdr item) self.last_logical_page = None - #: (str) Backup GUID (variable hdr item) + #: str: Backup GUID (variable hdr item) self.backup_guid = None - #: (str) Root file name (variable hdr item) + #: str: Root file name (variable hdr item) self.root_filename = None - #: (str) replay logging file (variable hdr item) + #: str: replay logging file (variable hdr item) self.replay_logging_file = None - #: (str) Backup difference file (variable hdr item) + #: str: Backup difference file (variable hdr item) self.backup_diff_file = None - #: (Encryption) Stats for enxrypted data page + #: Encryption: Stats for enxrypted data page self.encrypted_data_pages = None - #: (Encryption) Stats for enxrypted index page + #: Encryption: Stats for enxrypted index page self.encrypted_index_pages = None - #: (Encryption) Stats for enxrypted blob page + #: Encryption: Stats for enxrypted blob page self.encrypted_blob_pages = None - #: List of database file names + #: list: database file names self.continuation_files = [] - #: :class:`~fdb.utils.ObjectList` with :class:`StatTable` or :class:`StatTable3` instances + #: :class:`~fdb.utils.ObjectList`: :class:`StatTable` or :class:`StatTable3` instances self.tables = None - #: :class:`~fdb.utils.ObjectList` with :class:`StatIndex` or :class:`StatIndex3` instances + #: :class:`~fdb.utils.ObjectList`: :class:`StatIndex` or :class:`StatIndex3` instances self.indices = None def has_table_stats(self): """Return True if instance contains information about tables. @@ -282,10 +282,14 @@ def parse(lines): """Parse output from Firebird gstat utility. - :param lines: Iterable of lines produced by Firebird gstat utility. - :returns: :class:`~fdb.gstat.StatDatabase` instance with parsed results. + Args: + lines (iterable): Lines produced by Firebird gstat utility. - :raises `~fdb.ParseError`: When any problem is found in input stream. + Returns: + :class:`~fdb.gstat.StatDatabase` instance with parsed results. + + Raises: + fdb.ParseError: When any problem is found in input stream. """ def parse_hdr(line): "Parse line from header" diff -Nru fdb-2.0.0/fdb/ibase.py fdb-2.0.1/fdb/ibase.py --- fdb-2.0.0/fdb/ibase.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/ibase.py 2019-07-13 09:34:51.000000000 +0000 @@ -1397,6 +1397,9 @@ else: fb_library = CDLL(fb_library_name) + #: Firebird client library name + self.client_library_name = fb_library_name + #: Firebird client library (loaded by ctypes) self.client_library = fb_library #: isc_attach_database(POINTER(ISC_STATUS), c_short, STRING, POINTER(isc_db_handle), c_short, STRING) diff -Nru fdb-2.0.0/fdb/log.py fdb-2.0.1/fdb/log.py --- fdb-2.0.0/fdb/log.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/log.py 2019-07-08 09:48:05.000000000 +0000 @@ -31,12 +31,14 @@ def parse(lines): """Parse Firebird server log and yield named tuples describing individual log entries/events. - :param lines: Iterable of lines from Firebird server log. + Args: + lines: Iterable of lines from Firebird server log. - :raises `~fdb.ParseError`: When any problem is found in input stream. + Raises: + fdb.ParseError: When any problem is found in input stream. """ line_no = 0 - locale = getlocale(LC_ALL) + locale = getlocale() # (LC_ALL) if sys.platform == 'win32': setlocale(LC_ALL, 'English_United States') else: diff -Nru fdb-2.0.0/fdb/monitor.py fdb-2.0.1/fdb/monitor.py --- fdb-2.0.0/fdb/monitor.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/monitor.py 2018-05-03 10:36:45.000000000 +0000 @@ -229,10 +229,12 @@ def bind(self, connection): """Bind this instance to specified :class:`~fdb.Connection`. - :param connection: :class:`~fdb.Connection` instance. + Args: + connection: :class:`~fdb.Connection` instance. - :raises fdb.ProgrammingError: If Monitor object was set as internal (via - :meth:`_set_as_internal`) or database has ODS lower than 11.1. + Raises: + fdb.ProgrammingError: If Monitor object was set as internal (via + :meth:`_set_as_internal`) or database has ODS lower than 11.1. """ if self.__internal: raise fdb.ProgrammingError("Call to 'bind' not allowed for embedded Monitor.") @@ -247,8 +249,9 @@ def close(self): """Sever link to :class:`~fdb.Connection`. - :raises fdb.ProgrammingError: If Monitor object was set as internal (via - :meth:`_set_as_internal`). + Raises: + fdb.ProgrammingError: If Monitor object was set as internal (via + :meth:`_set_as_internal`). """ if self.__internal: raise fdb.ProgrammingError("Call to 'close' not allowed for embedded Monitor.") @@ -276,9 +279,11 @@ def get_attachment(self, id): """Get :class:`AttachmentInfo` by ID. - :param int id: Attachment ID. + Args: + id (int): Attachment ID. - :returns: :class:`AttachmentInfo` with specified ID or `None`. + Returns: + :class:`AttachmentInfo` with specified ID or `None`. """ for attachment in self.attachments: if attachment.id == id: @@ -288,9 +293,11 @@ def get_transaction(self, id): """Get :class:`TransactionInfo` by ID. - :param int id: Transaction ID. + Args: + id (int): Transaction ID. - :returns: :class:`TransactionInfo` with specified ID or `None`. + Returns: + :class:`TransactionInfo` with specified ID or `None`. """ for transaction in self.transactions: if transaction.id == id: @@ -300,9 +307,11 @@ def get_statement(self, id): """Get :class:`StatementInfo` by ID. - :param int id: Statement ID. + Args: + id (int): Statement ID. - :returns: :class:`StatementInfo` with specified ID or `None`. + Returns: + :class:`StatementInfo` with specified ID or `None`. """ for statement in self.statements: if statement.id == id: @@ -312,9 +321,11 @@ def get_call(self, id): """Get :class:`CallStackInfo` by ID. - :param int id: Callstack ID. + Args: + id (int): Callstack ID. - :returns: :class:`CallStackInfo` with specified ID or `None`. + Returns: + :class:`CallStackInfo` with specified ID or `None`. """ for call in self.callstack: if call.id == id: @@ -545,8 +556,9 @@ def terminate(self): """Terminates client session associated with this attachment. - :raises fdb.ProgrammingError: If database has ODS lower than 11.2 or - this attachement is current session. + Raises + fdb.ProgrammingError: If database has ODS lower than 11.2 or + this attachement is current session. """ if self.monitor._con.ods < fdb.ODS_FB_25: raise fdb.ProgrammingError("Attachments could be terminated only " \ @@ -705,7 +717,8 @@ def terminate(self): """Terminates execution of statement. - :raises fdb.ProgrammingError: If this attachement is current session. + Raises: + fdb.ProgrammingError: If this attachement is current session. """ if self.attachment == self.monitor.this_attachment: raise fdb.ProgrammingError("Can't terminate statement from current session.") diff -Nru fdb-2.0.0/fdb/schema.py fdb-2.0.1/fdb/schema.py --- fdb-2.0.0/fdb/schema.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/schema.py 2018-05-03 10:32:15.000000000 +0000 @@ -330,9 +330,12 @@ """Get list of minimal set of SQL GRANT statamenets necessary to grant specified privileges. - :param list privileges: List of :class:`Privilege` instances. - :param list grantors: List of standard grantor names. Generates GRANTED BY - clause for privileges granted by user that's not in list. + Args: + privileges (list): List of :class:`Privilege` instances. + + Keyword Args: + grantors (list): List of standard grantor names. Generates GRANTED BY + clause for privileges granted by user that's not in list. """ tp = {'S':'SELECT', 'I':'INSERT', 'U':'UPDATE', 'D':'DELETE', 'R':'REFERENCES'} @@ -636,38 +639,47 @@ if self._con.ods >= fdb.ODS_FB_30: cols.extend(['RDB$SECURITY_CLASS', 'RDB$OWNER_NAME']) self._ic.execute("""select %s from RDB$FIELDS""" % ','.join(cols)) - self.__domains = ObjectList((Domain(self, row) for row in self._ic.itermap()), - Domain, 'item.name') - self.__domains.freeze() + sys_domains, user_domains = ObjectList((Domain(self, row) for row in self._ic.itermap()), + Domain, 'item.name').split(lambda item: + item.issystemobject()) + sys_domains.freeze() + user_domains.freeze() + self.__domains = (user_domains, sys_domains) return self.__domains def _get_domains(self): - return self._get_all_domains().filter(lambda item: not item.issystemobject()) + return self._get_all_domains()[0] def _get_sysdomains(self): - return self._get_all_domains().filter(lambda item: item.issystemobject()) + return self._get_all_domains()[1] def _get_all_tables(self): if self.__tables is None: self.__fail_if_closed() self._ic.execute("select * from rdb$relations where rdb$view_blr is null") - self.__tables = ObjectList((Table(self, row) for row in self._ic.itermap()), - Table, 'item.name') - self.__tables.freeze() + sys_tables, user_tables = ObjectList((Table(self, row) for row in self._ic.itermap()), + Table, 'item.name').split(lambda item: + item.issystemobject()) + sys_tables.freeze() + user_tables.freeze() + self.__tables = (user_tables, sys_tables) return self.__tables def _get_tables(self): - return self._get_all_tables().filter(lambda item: not item.issystemobject()) + return self._get_all_tables()[0] def _get_systables(self): - return self._get_all_tables().filter(lambda item: item.issystemobject()) + return self._get_all_tables()[1] def _get_all_views(self): if self.__views is None: self.__fail_if_closed() self._ic.execute("select * from rdb$relations where rdb$view_blr is not null") - self.__views = ObjectList((View(self, row) for row in self._ic.itermap()), - View, 'item.name') - self.__views.freeze() + sys_views, user_views = ObjectList((View(self, row) for row in self._ic.itermap()), + View, 'item.name').split(lambda item: + item.issystemobject()) + sys_views.freeze() + user_views.freeze() + self.__views = (user_views, sys_views) return self.__views def _get_views(self): - return self._get_all_views().filter(lambda item: not item.issystemobject()) + return self._get_all_views()[0] def _get_sysviews(self): - return self._get_all_views().filter(lambda item: item.issystemobject()) + return self._get_all_views()[1] def _get_constraint_indices(self): if self.__constraint_indices is None: self.__fail_if_closed() @@ -686,14 +698,17 @@ RDB$INDEX_ID, RDB$UNIQUE_FLAG, RDB$DESCRIPTION, RDB$SEGMENT_COUNT, RDB$INDEX_INACTIVE, RDB$INDEX_TYPE, RDB$FOREIGN_KEY, RDB$SYSTEM_FLAG, RDB$EXPRESSION_SOURCE, RDB$STATISTICS from RDB$INDICES""") - self.__indices = ObjectList((Index(self, row) for row in self._ic.itermap()), - Index, 'item.name') - self.__indices.freeze() + sys_indices, user_indices = ObjectList((Index(self, row) for row in self._ic.itermap()), + Index, 'item.name').split(lambda item: + item.issystemobject()) + sys_indices.freeze() + user_indices.freeze() + self.__indices = (user_indices, sys_indices) return self.__indices def _get_indices(self): - return self._get_all_indices().filter(lambda item: not item.issystemobject()) + return self._get_all_indices()[0] def _get_sysindices(self): - return self._get_all_indices().filter(lambda item: item.issystemobject()) + return self._get_all_indices()[1] def _get_all_generators(self): if self.__generators is None: self.__fail_if_closed() @@ -703,14 +718,17 @@ cols.extend(['RDB$SECURITY_CLASS', 'RDB$OWNER_NAME', 'RDB$INITIAL_VALUE', 'RDB$GENERATOR_INCREMENT']) self._ic.execute("select %s from rdb$generators" % ','.join(cols)) - self.__generators = ObjectList((Sequence(self, row) for row in self._ic.itermap()), - Sequence, 'item.name') - self.__generators.freeze() + sys_generators, user_generators = ObjectList((Sequence(self, row) for row in self._ic.itermap()), + Sequence, 'item.name').split(lambda item: + item.issystemobject()) + sys_generators.freeze() + user_generators.freeze() + self.__generators = (user_generators, sys_generators) return self.__generators def _get_generators(self): - return self._get_all_generators().filter(lambda item: not item.issystemobject()) + return self._get_all_generators()[0] def _get_sysgenerators(self): - return self._get_all_generators().filter(lambda item: item.issystemobject()) + return self._get_all_generators()[1] def _get_all_triggers(self): if self.__triggers is None: self.__fail_if_closed() @@ -720,14 +738,17 @@ if self._con.ods >= fdb.ODS_FB_30: cols.extend(['RDB$VALID_BLR', 'RDB$ENGINE_NAME', 'RDB$ENTRYPOINT']) self._ic.execute("select %s from RDB$TRIGGERS" % ','.join(cols)) - self.__triggers = ObjectList((Trigger(self, row) for row in self._ic.itermap()), - Trigger, 'item.name') - self.__triggers.freeze() + sys_triggers, user_triggers = ObjectList((Trigger(self, row) for row in self._ic.itermap()), + Trigger, 'item.name').split(lambda item: + item.issystemobject()) + sys_triggers.freeze() + user_triggers.freeze() + self.__triggers = (user_triggers, sys_triggers) return self.__triggers def _get_triggers(self): - return self._get_all_triggers().filter(lambda item: not item.issystemobject()) + return self._get_all_triggers()[0] def _get_systriggers(self): - return self._get_all_triggers().filter(lambda item: item.issystemobject()) + return self._get_all_triggers()[1] def _get_all_procedures(self): if self.__procedures is None: self.__fail_if_closed() @@ -740,14 +761,17 @@ cols.extend(['RDB$ENGINE_NAME', 'RDB$ENTRYPOINT', 'RDB$PACKAGE_NAME', 'RDB$PRIVATE_FLAG']) self._ic.execute("select %s from rdb$procedures" % ','.join(cols)) - self.__procedures = ObjectList((Procedure(self, row) for row in self._ic.itermap()), - Procedure, 'item.name') - self.__procedures.freeze() + sys_procedures, user_procedures = ObjectList((Procedure(self, row) for row in self._ic.itermap()), + Procedure, 'item.name').split(lambda item: + item.issystemobject()) + sys_procedures.freeze() + user_procedures.freeze() + self.__procedures = (user_procedures, sys_procedures) return self.__procedures def _get_procedures(self): - return self._get_all_procedures().filter(lambda item: not item.issystemobject()) + return self._get_all_procedures()[0] def _get_sysprocedures(self): - return self._get_all_procedures().filter(lambda item: item.issystemobject()) + return self._get_all_procedures()[1] def _get_constraints(self): if self.__constraints is None: self.__fail_if_closed() @@ -805,14 +829,17 @@ 'RDB$SECURITY_CLASS', 'RDB$OWNER_NAME', 'RDB$LEGACY_FLAG', 'RDB$DETERMINISTIC_FLAG']) self._ic.execute("select %s from rdb$functions" % ','.join(cols)) - self.__functions = ObjectList((Function(self, row) for row in self._ic.itermap()), - Function, 'item.name') - self.__functions.freeze() + sys_functions, user_functions = ObjectList((Function(self, row) for row in self._ic.itermap()), + Function, 'item.name').split(lambda item: + item.issystemobject()) + sys_functions.freeze() + user_functions.freeze() + self.__functions = (user_functions, sys_functions) return self.__functions def _get_functions(self): - return self._get_all_functions().filter(lambda item: not item.issystemobject()) + return self._get_all_functions()[0] def _get_sysfunctions(self): - return self._get_all_functions().filter(lambda item: item.issystemobject()) + return self._get_all_functions()[1] def _get_files(self): if self.__files is None: self.__fail_if_closed() @@ -931,10 +958,11 @@ def bind(self, connection): """Bind this instance to specified :class:`~fdb.Connection`. - :param connection: :class:`~fdb.Connection` instance. + Args: + connection: :class:`~fdb.Connection` instance. - :raises `~fdb.ProgrammingError`: If Schema object was set as internal (via - :meth:`_set_as_internal`). + Raises: + fdb.ProgrammingError: If Schema object was set as internal (via :meth:`_set_as_internal`). """ if self.__internal: raise fdb.ProgrammingError("Call to 'bind' not allowed for embedded Schema.") @@ -1012,8 +1040,9 @@ def close(self): """Sever link to :class:`~fdb.Connection`. - :raises `~fdb.ProgrammingError`: If Schema object was set as internal (via - :meth:`_set_as_internal`). + Raises: + fdb.ProgrammingError: If Schema object was set as internal (via + :meth:`_set_as_internal`). """ if self.__internal: raise fdb.ProgrammingError("Call to 'close' not allowed for embedded Schema.") @@ -1029,13 +1058,16 @@ """Drop all or specified category of cached metadata objects, so they're reloaded from database on next reference. - :param string data: `None`, metadata category code or iterable with category codes. + Keyword Args: + data: `None`, metadata category code or iterable with category codes. - .. note:: Category codes are defined by `SCHEMA_*` globals. + Note: + Category codes are defined by `SCHEMA_*` globals. - :raises fdb.ProgrammingError: For undefined metadata category. + Also commits query transaction! - .. note:: Also commits query transaction. + Raises: + fdb.ProgrammingError: For undefined metadata category. """ self.__clear(data) if not self.closed: @@ -1044,9 +1076,11 @@ def get_metadata_ddl(self, sections=SCRIPT_DEFAULT_ORDER): """Return list of DDL SQL commands for creation of specified categories of database objects. - :param list sections: List of section identifiers. + Keyword Args: + sections (list): List of section identifiers. - :returns: List with SQL commands. + Returns: + List with SQL commands. Sections identifiers are represented by `SCRIPT_*` contants defined in schema module. @@ -1203,115 +1237,167 @@ def get_collation(self, name): """Get :class:`Collation` by name. - :param string name: Collation name. + Args: + name (str): Collation name. - :returns: :class:`Collation` with specified name or `None`. + Returns: + :class:`Collation` with specified name or `None`. """ return self.collations.get(name) def get_character_set(self, name): """Get :class:`CharacterSet` by name. - :param string name: Character set name. + Args: + name (str): Character set name. - :returns: :class:`CharacterSet` with specified name or `None`. + Returns: + :class:`CharacterSet` with specified name or `None`. """ return self.character_sets.get(name) def get_exception(self, name): """Get :class:`DatabaseException` by name. - :param string name: Exception name. + Args: + name (str): Exception name. - :returns: :class:`DatabaseException` with specified name or `None`. + Returns: + :class:`DatabaseException` with specified name or `None`. """ return self.exceptions.get(name) def get_generator(self, name): """Get :class:`Sequence` by name. - :param string name: Sequence name. + Args: + name (str): Sequence name. - :returns: :class:`Sequence` with specified name or `None`. + Returns: + :class:`Sequence` with specified name or `None`. """ - return self._get_all_generators().get(name) + generator = self.generators.get(name) + if generator is None: + generator = self.sysgenerators.get(name) + return generator get_sequence = get_generator def get_index(self, name): """Get :class:`Index` by name. - :param string name: Index name. + Args: + name (str): Index name. - :returns: :class:`Index` with specified name or `None`. + Returns: + :class:`Index` with specified name or `None`. """ - return self._get_all_indices().get(name) + index = self.indices.get(name) + if index is None: + index = self.sysindices.get(name) + return index def get_domain(self, name): """Get :class:`Domain` by name. - :param string name: Domain name. + Args: + name (str): Domain name. - :returns: :class:`Domain` with specified name or `None`. + Returns: + :class:`Domain` with specified name or `None`. """ - return self._get_all_domains().get(name) + domain = self.domains.get(name) + if domain is None: + domain = self.sysdomains.get(name) + return domain def get_table(self, name): """Get :class:`Table` by name. - :param string name: Table name. + Args: + name (str): Table name. - :returns: :class:`Table` with specified name or `None`. + Returns: + :class:`Table` with specified name or `None`. """ - return self._get_all_tables().get(name) + table = self.tables.get(name) + if table is None: + table = self.systables.get(name) + return table def get_view(self, name): """Get :class:`View` by name. - :param string name: View name. + Args: + name (str): View name. - :returns: :class:`View` with specified name or `None`. + Returns: + :class:`View` with specified name or `None`. """ - return self._get_all_views().get(name) + view = self.views.get(name) + if view is None: + view = self.sysviews.get(name) + return view def get_trigger(self, name): """Get :class:`Trigger` by name. - :param string name: Trigger name. + Args: + name (str): Trigger name. - :returns: :class:`Trigger` with specified name or `None`. + Returns: + :class:`Trigger` with specified name or `None`. """ - return self._get_all_triggers().get(name) + trigger = self.triggers.get(name) + if trigger is None: + trigger = self.systriggers.get(name) + return trigger def get_procedure(self, name): """Get :class:`Procedure` by name. - :param string name: Procedure name. + Args: + name (str): Procedure name. - :returns: :class:`Procedure` with specified name or `None`. + Returns: + :class:`Procedure` with specified name or `None`. """ - return self._get_all_procedures().get(name) + procedure = self.procedures.get(name) + if procedure is None: + procedure = self.sysprocedures.get(name) + return procedure def get_constraint(self, name): """Get :class:`Constraint` by name. - :param string name: Constraint name. + Args: + name (str): Constraint name. - :returns: :class:`Constraint` with specified name or `None`. + Returns: + :class:`Constraint` with specified name or `None`. """ return self.constraints.get(name) def get_role(self, name): """Get :class:`Role` by name. - :param string name: Role name. + Args: + name (str): Role name. - :returns: :class:`Role` with specified name or `None`. + Returns: + :class:`Role` with specified name or `None`. """ return self.roles.get(name) def get_function(self, name): """Get :class:`Function` by name. - :param string name: Function name. + Args: + name (str): Function name. - :returns: :class:`Function` with specified name or `None`. + Returns: + :class:`Function` with specified name or `None`. """ - return self._get_all_functions().get(name) + function = self.functions.get(name) + if function is None: + function = self.sysfunctions.get(name) + return function def get_collation_by_id(self, charset_id, collation_id): """Get :class:`Collation` by ID. - :param integer charset_id: Character set ID. - :param integer collation_id: Collation ID. + Args: + charset_id (int): Character set ID. + collation_id (int): Collation ID. - :returns: :class:`Collation` with specified ID or `None`. + Returns: + :class:`Collation` with specified ID or `None`. """ for collation in self.collations: if (collation._attributes['RDB$CHARACTER_SET_ID'] == charset_id) and (collation.id == collation_id): @@ -1321,9 +1407,11 @@ def get_character_set_by_id(self, id): """Get :class:`CharacterSet` by ID. - :param integer name: CharacterSet ID. + Args: + id (int): CharacterSet ID. - :returns: :class:`CharacterSet` with specified ID or `None`. + Returns: + :class:`CharacterSet` with specified ID or `None`. """ for charset in self.character_sets: if charset.id == id: @@ -1333,14 +1421,20 @@ def get_privileges_of(self, user, user_type=None): """Get list of all privileges granted to user/database object. - :param user: User name or instance of class that represents possible user. - Allowed classes are :class:`~fdb.services.User`, :class:`Table`, - :class:`View`, :class:`Procedure`, :class:`Trigger` or :class:`Role`. - :param int user_type: **Required if** `user` is provided as string name. - Numeric code for user type, see :attr:`Schema.enum_object_types`. - :returns: List of :class:`Privilege` objects. + Args: + user: User name or instance of class that represents possible user. + Allowed classes are :class:`~fdb.services.User`, :class:`Table`, + :class:`View`, :class:`Procedure`, :class:`Trigger` or :class:`Role`. + + Keyword Args: + user_type (int): **Required if** `user` is provided as string name. + Numeric code for user type, see :attr:`Schema.enum_object_types`. + + Returns: + List of :class:`Privilege` objects. - :raises `~fdb.ProgrammingError`: For unknown `user_type` code. + Raises: + fdb.ProgrammingError: For unknown `user_type` code. """ if isinstance(user, (fdb.StringType, fdb.UnicodeType)): if (user_type is None) or (user_type not in self.enum_object_types): @@ -1359,9 +1453,11 @@ def get_package(self, name): """Get :class:`Package` by name. - :param string name: Package name. + Args: + name (str): Package name. - :returns: :class:`Package` with specified name or `None`. + Returns: + :class:`Package` with specified name or `None`. """ return self.packages.get(name) @@ -1436,7 +1532,8 @@ Supported actions are defined by :attr:`actions` list. - :raises `~fdb.ProgrammingError`: For unsupported action or wrong parameters passed. + Raises: + fdb.ProgrammingError: For unsupported action or wrong parameters passed. """ _action = action.lower() if _action in self._actions: @@ -1449,9 +1546,8 @@ """Represents collation. Supported SQL actions: - - - User collation: create, drop, comment - - System collation: comment + - User collation: `create`, `drop`, `comment` + - System collation: `comment` """ def __init__(self, schema, attributes): super(Collation, self).__init__(schema, attributes) @@ -1542,7 +1638,8 @@ class CharacterSet(BaseSchemaItem): """Represents character set. - Supported SQL actions: alter(collation=Collation instance or collation name), comment + Supported SQL actions: + `alter` (collation=Collation instance or collation name), `comment` """ def __init__(self, schema, attributes): super(CharacterSet, self).__init__(schema, attributes) @@ -1612,9 +1709,8 @@ """Represents database exception. Supported SQL actions: - - - User exception: create, recreate, alter(message=string), create_or_alter, drop, comment - - System exception: comment + - User exception: `create`, `recreate`, `alter` (message=string), `create_or_alter`, `drop`, `comment` + - System exception: `comment` """ def __init__(self, schema, attributes): super(DatabaseException, self).__init__(schema, attributes) @@ -1671,9 +1767,8 @@ """Represents database generator/sequence. Supported SQL actions: - - - User sequence: create, alter(value=number), drop, comment - - System sequence: comment + - User sequence: `create`, `alter` (value=number), `drop`, `comment` + - System sequence: `comment` """ def __init__(self, schema, attributes): super(Sequence, self).__init__(schema, attributes) @@ -1742,10 +1837,10 @@ """Represents table column. Supported SQL actions: - - - User column: alter(name=string,datatype=string_SQLTypeDef,position=number, - expression=computed_by_expr,restart=None_or_init_value), drop, comment - - System column: comment + - User column: `drop`, `comment`, + `alter` (name=string, datatype=string_SQLTypeDef, position=number, + expression=computed_by_expr, restart=None_or_init_value) + - System column: `comment` """ def __init__(self, schema, table, attributes): super(TableColumn, self).__init__(schema, attributes) @@ -1887,9 +1982,8 @@ """Represents database index. Supported SQL actions: - - - User index: create, activate, deactivate, recompute, drop, comment - - System index: activate, recompute, comment + - User index: `create`, `activate`, `deactivate`, `recompute`, `drop`, `comment` + - System index: `activate`, `recompute`, `comment` """ def __init__(self, schema, attributes): super(Index, self).__init__(schema, attributes) @@ -2006,7 +2100,8 @@ class ViewColumn(BaseSchemaItem): """Represents view column. - Supported SQL actions: comment + Supported SQL actions: + `comment` """ def __init__(self, schema, view, attributes): super(ViewColumn, self).__init__(schema, attributes) @@ -2096,10 +2191,10 @@ """Represents SQl Domain. Supported SQL actions: - - - User domain: create, alter(name=string,default=string_definition_or_None, - check=string_definition_or_None,datatype=string_SQLTypeDef), drop, comment - - System domain: comment + - User domain: `create`, `drop`, `comment`, + `alter` (name=string, default=string_definition_or_None, + check=string_definition_or_None, datatype=string_SQLTypeDef) + - System domain: `comment` """ def __init__(self, schema, attributes): super(Domain, self).__init__(schema, attributes) @@ -2284,7 +2379,8 @@ class Dependency(BaseSchemaItem): """Maps dependency between database objects. - Supported SQL actions: none + Supported SQL actions: + `none` """ def __init__(self, schema, attributes): super(Dependency, self).__init__(schema, attributes) @@ -2430,9 +2526,8 @@ """Represents table or column constraint. Supported SQL actions: - - - Constraint on user table except NOT NULL constraint: create, drop - - Constraint on system table: none + - Constraint on user table except NOT NULL constraint: `create`, `drop` + - Constraint on system table: `none` """ def __init__(self, schema, attributes): super(Constraint, self).__init__(schema, attributes) @@ -2555,11 +2650,10 @@ """Represents Table in database. Supported SQL actions: - - - User table: create (no_pk=bool,no_unique=bool), - recreate (no_pk=bool,no_unique=bool), - drop, comment - - System table: comment + - User table: `create` (no_pk=bool, no_unique=bool), + `recreate` (no_pk=bool, no_unique=bool), + `drop`, `comment` + - System table: `comment` """ def __init__(self, schema, attributes): super(Table, self).__init__(schema, attributes) @@ -2674,7 +2768,10 @@ def _get_flags(self): return self._attributes['RDB$FLAGS'] def _get_indices(self): - return self.schema._get_all_indices().filter(lambda i: i._attributes['RDB$RELATION_NAME'] == self.name) + user_indices, sys_indices = self.schema._get_all_indices() + result = user_indices.filter(lambda i: i._attributes['RDB$RELATION_NAME'] == self.name) + result.extend(sys_indices.filter(lambda i: i._attributes['RDB$RELATION_NAME'] == self.name)) + return result def _get_triggers(self): return self.schema.triggers.filter(lambda t: t._attributes['RDB$RELATION_NAME'] == self.name) def _get_constraints(self): @@ -2754,10 +2851,9 @@ """Represents database View. Supported SQL actions: - - - User views: create, recreate, alter(columns=string_or_list,query=string,check=bool), - create_or_alter, drop, comment - - System views: comment + - User views: `create`, `recreate`, `alter` (columns=string_or_list, query=string,check=bool), + `create_or_alter`, `drop`, `comment` + - System views: `comment` """ def __init__(self, schema, attributes): super(View, self).__init__(schema, attributes) @@ -2874,11 +2970,9 @@ """Represents trigger. Supported SQL actions: - - - User trigger: create(inactive=bool), recreate, create_or_alter, drop, - alter(fire_on=string,active=bool,sequence=int,declare=string_or_list, - code=string_or_list), comment - - System trigger: comment + - User trigger: `create` (inactive=bool), `recreate`, `create_or_alter`, `drop`, `comment`, + `alter` (fire_on=string, active=bool,sequence=int, declare=string_or_list, code=string_or_list) + - System trigger: `comment` """ def __init__(self, schema, attributes): super(Trigger, self).__init__(schema, attributes) @@ -3057,7 +3151,8 @@ class ProcedureParameter(BaseSchemaItem): """Represents procedure parameter. - Supported SQL actions: comment + Supported SQL actions: + `comment` """ def __init__(self, schema, proc, attributes): super(ProcedureParameter, self).__init__(schema, attributes) @@ -3172,12 +3267,10 @@ """Represents stored procedure. Supported SQL actions: - - - User procedure: create(no_code=bool), recreate(no_code=bool), - create_or_alter(no_code=bool), drop, - alter(input=string_or_list,output=string_or_list,declare=string_or_list, - code=string_or_list), comment - - System procedure: comment + - User procedure: `create` (no_code=bool), `recreate` no_code=bool), + `create_or_alter` (no_code=bool), `drop`, `comment` + `alter` (input=string_or_list, output=string_or_list, declare=string_or_list, code=string_or_list) + - System procedure: `comment` """ def __init__(self, schema, attributes): super(Procedure, self).__init__(schema, attributes) @@ -3400,9 +3493,8 @@ """Represents user role. Supported SQL actions: - - - User role: create, drop, comment - - System role: comment + - User role: `create`, `drop`, `comment` + - System role: `comment` """ def __init__(self, schema, attributes): super(Role, self).__init__(schema, attributes) @@ -3445,7 +3537,8 @@ class FunctionArgument(BaseSchemaItem): """Represets UDF argument. - Supported SQL actions: none. + Supported SQL actions: + `none` """ def __init__(self, schema, function, attributes): super(FunctionArgument, self).__init__(schema, attributes) @@ -3645,13 +3738,11 @@ """Represents user defined function. Supported SQL actions: - - - External UDF: declare, drop, comment - - PSQL UDF (FB 3, not declared in package): create(no_code=bool), - recreate(no_code=bool), create_or_alter(no_code=bool), drop, - alter(arguments=string_or_list,returns=string,declare=string_or_list, - code=string_or_list) - - System UDF: none + - External UDF: `declare`, `drop`, `comment` + - PSQL UDF (FB 3, not declared in package): `create` (no_code=bool), + `recreate` (no_code=bool), `create_or_alter` (no_code=bool), `drop`, + `alter` (arguments=string_or_list, returns=string, declare=string_or_list, code=string_or_list) + - System UDF: `none` """ def __init__(self, schema, attributes): super(Function, self).__init__(schema, attributes) @@ -3862,7 +3953,8 @@ class DatabaseFile(BaseSchemaItem): """Represents database extension file. - Supported SQL actions: create + Supported SQL actions: + `create` """ def __init__(self, schema, attributes): super(DatabaseFile, self).__init__(schema, attributes) @@ -3895,7 +3987,8 @@ class Shadow(BaseSchemaItem): """Represents database shadow. - Supported SQL actions: create, drop(preserve=bool) + Supported SQL actions: + `create`, `drop` (preserve=bool) """ SHADOW_INACTIVE = 2 SHADOW_MANUAL = 4 @@ -3969,7 +4062,8 @@ class Privilege(BaseSchemaItem): """Represents priviledge to database object. - Supported SQL actions: grant(grantors),revoke(grantors,grant_option) + Supported SQL actions: + `grant` (grantors), `revoke` (grantors, grant_option) """ def __init__(self, schema, attributes): super(Privilege, self).__init__(schema, attributes) @@ -4119,8 +4213,9 @@ class Package(BaseSchemaItem): """Represents PSQL package. - Supported SQL actions: create(body=bool), recreate(body=bool), create_or_alter(body=bool), - alter(header=string_or_list), drop(body=bool), alter + Supported SQL actions: + `create` (body=bool), `recreate` (body=bool), `create_or_alter` (body=bool), + `alter` (header=string_or_list), `drop` (body=bool) """ def __init__(self, schema, attributes): super(Package, self).__init__(schema, attributes) @@ -4185,10 +4280,10 @@ return bool(result) if result is not None else None class BackupHistory(BaseSchemaItem): - """Represents entry of history for backups performed -using the nBackup utility. + """Represents entry of history for backups performed using the nBackup utility. - Supported SQL actions: None + Supported SQL actions: + `None` """ def __init__(self, schema, attributes): super(BackupHistory, self).__init__(schema, attributes) @@ -4229,9 +4324,8 @@ """Represents userdefined BLOB filter. Supported SQL actions: - - - BLOB filter: declare, drop, comment - - System UDF: none + - BLOB filter: `declare`, `drop`, `comment` + - System UDF: `none` """ def __init__(self, schema, attributes): super(Filter, self).__init__(schema, attributes) diff -Nru fdb-2.0.0/fdb/services.py fdb-2.0.1/fdb/services.py --- fdb-2.0.0/fdb/services.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/services.py 2018-05-03 11:42:34.000000000 +0000 @@ -156,25 +156,22 @@ def connect(host='service_mgr', user=None, password=None): """Establishes a connection to the Services Manager. - :param string host: (optional) Host machine specification. Local by default. - :param string user: (optional) Administrative user name. Defaults to content - of environment variable `'ISC_USER'` or `'SYSDBA'`. - :param string password: Administrative user password. Default is content - of environment variable `'ISC_PASSWORD'`. - - - .. note:: + Args: + host (str): (optional) Host machine specification. Local by default. + user (str): (optional) Administrative user name. Defaults to content + of environment variable `ISC_USER` or `SYSDBA`. + password (str): Administrative user password. Default is content + of environment variable `ISC_PASSWORD`. + Note: By definition, a Services Manager connection is bound to a particular host. Therefore, the database specified as a parameter to methods such as `getStatistics` MUST NOT include the host name of the database server. - **Hooks:** - - Event `HOOK_SERVICE_ATTACHED`: Executed before :class:`Connection` - instance is returned. Hook must have signature: - hook_func(connection). Any value returned by hook is ignored. - + Hooks: + Event `HOOK_SERVICE_ATTACHED`: Executed before :class:`Connection` + instance is returned. Hook must have signature: + hook_func(connection). Any value returned by hook is ignored. """ setattr(sys.modules[__name__], 'api', fdb.load_api()) if not user: @@ -280,7 +277,8 @@ """Return the next result line from service manager. Part of *iterator protocol*. - :raises StopIteration: If there are no further lines. + Raises: + StopIteration: If there are no further lines. """ line = self.readline() if line is not None: @@ -547,7 +545,8 @@ def readline(self): """Get next line of textual output from last service query. - :returns string: Output line. + Returns: + str: Output line. """ if self.__fetching: return self.__fetchline() @@ -556,15 +555,17 @@ def readlines(self): """Get list of remaining output lines from last service query. - :returns list: Service output. - :raises `~fdb.ProgrammingError`: When service is not in :attr:`fetching` mode. + Returns: + list: Service output. + + Raises: + fdb.ProgrammingError: When service is not in :attr:`fetching` mode. """ return [line for line in self] def isrunning(self): """Returns True if service is running. - .. note:: - + Note: Some services like :meth:`backup` or :meth:`sweep` may take time to comlete, so they're called asynchronously. Until they're finished, no other async service could be started. @@ -579,52 +580,58 @@ def get_service_manager_version(self): """Get Firebird Service Manager version number. - :returns integer: Version number. + Returns: + int: Version number. """ self.__check_active() return self._QI(ibase.isc_info_svc_version) def get_server_version(self): """Get Firebird version. - :returns string: Firebird version (example: 'LI-V2.5.2.26536 Firebird 2.5'). + Returns: + str: Firebird version (example: 'LI-V2.5.2.26536 Firebird 2.5'). """ self.__check_active() return self._QS(ibase.isc_info_svc_server_version) def get_architecture(self): """Get Firebird Server architecture. - :returns string: Architecture (example: 'Firebird/linux AMD64'). + Returns: + str: Architecture (example: 'Firebird/linux AMD64'). """ self.__check_active() return self._QS(ibase.isc_info_svc_implementation) def get_home_directory(self): """Get Firebird Home (installation) Directory. - :returns string: Directory path. + Returns: + str: Directory path. """ self.__check_active() return self._QS(ibase.isc_info_svc_get_env) def get_security_database_path(self): """Get full path to Firebird security database. - :returns string: Path (path+filename) to security database. + Returns: + str: Path (path+filename) to security database. """ self.__check_active() return self._QS(ibase.isc_info_svc_user_dbpath) def get_lock_file_directory(self): """Get directory location for Firebird lock files. - :returns string: Directory path. + Returns: + str: Directory path. """ self.__check_active() return self._QS(ibase.isc_info_svc_get_env_lock) def get_server_capabilities(self): """Get list of Firebird capabilities. - :returns tuple: Capability info codes for each capability reported by - server. + Returns: + tuple: Capability info codes for each capability reported by server. - Next fdb.services constants define possible info codes returned:: + Next `fdb.services` constants define possible info codes returned:: CAPABILITY_MULTI_CLIENT CAPABILITY_REMOTE_HOP @@ -632,10 +639,11 @@ CAPABILITY_QUOTED_FILENAME CAPABILITY_NO_SERVER_SHUTDOWN - **Example**:: + Example: + .. code-block:: python - >>>fdb.services.CAPABILITY_REMOTE_HOP in svc.get_server_capabilities() - True + >>>fdb.services.CAPABILITY_REMOTE_HOP in svc.get_server_capabilities() + True """ self.__check_active() capabilities = self._QI(ibase.isc_info_svc_capabilities) @@ -648,36 +656,39 @@ def get_message_file_directory(self): """Get directory with Firebird message file. - :returns string: Directory path. + Returns: + str: Directory path. """ self.__check_active() return self._QS(ibase.isc_info_svc_get_env_msg) def get_connection_count(self): """Get number of attachments to server. - :returns integer: Number of attachments. + Returns: + int: Number of attachments. """ self.__check_active() return self._get_isc_info_svc_svr_db_info()[0] def get_attached_database_names(self): """Get list of attached databases. - :returns list: Filenames of attached databases. + Returns: + list: Filenames of attached databases. """ self.__check_active() return self._get_isc_info_svc_svr_db_info()[1] def get_log(self, callback=None): """Request content of Firebird Server log. **(ASYNC service)** - :param function callback: Function to call back with each output line. - Function must accept only one parameter: line of output. + Keyword Args: + callback (callable): Function to call back with each output line. + Function must accept only one parameter: line of output. If `callback` is not specified, log content could be retrieved through :meth:`readline`, :meth:`readlines`, iteration over `Connection` or ignored via call to :meth:`wait`. - .. note:: - + Note: Until log content is not fully fetched from service (or ignored via :meth:`wait`), any attempt to start another asynchronous service will fail with exception. @@ -692,9 +703,14 @@ def get_limbo_transaction_ids(self, database): """Get list of transactions in limbo. - :param string database: Database filename or alias. - :returns list: Transaction IDs. - :raises `~fdb.InternalError`: When can't process the result buffer. + Args: + database (str): Database filename or alias. + + Returns: + list: Transaction IDs. + + Raises: + fdb.InternalError: When can't process the result buffer. """ self.__check_active() _check_string(database) @@ -729,8 +745,9 @@ def commit_limbo_transaction(self, database, transaction_id): """Resolve limbo transaction with commit. - :param string database: Database filename or alias. - :param integer transaction_id: ID of Transaction to resolve. + Args: + database (str): Database filename or alias. + transaction_id (int): ID of Transaction to resolve. """ self.__check_active() self._resolve_limbo_transaction(ibase.isc_spb_rpr_commit_trans, @@ -738,8 +755,9 @@ def rollback_limbo_transaction(self, database, transaction_id): """Resolve limbo transaction with rollback. - :param string database: Database filename or alias. - :param integer transaction_id: ID of Transaction to resolve. + Args: + database (str): Database filename or alias. + transaction_id (int): ID of Transaction to resolve. """ self.__check_active() self._resolve_limbo_transaction(ibase.isc_spb_rpr_rollback_trans, @@ -750,25 +768,27 @@ show_record_versions=0, callback=None, tables=None): """Request database statisctics. **(ASYNC service)** - :param string database: Database specification. - :param integer show_only_db_log_pages: `1` to analyze only log pages. - :param integer show_only_db_header_pages: `1` to analyze only database - header. When set, all other parameters are ignored. - :param integer show_user_data_pages: `0` to skip user data analysis. - :param integer show_user_index_pages: `0` to skip user index analysis. - :param integer show_system_tables_and_indexes: `1` to analyze system - tables and indices. - :param integer show_record_versions: `1` to analyze record versions. - :param function callback: Function to call back with each output line. - Function must accept only one parameter: line of output. - :param string_or_list tables: table name or iterable of table names. + Args: + database (str): Database specification. + + Keyword Args: + show_only_db_log_pages (int): `1` to analyze only log pages. + show_only_db_header_pages (int): `1` to analyze only database + header. When set, all other parameters are ignored. + show_user_data_pages (int): `0` to skip user data analysis. + show_user_index_pages (int): `0` to skip user index analysis. + show_system_tables_and_indexes (int): `1` to analyze system + tables and indices. + show_record_versions (int): `1` to analyze record versions. + callback (callable): Function to call back with each output line. + Function must accept only one parameter: line of output. + tables (str or list): table name or iterable of table names. If `callback` is not specified, statistical report could be retrieved through :meth:`readline`, :meth:`readlines`, iteration over `Connection` or ignored via call to :meth:`wait`. - .. note:: - + Note: Until report is not fully fetched from service (or ignored via :meth:`wait`), any attempt to start another asynchronous service will fail with exception. @@ -830,30 +850,29 @@ stats=None): """Request logical (GBAK) database backup. **(ASYNC service)** - :param string source_database: Source database specification. - :param dest_filenames: Backup file(s) specification. - :type dest_filenames: string or tuple of strings - :param dest_file_sizes: (optional) specification of backup file max. sizes. - :type dest_file_sizes: tuple of integers - :param integer ignore_checksums: `1` to ignore checksums. - :param integer ignore_limbo_transactions: `1` to ignore limbo transactions. - :param integer metadata_only: `1` to create only metadata backup. - :param integer collect_garbage: `0` to skip garbage collection. - :param integer transportable: `0` to do not create transportable backup. - :param integer convert_external_tables: `1` to convert - external table to internal ones. - :param integer compressed: `0` to create uncompressed backup. - :param integer no_db_triggers: `1` to disable database triggers temporarily. - :param function callback: Function to call back with each output line. - Function must accept only one parameter: line of output. - :param list stats: List of arguments for run-time statistics, see STATS_* constants. + Args: + source_database (str): Source database specification. + dest_filenames (str or tuple(str)): Backup file(s) specification. + + Keyword Args: + dest_file_sizes (tuple(int)): Specification of backup file max. sizes. + ignore_checksums (int): `1` to ignore checksums. + ignore_limbo_transactions (int): `1` to ignore limbo transactions. + metadata_only (int): `1` to create only metadata backup. + collect_garbage (int): `0` to skip garbage collection. + transportable (int): `0` to do not create transportable backup. + convert_external_tables (int): `1` to convert external table to internal ones. + compressed (int): `0` to create uncompressed backup. + no_db_triggers (int): `1` to disable database triggers temporarily. + callback (callable): Function to call back with each output line. + Function must accept only one parameter: line of output. + stats (list): List of arguments for run-time statistics, see STATS_* constants. If `callback` is not specified, backup log could be retrieved through :meth:`readline`, :meth:`readlines`, iteration over `Connection` or ignored via call to :meth:`wait`. - .. note:: - + Note: Until backup report is not fully fetched from service (or ignored via :meth:`wait`), any attempt to start another asynchronous service will fail with exception. @@ -941,17 +960,19 @@ no_db_triggers=0): """Request logical (GBAK) database backup into local byte stream. **(SYNC service)** - :param string source_database: Source database specification. - :param backup_stream: Backup stream. - :param integer ignore_checksums: `1` to ignore checksums. - :param integer ignore_limbo_transactions: `1` to ignore limbo transactions. - :param integer metadata_only: `1` to create only metadata backup. - :param integer collect_garbage: `0` to skip garbage collection. - :param integer transportable: `0` to do not create transportable backup. - :param integer convert_external_tables: `1` to convert - external table to internal ones. - :param integer compressed: `0` to create uncompressed backup. - :param integer no_db_triggers: `1` to disable database triggers temporarily. + Args: + source_database (str): Source database specification. + backup_stream (stream): Backup stream. + + Keyword Args: + ignore_checksums (int): `1` to ignore checksums. + ignore_limbo_transactions (int): `1` to ignore limbo transactions. + metadata_only (int): `1` to create only metadata backup. + collect_garbage (int): `0` to skip garbage collection. + transportable (int): `0` to do not create transportable backup. + convert_external_tables (int): `1` to convert external table to internal ones. + compressed (int): `0` to create uncompressed backup. + no_db_triggers (int): `1` to disable database triggers temporarily. """ self.__check_active() # Begin parameter validation section. @@ -1024,37 +1045,32 @@ stats=None): """Request database restore from logical (GBAK) backup. **(ASYNC service)** - :param source_filenames: Backup file(s) specification. - :type source_filenames: string or tuple of strings - :param dest_filenames: Database file(s) specification. - :type dest_filenames: string or tuple of strings - :param dest_file_pages: (optional) specification of database file max. - # of pages. - :type dest_file_pages: tuple of integers - :param integer page_size: (optional) Page size. - :param integer cache_buffers: (optional) Size of page-cache for this - database. - :param integer access_mode_read_only: `1` to create R/O database. - :param integer replace: `1` to replace existing database. - :param integer deactivate_indexes: `1` to do not activate indices. - :param integer do_not_restore_shadows: `1` to do not restore shadows. - :param integer do_not_enforce_constraints: `1` to do not enforce - constraints during restore. - :param integer commit_after_each_table: `1` to commit after each table - is restored. - :param integer use_all_page_space: `1` to use all space on data pages. - :param integer no_db_triggers: `1` to disable database triggers temporarily. - :param integer metadata_only: `1` to restore only database metadata. - :param function callback: Function to call back with each output line. - Function must accept only one parameter: line of output. - :param list stats: List of arguments for run-time statistics, see STATS_* constants. + Args: + source_filenames (str or tuple(str)): Backup file(s) specification. + dest_filenames (str or tuple(str)): Database file(s) specification. + + Keyword Args: + dest_file_pages (tuple(int)): Specification of database file max. # of pages. + page_size (int): Page size. + cache_buffers (int): Size of page-cache for this database. + access_mode_read_only (int): `1` to create R/O database. + replace (int): `1` to replace existing database. + deactivate_indexes (int): `1` to do not activate indices. + do_not_restore_shadows (int): `1` to do not restore shadows. + do_not_enforce_constraints (int): `1` to do not enforce constraints during restore. + commit_after_each_table (int): `1` to commit after each table is restored. + use_all_page_space (int): `1` to use all space on data pages. + no_db_triggers (int): `1` to disable database triggers temporarily. + metadata_only (int): `1` to restore only database metadata. + callback (callable): Function to call back with each output line. + Function must accept only one parameter: line of output. + stats (list): List of arguments for run-time statistics, see STATS_* constants. If `callback` is not specified, restore log could be retrieved through :meth:`readline`, :meth:`readlines`, iteration over `Connection` or ignored via call to :meth:`wait`. - .. note:: - + Note: Until restore report is not fully fetched from service (or ignored via :meth:`wait`), any attempt to start another asynchronous service will fail with exception. @@ -1142,26 +1158,23 @@ metadata_only=0): """Request database restore from logical (GBAK) backup stored in local byte stream. **(SYNC service)** - :param backup_stream: Backup stream. - :param dest_filenames: Database file(s) specification. - :type dest_filenames: string or tuple of strings - :param dest_file_pages: (optional) specification of database file max. - # of pages. - :type dest_file_pages: tuple of integers - :param integer page_size: (optional) Page size. - :param integer cache_buffers: (optional) Size of page-cache for this - database. - :param integer access_mode_read_only: `1` to create R/O database. - :param integer replace: `1` to replace existing database. - :param integer deactivate_indexes: `1` to do not activate indices. - :param integer do_not_restore_shadows: `1` to do not restore shadows. - :param integer do_not_enforce_constraints: `1` to do not enforce - constraints during restore. - :param integer commit_after_each_table: `1` to commit after each table - is restored. - :param integer use_all_page_space: `1` to use all space on data pages. - :param integer no_db_triggers: `1` to disable database triggers temporarily. - :param integer metadata_only: `1` to restore only database metadata. + Args: + backup_stream (stream): Backup stream. + dest_filenames (str or tuple(str)): Database file(s) specification. + + Keyword Args: + dest_file_pages (tuple(int)): Specification of database file max. # of pages. + page_size (int): Page size. + cache_buffers (int): Size of page-cache for this database. + access_mode_read_only (int): `1` to create R/O database. + replace (int): `1` to replace existing database. + deactivate_indexes (int): `1` to do not activate indices. + do_not_restore_shadows (int): `1` to do not restore shadows. + do_not_enforce_constraints (int): `1` to do not enforce constraints during restore. + commit_after_each_table (int): `1` to commit after each table is restored. + use_all_page_space (int): `1` to use all space on data pages. + no_db_triggers (int): `1` to disable database triggers temporarily. + metadata_only (int): `1` to restore only database metadata. """ self.__check_active() # Begin parameter validation section. @@ -1273,12 +1286,16 @@ no_db_triggers=0): """Perform physical (NBACKUP) database backup. - :param string source_database: Source database specification. - :param dest_filename: Backup file specification. - :param integer nbackup_level: Incremental backup level. - :param integer no_db_triggers: `1` to disable database triggers temporarily. + Args: + source_database (str): Source database specification. + dest_filename (str): Backup file specification. + + Keyword Args: + nbackup_level (int): Incremental backup level. + no_db_triggers (int): `1` to disable database triggers temporarily. - .. note:: Method call will not return until action is finished. + Note: + Method call will not return until action is finished. """ self.__check_active() # Begin parameter validation section. @@ -1315,12 +1332,15 @@ no_db_triggers=0): """Perform restore from physical (NBACKUP) database backup. - :param source_filenames: Backup file(s) specification. - :type source_filenames: string or tuple of strings - :param dest_filename: Database file specification. - :param integer no_db_triggers: `1` to disable database triggers temporarily. + Args: + source_filenames (str or tuple(str)): Backup file(s) specification. + dest_filename (str): Database file specification. - .. note:: Method call will not return until action is finished. + Keyword Args: + no_db_triggers (int): `1` to disable database triggers temporarily. + + Note: + Method call will not return until action is finished. """ self.__check_active() # Begin parameter validation section. @@ -1353,17 +1373,23 @@ def trace_start(self, config, name=None): """Start new trace session. **(ASYNC service)** - :param string config: Trace session configuration. - :param string name: (optional) Trace session name. - :returns integer: Trace session ID. - :raises fdb.DatabaseError: When session ID is not returned on start. + Args: + config (str): Trace session configuration. + + Keyword Args: + name (str): Trace session name. + + Returns: + integer: Trace session ID. + + Raises: + fdb.DatabaseError: When session ID is not returned on start. Trace session output could be retrieved through :meth:`readline`, :meth:`readlines`, iteration over `Connection` or ignored via call to :meth:`wait`. - .. note:: - + Note: Until session output is not fully fetched from service (or ignored via :meth:`wait`), any attempt to start another asynchronous service including call to any `trace_` method will fail with exception. @@ -1391,10 +1417,15 @@ def trace_stop(self, trace_id): """Stop trace session. - :param integer trace_id: Trace session ID. - :returns string: Text with confirmation that session was stopped. - :raises `~fdb.DatabaseError`: When trace session is not stopped. - :raises `~fdb.OperationalError`: When server can't perform requested operation. + Args: + trace_id (int): Trace session ID. + + Returns: + str: Text with confirmation that session was stopped. + + Raises: + fdb.DatabaseError: When trace session is not stopped. + fdb.OperationalError: When server can't perform requested operation. """ self.__check_active() # Construct the request buffer. @@ -1409,10 +1440,15 @@ def trace_suspend(self, trace_id): """Suspend trace session. - :param integer trace_id: Trace session ID. - :returns string: Text with confirmation that session was paused. - :raises `~fdb.DatabaseError`: When trace session is not paused. - :raises `~fdb.OperationalError`: When server can't perform requested operation. + Args: + trace_id (int): Trace session ID. + + Returns: + str: Text with confirmation that session was paused. + + Raises: + fdb.DatabaseError: When trace session is not paused. + fdb.OperationalError: When server can't perform requested operation. """ self.__check_active() # Construct the request buffer. @@ -1427,10 +1463,15 @@ def trace_resume(self, trace_id): """Resume trace session. - :param integer trace_id: Trace session ID. - :returns string: Text with confirmation that session was resumed. - :raises `~fdb.DatabaseError`: When trace session is not resumed. - :raises `~fdb.OperationalError`: When server can't perform requested operation. + Args: + trace_id (int): Trace session ID. + + Returns: + str: Text with confirmation that session was resumed. + + Raises: + fdb.DatabaseError: When trace session is not resumed. + fdb.OperationalError: When server can't perform requested operation. """ self.__check_active() # Construct the request buffer. @@ -1445,16 +1486,18 @@ def trace_list(self): """Get information about existing trace sessions. - :returns dictionary: Mapping `SESSION_ID -> SESSION_PARAMS` + Returns: + dict: Mapping `SESSION_ID -> SESSION_PARAMS` - Session parameters is another dictionary with next keys: + Session parameters is another dictionary with next keys: - :name: (string) (optional) Session name if specified. + :name: (str) (optional) Session name if specified. :date: (datetime.datetime) Session start date and time. - :user: (string) Trace user name. - :flags: (list of strings) Session flags. + :user: (str) Trace user name. + :flags: (list(str)) Session flags. - :raises `~fdb.OperationalError`: When server can't perform requested operation. + Raises: + fdb.OperationalError: When server can't perform requested operation. """ self.__check_active() # Construct the request buffer. @@ -1486,8 +1529,9 @@ def set_default_page_buffers(self, database, n): """Set individual page cache size for Database. - :param string database: Database filename or alias. - :param integer n: Number of pages. + Args: + database (str): Database filename or alias. + n (int): Number of pages. """ self.__check_active() _check_string(database) @@ -1497,8 +1541,9 @@ def set_sweep_interval(self, database, n): """Set treshold for automatic sweep. - :param string database: Database filename or alias. - :param integer n: Sweep treshold, or `0` to disable automatic sweep. + Args: + database (str): Database filename or alias. + n (int): Sweep treshold, or `0` to disable automatic sweep. """ self.__check_active() _check_string(database) @@ -1508,8 +1553,9 @@ def set_reserve_page_space(self, database, reserve_space): """Set data page space reservation policy. - :param string database: Database filename or alias. - :param boolean reserve_space: `True` to reserve space, `False` to do not. + Args: + database (str): Database filename or alias. + reserve_space (bool): `True` to reserve space, `False` to do not. """ self.__check_active() _check_string(database) @@ -1523,10 +1569,11 @@ def set_write_mode(self, database, mode): """Set Disk Write Mode: Sync (forced writes) or Async (buffered). - :param string database: Database filename or alias. - :param integer mode: One from following constants: - :data:`~fdb.services.WRITE_FORCED` or - :data:`~fdb.services.WRITE_BUFFERED` + Args: + database (str): Database filename or alias. + mode (int): One from following constants: + :data:`~fdb.services.WRITE_FORCED` or + :data:`~fdb.services.WRITE_BUFFERED` """ self.__check_active() _check_string(database) @@ -1539,10 +1586,11 @@ def set_access_mode(self, database, mode): """Set Database Access mode: Read Only or Read/Write - :param string database: Database filename or alias. - :param integer mode: One from following constants: - :data:`~fdb.services.ACCESS_READ_WRITE` or - :data:`~fdb.services.ACCESS_READ_ONLY` + Args: + database (str): Database filename or alias. + mode (int): One from following constants: + :data:`~fdb.services.ACCESS_READ_WRITE` or + :data:`~fdb.services.ACCESS_READ_ONLY` """ self.__check_active() _check_string(database) @@ -1555,8 +1603,9 @@ def set_sql_dialect(self, database, dialect): """Set SQL Dialect for Database. - :param string database: Database filename or alias. - :param integer dialect: `1` or `3`. + Args: + database (str): Database filename or alias. + dialect (int): `1` or `3`. """ self.__check_active() _check_string(database) @@ -1569,7 +1618,8 @@ def activate_shadow(self, database): """Activate Database Shadow(s). - :param string database: Database filename or alias. + Args: + database (str): Database filename or alias. """ self.__check_active() _check_string(database) @@ -1579,7 +1629,8 @@ def no_linger(self, database): """Set one-off override for database linger. - :param string database: Database filename or alias. + Args: + database (str): Database filename or alias. """ self.__check_active() _check_string(database) @@ -1590,17 +1641,19 @@ def shutdown(self, database, shutdown_mode, shutdown_method, timeout): """Database shutdown. - :param string database: Database filename or alias. - :param integer shutdown_mode: One from following constants: - :data:`~fdb.services.SHUT_LEGACY`, :data:`~fdb.services.SHUT_SINGLE`, - :data:`~fdb.services.SHUT_MULTI` or :data:`~fdb.services.SHUT_FULL`. - :param integer shutdown_method: One from following constants: - :data:`~fdb.services.SHUT_FORCE`, - :data:`~fdb.services.SHUT_DENY_NEW_TRANSACTIONS` - or :data:`~fdb.services.SHUT_DENY_NEW_ATTACHMENTS`. - :param integer timeout: Time in seconds, that the shutdown must complete in. + Args: + database (str): Database filename or alias. + shutdown_mode (int): One from following constants: + :data:`~fdb.services.SHUT_LEGACY`, :data:`~fdb.services.SHUT_SINGLE`, + :data:`~fdb.services.SHUT_MULTI` or :data:`~fdb.services.SHUT_FULL`. + shutdown_method (int): One from following constants: + :data:`~fdb.services.SHUT_FORCE`, + :data:`~fdb.services.SHUT_DENY_NEW_TRANSACTIONS` + or :data:`~fdb.services.SHUT_DENY_NEW_ATTACHMENTS`. + timeout (int): Time in seconds, that the shutdown must complete in. - .. seealso:: See also :meth:`~Connection.bring_online` method. + See also: + Method :meth:`bring_online` """ self.__check_active() _check_string(database) @@ -1624,12 +1677,16 @@ def bring_online(self, database, online_mode=SHUT_NORMAL): """Bring previously shut down database back online. - :param string database: Database filename or alias. - :param integer online_mode: (Optional) One from following constants: - :data:`~fdb.services.SHUT_LEGACY`, :data:`~fdb.services.SHUT_SINGLE`, - :data:`~fdb.services.SHUT_MULTI` or :data:`~fdb.services.SHUT_NORMAL` (**Default**). + Args: + database (str): Database filename or alias. - .. seealso:: See also :meth:`~Connection.shutdown` method. + Keyword Args: + online_mode (int): One from following constants: + :data:`~fdb.services.SHUT_LEGACY`, :data:`~fdb.services.SHUT_SINGLE`, + :data:`~fdb.services.SHUT_MULTI` or (**Default**) :data:`~fdb.services.SHUT_NORMAL`. + + See also: + Method :meth:`shutdown` """ self.__check_active() _check_string(database) @@ -1648,9 +1705,11 @@ def sweep(self, database): """Perform Database Sweep. - .. note:: Method call will not return until sweep is finished. + Note: + Method call will not return until sweep is finished. - :param string database: Database filename or alias. + Args: + database (str): Database filename or alias. """ self.__check_active() _check_string(database) @@ -1667,16 +1726,19 @@ validate_record_fragments=1): """Database Validation and Repair. - :param string database: Database filename or alias. - :param integer read_only_validation: `1` to prevent any database changes. - :param integer ignore_checksums: `1` to ignore page checksum errors. - :param integer kill_unavailable_shadows: `1` to kill unavailable shadows. - :param integer mend_database: `1` to fix database for backup. - :param integer validate_database: `0` to skip database validation. - :param integer validate_record_fragments: `0` to skip validation of - record fragments. + Args: + database (str): Database filename or alias. + + Keyword Args: + read_only_validation (int): `1` to prevent any database changes. + ignore_checksums (int): `1` to ignore page checksum errors. + kill_unavailable_shadows (int): `1` to kill unavailable shadows. + mend_database (int): `1` to fix database for backup. + validate_database (int): `0` to skip database validation. + validate_record_fragments (int): `0` to skip validation of record fragments. - .. note:: Method call will not return until action is finished. + Note: + Method call will not return until action is finished. """ self.__check_active() _check_string(database) @@ -1718,32 +1780,34 @@ lock_timeout=None, callback=None): """On-line database validation. - :param string database: Database filename or alias. - :param string include_tables: Pattern for table names to include in validation run. - :param string exclude_tables: Pattern for table names to exclude from validation run. - :param string include_indices: Pattern for index names to include in validation run. - :param string exclude_indices: Pattern for index names to exclude from validation run. - :param integer lock_timeout: lock timeout, used to acquire locks for table to validate, - in seconds, default is 10 secs. 0 is no-wait, -1 is infinite wait. - :param function callback: Function to call back with each output line. - Function must accept only one parameter: line of output. - - .. note:: Patterns are regular expressions, processed by the same rules as SIMILAR TO - expressions. All patterns are case-sensitive, regardless of database dialect. If the - pattern for tables is omitted then all user tables will be validated. If the pattern - for indexes is omitted then all indexes of the appointed tables will be validated. - System tables are not validated. + Args: + database (str): Database filename or alias. + + Keyword Args: + include_tables (str): Pattern for table names to include in validation run. + exclude_tables (str): Pattern for table names to exclude from validation run. + include_indices (str): Pattern for index names to include in validation run. + exclude_indices (str): Pattern for index names to exclude from validation run. + lock_timeout (int): lock timeout, used to acquire locks for table to validate, + in seconds, default is 10 secs. 0 is no-wait, -1 is infinite wait. + callback (callable): Function to call back with each output line. + Function must accept only one parameter: line of output. + + Note: + Patterns are regular expressions, processed by the same rules as SIMILAR TO + expressions. All patterns are case-sensitive, regardless of database dialect. If the + pattern for tables is omitted then all user tables will be validated. If the pattern + for indexes is omitted then all indexes of the appointed tables will be validated. + System tables are not validated. If `callback` is not specified, validation log could be retrieved through :meth:`readline`, :meth:`readlines`, iteration over `Connection` or ignored via call to :meth:`wait`. - .. note:: - + Note: Until validate report is not fully fetched from service (or ignored via :meth:`wait`), any attempt to start another asynchronous service will fail with exception. - """ self.__check_active() _check_string(database) @@ -1772,9 +1836,12 @@ def get_users(self, user_name=None): """Get information about user(s). - :param string user_name: (Optional) When specified, returns information - only about user with specified user name. - :returns list: :class:`User` instances. + Keyword Args: + user_name (str): When specified, returns information + only about user with specified user name. + + Returns: + list: List of :class:`User` instances. """ self.__check_active() if user_name is not None: @@ -1826,13 +1893,12 @@ def add_user(self, user): """Add new user. - :param user: Instance of :class:`User` with **at least** its - :attr:`~User.name` and :attr:`~User.password` attributes specified - as non-empty values. All other attributes are optional. - :type user: :class:`User` - - .. note:: + Args: + user (:class:`User`): Instance of :class:`User` with **at least** its + :attr:`~User.name` and :attr:`~User.password` attributes specified + as non-empty values. All other attributes are optional. + Note: This method ignores the :attr:`~User.user_id` and :attr:`~User.group_id` attributes of :class:`~User` regardless of their values. """ @@ -1868,12 +1934,11 @@ def modify_user(self, user): """Modify user information. - :param user: Instance of :class:`User` with **at least** its - :attr:`~User.name` attribute specified as non-empty value. - :type user: :class:`User` - - .. note:: + Args: + user (:class:`User`): Instance of :class:`User` with **at least** its + :attr:`~User.name` attribute specified as non-empty value. + Note: This method sets :attr:`~User.first_name`, :attr:`~User.middle_name` and :attr:`~User.last_name` to their actual values, and ignores the :attr:`~User.user_id` and :attr:`~User.group_id` attributes @@ -1904,9 +1969,9 @@ def remove_user(self, user): """Remove user. - :param user: User name or Instance of :class:`User` with **at least** its - :attr:`~User.name` attribute specified as non-empty value. - :type user: string or :class:`User` + Args: + user (:class:`User`): User name or Instance of :class:`User` with **at least** its + :attr:`~User.name` attribute specified as non-empty value. """ self.__check_active() if isinstance(user, User): @@ -1922,10 +1987,12 @@ def user_exists(self, user): """Check for user's existence. - :param user: User name or Instance of :class:`User` with **at least** its - :attr:`~User.name` attribute specified as non-empty value. - :type user: string or :class:`User` - :returns boolean: `True` when the specified user exists. + Args: + user (:class:`User`): User name or Instance of :class:`User` with **at least** its + :attr:`~User.name` attribute specified as non-empty value. + + Returns: + bool: `True` when the specified user exists. """ self.__check_active() if isinstance(user, User): @@ -1950,25 +2017,25 @@ _check_string(name) self.name = name.upper() else: - #: User `login` name (username). + #: str: User `login` name (username). self.name = None - #: Password. Not returned by user output methods, but must be + #: str: Password. Not returned by user output methods, but must be #: specified to add a user. self.password = None - #: First name. + #: str: First name. self.first_name = None - #: Middle name + #: str: Middle name self.middle_name = None - #: Last name + #: str: Last name self.last_name = None # The user id and group id are not fully supported. For details, see # the documentation of the "User Management Methods" of # services.Connection. - #: User ID + #: int: User ID self.user_id = None - #: User group ID + #: int: User group ID self.group_id = None def __str__(self): @@ -1978,11 +2045,14 @@ def load_information(self, svc): """Load information about user from server. - :param svc: Open service connection. - :type svc: :class:`Connection` - :returns: True if information was successfuly retrieved, False otherwise. + Args: + svc (:class:`Connection`): Open service connection. + + Returns: + True if information was successfuly retrieved, False otherwise. - :raises `~fdb.ProgrammingError`: If user name is not defined. + Raises: + fdb.ProgrammingError: If user name is not defined. """ if self.name is None: raise fdb.ProgrammingError("Can't load information about user without name.") diff -Nru fdb-2.0.0/fdb/trace.py fdb-2.0.1/fdb/trace.py --- fdb-2.0.0/fdb/trace.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/trace.py 2019-07-08 09:48:05.000000000 +0000 @@ -152,15 +152,14 @@ """Parser for standard textual trace log. Produces named tuples describing individual trace log entries/events. Attributes: - - :seen_attachments: Set of attachment ids that were already processed. - :seen_transactions: Set of transaction ids that were already processed. - :seen_services: Set of service ids that were already processed. - :sqlinfo_map: Dictionary that maps (sql_cmd,plan) keys to internal ids - :param_map: Dictionary that maps parameters (statement or procedure) keys to internal ids - :next_event_id: Sequence id that would be assigned to next parsed event (starts with 1). - :next_sql_id: Sequence id that would be assigned to next parsed unique SQL command (starts with 1). - :next_param_id: Sequence id that would be assigned to next parsed unique parameter (starts with 1). + seen_attachments (set): Set of attachment ids that were already processed. + seen_transactions (set): Set of transaction ids that were already processed. + seen_services (set): Set of service ids that were already processed. + sqlinfo_map (dict): Dictionary that maps (sql_cmd,plan) keys to internal ids + param_map (dict): Dictionary that maps parameters (statement or procedure) keys to internal ids + next_event_id (int): Sequence id that would be assigned to next parsed event (starts with 1). + next_sql_id (int): Sequence id that would be assigned to next parsed unique SQL command (starts with 1). + next_param_id (int): Sequence id that would be assigned to next parsed unique parameter (starts with 1). """ def __init__(self): self.seen_attachments = set() @@ -305,7 +304,7 @@ if protocol_address == '': protocol = address = protocol_address else: - protocol, address = protocol_address.split(':') + protocol, address = protocol_address.split(':', 1) values['protocol'] = protocol values['address'] = address if ':' in user_role: @@ -944,9 +943,11 @@ def parse_event(self, trace_block): """Parse single trace event. - :param list trace_block: List with trace entry lines for single trace event. + Args: + trace_block (list): List with trace entry lines for single trace event. - :returns: Named tuple with parsed event. + Returns: + Named tuple with parsed event. """ self.__current_block = collections.deque(trace_block) if self._is_session_suspended(self.__current_block[0]): @@ -957,11 +958,16 @@ # return self._parse_block(record_parser) def parse(self, lines): - """Parse output from Firebird trace session and yield named tuples describing individual trace log entries/events. + """Parse output from Firebird trace session. + + Args: + lines (iterable): Iterable that return lines produced by firebird trace session. - :param lines: Iterable that return lines produced by firebird trace session. + Yields: + Named tuples describing individual trace log entries/events. - :raises `~fdb.ParseError`: When any problem is found in input stream. + Raises: + fdb.ParseError: When any problem is found in input stream. """ for rec in (self.parse_event(x) for x in self._iter_trace_blocks(lines)): while len(self.__buffer) > 0: diff -Nru fdb-2.0.0/fdb/utils.py fdb-2.0.1/fdb/utils.py --- fdb-2.0.0/fdb/utils.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/fdb/utils.py 2018-08-20 13:20:44.000000000 +0000 @@ -46,66 +46,54 @@ class LateBindingProperty(property): """Property class that binds to getter/setter/deleter methods when **instance** -of class that define the property is created. This allows you to override -these methods in descendant classes (if they are not private) without -necessity to redeclare the property itself in descendant class. - -Recipe from Tim Delaney, 2005/03/31 -http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408713 - -:: - - class C(object): - - def getx(self): - print 'C.getx' - return self._x - - def setx(self, x): - print 'C.setx' - self._x = x - - def delx(self): - print 'C.delx' - del self._x - - x = LateBindingProperty(getx, setx, delx) - - class D(C): - - def setx(self, x): - print 'D.setx' - super(D, self).setx(x) - - def delx(self): - print 'D.delx' - super(D, self).delx() - - c = C() - c.x = 1 - c.x - c.x - del c.x - - print - - d = D() - d.x = 1 - d.x - d.x - del d.x - -This has the advantages that: - -a. You get back an actual property object (with attendant memory savings, performance increases, etc); - -b. It's the same syntax as using property(fget, fset, fdel, doc) except for the name; - -c. It will fail earlier (when you define the class as opposed to when you use it). - -d. It's shorter ;) - -e. If you inspect the property you will get back functions with the correct __name__, __doc__, etc. + of class that define the property is created. This allows you to override + these methods in descendant classes (if they are not private) without + necessity to redeclare the property itself in descendant class. + + Recipe from Tim Delaney, 2005/03/31 + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408713 + + Example: + .. code-block:: python + + class C(object): + def getx(self): + print 'C.getx' + return self._x + def setx(self, x): + print 'C.setx' + self._x = x + def delx(self): + print 'C.delx' + del self._x + x = LateBindingProperty(getx, setx, delx) + + class D(C): + def setx(self, x): + print 'D.setx' + super(D, self).setx(x) + def delx(self): + print 'D.delx' + super(D, self).delx() + + c = C() + c.x = 1 + c.x + c.x + del c.x + print + d = D() + d.x = 1 + d.x + d.x + del d.x + + This has the advantages that: + - You get back an actual property object (with attendant memory savings, performance increases, etc); + - It's the same syntax as using property(fget, fset, fdel, doc) except for the name; + - It will fail earlier (when you define the class as opposed to when you use it). + - It's shorter ;) + - If you inspect the property you will get back functions with the correct `__name__`, `__doc__`, etc. """ def __new__(cls, fget=None, fset=None, fdel=None, doc=None): @@ -131,9 +119,9 @@ """ def __init__(self, method, sentinel=None): """ - :param method: Callable without parameters that returns next item. - :param sentinel: Value that when returned by `method` indicates the end - of sequence. + Args: + method (callable): Callable without parameters that returns next item. + sentinel: Value that when returned by `method` indicates the end of sequence. """ self.getnext = method self.sentinel = sentinel @@ -193,31 +181,43 @@ setattr(getattr(obj, self.obj), self.attr, val) def iter_class_properties(cls): - """Iterator that yields `name, property` pairs for all properties in class. + """Iterator function. - :param class cls: Class object.""" + Args: + cls (class): Class object. + + Yields: + `name', 'property` pairs for all properties in class. +""" for varname in vars(cls): value = getattr(cls, varname) if isinstance(value, property): yield varname, value def iter_class_variables(cls): - """Iterator that yields names of all non-callable attributes in class. + """Iterator function. + + Args: + cls (class): Class object. - :param class cls: Class object.""" + Yields: + Names of all non-callable attributes in class. +""" for varname in vars(cls): value = getattr(cls, varname) if not (isinstance(value, property) or callable(value)) and not varname.startswith('_'): yield varname def embed_attributes(from_class, attr): - """Class decorator that injects properties and attributes -from another class instance embedded in class instances. Only attributes and properties that are not -already defined in decorated class are injected. - - :param class from_class: Class that should extend decorated class. - :param string attr: Attribute name that holds instance of embedded class - within decorated class instance.""" + """Class decorator that injects properties and attributes from another class instance + embedded in class instances. Only attributes and properties that are not already defined + in decorated class are injected. + + Args: + from_class (class): Class that should extend decorated class. + attr (str): Attribute name that holds instance of embedded class within + decorated class instance. +""" def d(class_): for pname, prop in iter_class_properties(from_class): if not hasattr(class_, pname): @@ -245,11 +245,13 @@ """ def __init__(self, items=None, _cls=None, key_expr=None): """ - :param iterable items: Sequence to initialize the collection. - :param _cls: Class or list/tuple of classes. Only instances of these classes would be allowed in collection. - :param str key_expr: Key expression. Must contain item referrence as `item`, for example `item.attribute_name`. + Args: + items (iterable): Sequence to initialize the collection. + _cls (class or list/tuple): Only instances of these class(es) would be allowed in collection. + key_expr (str): Key expression. Must contain item referrence as `item`, for example `item.attribute_name`. - :raises ValueError: When initialization sequence contains invalid instance. + Raises: + ValueError: When initialization sequence contains invalid instance. """ if items: super(ObjectList, self).__init__(items) @@ -281,42 +283,46 @@ def insert(self, index, item): """Insert item before index. - :raises TypeError: When list is frozen or item is not an instance of allowed class""" + Raises: + TypeError: When list is frozen or item is not an instance of allowed class""" self.__check_mutability() self.__check_value(item) super(ObjectList, self).insert(index, item) def append(self, item): """Add an item to the end of the list. - :raises TypeError: When list is frozen or item is not an instance of allowed class""" + Raises: + TypeError: When list is frozen or item is not an instance of allowed class""" self.__check_mutability() self.__check_value(item) super(ObjectList, self).append(item) def extend(self, iterable): """Extend the list by appending all the items in the given iterable. - :raises TypeError: When list is frozen or item is not an instance of allowed class""" + Raises: + TypeError: When list is frozen or item is not an instance of allowed class""" for item in iterable: self.append(item) def sort(self, attrs=None, expr=None, reverse=False): """Sort items in-place, optionaly using attribute values as key or key expression. - :param list attrs: List of attribute names. - :param expr: Key expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + attrs (list): List of attribute names. + expr: Key expression, a callable accepting one parameter or expression + as string referencing list item as `item`. .. important:: - Only one parameter (`attrs` or `expr`) could be specified. If none is present then uses default list sorting rule. + Only one parameter (`attrs` or `expr`) could be specified. + If none is present then uses default list sorting rule. - :raises TypeError: When list is frozen. + Examples: + .. code-block:: python - Examples:: - - sort(attrs=['name','degree']) # Sort by item.name, item.degree - sort(expr=lambda x: x.name.upper()) # Sort by upper item.name - sort(expr='item.name.upper()') # Sort by upper item.name + sort(attrs=['name','degree']) # Sort by item.name, item.degree + sort(expr=lambda x: x.name.upper()) # Sort by upper item.name + sort(expr='item.name.upper()') # Sort by upper item.name """ - self.__check_mutability() if attrs: super(ObjectList, self).sort(key=attrgetter(*attrs), reverse=reverse) elif expr: @@ -324,20 +330,24 @@ else: super(ObjectList, self).sort(reverse=reverse) def reverse(self): - """Reverse the elements of the list, in place. - - :raises TypeError: When list is frozen.""" - self.__check_mutability() + """Reverse the elements of the list, in place.""" super(ObjectList, self).reverse() def clear(self): """Remove all items from the list. - :raises TypeError: When list is frozen.""" + Raises: + TypeError: When list is frozen.""" self.__check_mutability() while len(self) > 0: del self[0] def freeze(self): - """Set list to immutable (frozen) state.""" + """Set list to immutable (frozen) state. + + Freezing list makes internal map from `key_expr` to item index that significantly + speeds up retrieval by key using the :meth:`get` method. + + It's not possible to `add`, `delete` or `change` items in frozen list, but `sort` is allowed. +""" self.__frozen = True if self.__key_expr: fce = make_lambda(self.__key_expr) @@ -345,36 +355,45 @@ def filter(self, expr): """Return new ObjectList of items for which `expr` is evaluated as True. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - filter(lambda x: x.name.startswith("ABC")) - filter('item.name.startswith("ABC")') + filter(lambda x: x.name.startswith("ABC")) + filter('item.name.startswith("ABC")') """ fce = expr if callable(expr) else make_lambda(expr) return ObjectList(self.ifilter(expr), self._cls, self.__key_expr) def ifilter(self, expr): """Return generator that yields items for which `expr` is evaluated as True. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - ifilter(lambda x: x.name.startswith("ABC")) - ifilter('item.name.startswith("ABC")') + ifilter(lambda x: x.name.startswith("ABC")) + ifilter('item.name.startswith("ABC")') """ fce = expr if callable(expr) else make_lambda(expr) return (item for item in self if fce(item)) def ifilterfalse(self, expr): """Return generator that yields items for which `expr` is evaluated as False. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - ifilter(lambda x: x.name.startswith("ABC")) - ifilter('item.name.startswith("ABC")') + ifilter(lambda x: x.name.startswith("ABC")) + ifilter('item.name.startswith("ABC")') """ fce = expr if callable(expr) else make_lambda(expr) return (item for item in self if not fce(item)) @@ -386,17 +405,18 @@ - A callable accepting one parameter and returning data for output - One or more expressions as string referencing item as `item`. - Examples:: + Examples: + .. code-block:: python - # returns list of tuples with item.name and item.size + # returns list of tuples with item.name and item.size - report(lambda x: (x.name, x.size)) - report('item.name','item.size') + report(lambda x: (x.name, x.size)) + report('item.name','item.size') - # returns list of item names + # returns list of item names - report(lambda x: x.name) - report('item.name') + report(lambda x: x.name) + report('item.name') """ if len(args) == 1 and callable(args[0]): fce = args[0] @@ -412,17 +432,18 @@ - A callable accepting one parameter and returning data for output - One or more expressions as string referencing item as `item`. - Examples:: + Examples: + .. code-block:: python - # generator of tuples with item.name and item.size + # generator of tuples with item.name and item.size - report(lambda x: (x.name, x.size)) - report('item.name','item.size') + report(lambda x: (x.name, x.size)) + report('item.name','item.size') - # generator of item names + # generator of item names - report(lambda x: x.name) - report('item.name') + report(lambda x: x.name) + report('item.name') """ if len(args) == 1 and callable(args[0]): fce = args[0] @@ -433,36 +454,47 @@ def ecount(self, expr): """Return number of items for which `expr` is evaluated as True. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - ecount(lambda x: x.name.startswith("ABC")) - ecount('item.name.startswith("ABC")') + ecount(lambda x: x.name.startswith("ABC")) + ecount('item.name.startswith("ABC")') """ return sum(1 for item in self.ifilter(expr)) def split(self, expr): - """Return two new ObjectLists, first with items for which `expr` is evaluated as True and second for `expr` evaluated as False. + """Return two new ObjectLists, first with items for which `expr` is evaluated + as True and second for `expr` evaluated as False. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - split(lambda x: x.size > 100) - split('item.size > 100') + split(lambda x: x.size > 100) + split('item.size > 100') """ return ObjectList(self.ifilter(expr), self._cls, self.__key_expr), ObjectList(self.ifilterfalse(expr), self._cls, self.__key_expr) def extract(self, expr): """Move items for which `expr` is evaluated as True into new ObjectLists. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - :raises TypeError: When list is frozen. + Raises: + TypeError: When list is frozen. - Example:: + Example: + .. code-block:: python - extract(lambda x: x.name.startswith("ABC")) - extract('item.name.startswith("ABC")') + extract(lambda x: x.name.startswith("ABC")) + extract('item.name.startswith("ABC")') """ self.__check_mutability() fce = expr if callable(expr) else make_lambda(expr) @@ -477,23 +509,31 @@ i += 1 return l def get(self, value, expr=None): - """Return item with given key value using default or specified key expression, or None if there is no such item. - - Uses very fast method to look up value of default key expression in `frozen` list, otherwise it uses slower list traversal. + """Return item with given key value using default or specified key expression, + or None if there is no such item. - :param value: Searched value. - :param expr: Key value expression, a callable accepting two parameters (item,value) or expression as string referencing list item as `item`. + Uses very fast method to look up value of default key expression in `frozen` list, + otherwise it uses slower list traversal. - :raises TypeError: If key expression is not defined. + Args: + value: Searched value. - Examples:: - - # Search using default key expression - get('ITEM_NAME') - # Search using callable key expression - get('ITEM_NAME',lambda x: x.name.upper()) - # Search using string key expression - get('ITEM_NAME','item.name.upper()') + Keyword Args: + expr: Key value expression, a callable accepting two parameters (item,value) + or expression as string referencing list item as `item`. + + Raises: + TypeError: If key expression is not defined. + + Examples: + .. code-block:: python + + # Search using default key expression + get('ITEM_NAME') + # Search using callable key expression + get('ITEM_NAME',lambda x: x.name.upper()) + # Search using string key expression + get('ITEM_NAME','item.name.upper()') """ if self.__map and not expr: i = self.__map.get(value) @@ -512,28 +552,36 @@ def contains(self, value, expr=None): """Return True if list has any item with default or specified key expression equal to given value. - :param value: Tested key value. - :param expr: Key value expression, a callable accepting two parameters (item,value) or expression as string referencing list item as `item`. - - Examples:: + Args: + value: Tested key value. - # Search using default key expression - contains('ITEM_NAME') - # Search using callable key expression - contains('ITEM_NAME',lambda x: x.name.upper()) - # Search using string key expression - contains('ITEM_NAME','item.name.upper()') + Keyword Args: + expr: Key value expression, a callable accepting two parameters (item,value) + or expression as string referencing list item as `item`. + + Examples: + .. code-block:: python + + # Search using default key expression + contains('ITEM_NAME') + # Search using callable key expression + contains('ITEM_NAME',lambda x: x.name.upper()) + # Search using string key expression + contains('ITEM_NAME','item.name.upper()') """ return False if self.get(value, expr) is None else True def all(self, expr): """Return True if `expr` is evaluated as True for all list elements. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - all(lambda x: x.name.startswith("ABC")) - all('item.name.startswith("ABC")') + all(lambda x: x.name.startswith("ABC")) + all('item.name.startswith("ABC")') """ fce = expr if callable(expr) else make_lambda(expr) for item in self: @@ -543,21 +591,25 @@ def any(self, expr): """Return True if `expr` is evaluated as True for any list element. - :param expr: Boolean expression, a callable accepting one parameter or expression as string referencing list item as `item`. + Args: + expr: Boolean expression, a callable accepting one parameter or expression + as string referencing list item as `item`. - Example:: + Example: + .. code-block:: python - any(lambda x: x.name.startswith("ABC")) - any('item.name.startswith("ABC")') + any(lambda x: x.name.startswith("ABC")) + any('item.name.startswith("ABC")') """ fce = expr if callable(expr) else make_lambda(expr) for item in self: - if not fce(item): + if fce(item): return True return False # - frozen = property(fget=lambda self: self.__frozen, doc='True if list is immutable') + frozen = property(fget=lambda self: self.__frozen, doc="True if list items couldn't be changed") key = property(fget=lambda self: self.__key_expr, doc='Key expression') + class_type = property(fget=lambda self: self._cls, doc='Class or list/tuple of classes that this list accepts.') class Visitable(object): """Base class for Visitor Pattern support. @@ -567,7 +619,8 @@ def accept(self, visitor): """Visitor Pattern support. Calls `visit(self)` on parameter object. - :param visitor: Visitor object of Visitor Pattern. + Args: + visitor: Visitor object of Visitor Pattern. """ visitor.visit(self) @@ -584,8 +637,7 @@ This implementation uses Python Method Resolution Order (__mro__) to find special handling method, so special method for given class is used also for its decendants. - Example:: - + Example: class Node(object): pass class A(Node): pass class B(Node): pass @@ -607,8 +659,7 @@ visitor.visit(b) visitor.visit(c) - Will create output:: - + Will create output: default_action A visit_B B visit_B C @@ -619,7 +670,8 @@ First traverses the `obj.__mro__` to try find method with name following `visit_` pattern and calls it with `obj`. Otherwise it calls :meth:`default_action`. - :param object obj: Object to be handled by visitor. + Args: + obj: Object to be handled by visitor. """ meth = None for cls in obj.__class__.__mro__: @@ -632,8 +684,10 @@ def default_action(self, obj): """Default handler for visited objects. - :param object obj: Object to be handled. + Args: + obj: Object to be handled. - .. note:: This implementation does nothing! + Note: + This implementation does nothing! """ pass diff -Nru fdb-2.0.0/fdb.egg-info/PKG-INFO fdb-2.0.1/fdb.egg-info/PKG-INFO --- fdb-2.0.0/fdb.egg-info/PKG-INFO 2018-04-27 11:40:46.000000000 +0000 +++ fdb-2.0.1/fdb.egg-info/PKG-INFO 2019-07-13 10:01:42.000000000 +0000 @@ -1,8 +1,8 @@ Metadata-Version: 2.1 Name: fdb -Version: 2.0.0 +Version: 2.0.1 Summary: The Python driver for Firebird -Home-page: http://www.firebirdsql.org/en/devel-python-driver/ +Home-page: https://github.com/FirebirdSQL/fdb Author: Pavel Císař Author-email: pcisar@users.sourceforge.net License: UNKNOWN @@ -15,7 +15,9 @@ FDB - The Python driver for Firebird ==================================== - |docs| || Home_ || `Bug Reports`_ || Source_ || `Say Thanks!`_ + |docs| + + Home_ * Documentation_ * `Bug Reports`_ * Source_ * `Say Thanks!`_ FDB is a `Python`_ library package that implements `Python Database API 2.0`_-compliant support for the open source relational database `Firebird`_ ®. In addition to the minimal feature set of the standard Python DB API, FDB also exposes the entire native @@ -40,16 +42,6 @@ * Parsing Firebird server log * Parsing Firebird gstat utility output - FDB is implemented on top of Firebird client library using ctypes, and currently uses only traditional Firebird API. - - FDB works with Firebird 2.0 and newer, and Python 2.7 and 3.4+. - - FDB is free – covered by a permissive BSD-style license that both commercial and noncommercial users should find agreeable. - - FDB is replacement for discontinued KInterbasDB library, and as such it's designed to be as much compatible - with KInterbasDB as possible, but there are some differences. See FDB documentation for full description - of these differences. - |donate| .. _Python: http://python.org @@ -59,6 +51,7 @@ .. _Home: http://www.firebirdsql.org/en/devel-python-driver/ .. _Source: https://github.com/FirebirdSQL/fdb .. _Say Thanks!: https://saythanks.io/to/pcisar + .. _Documentation: http://fdb.readthedocs.io/en/v2.0/ .. |donate| image:: https://www.firebirdsql.org/img/donate/donate_to_firebird.gif :alt: Contribute to the development @@ -70,6 +63,8 @@ :scale: 100% :target: http://fdb.readthedocs.io/en/v2.0/ + + Keywords: Firebird Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable diff -Nru fdb-2.0.0/PKG-INFO fdb-2.0.1/PKG-INFO --- fdb-2.0.0/PKG-INFO 2018-04-27 11:40:46.000000000 +0000 +++ fdb-2.0.1/PKG-INFO 2019-07-13 10:01:43.000000000 +0000 @@ -1,8 +1,8 @@ Metadata-Version: 2.1 Name: fdb -Version: 2.0.0 +Version: 2.0.1 Summary: The Python driver for Firebird -Home-page: http://www.firebirdsql.org/en/devel-python-driver/ +Home-page: https://github.com/FirebirdSQL/fdb Author: Pavel Císař Author-email: pcisar@users.sourceforge.net License: UNKNOWN @@ -15,7 +15,9 @@ FDB - The Python driver for Firebird ==================================== - |docs| || Home_ || `Bug Reports`_ || Source_ || `Say Thanks!`_ + |docs| + + Home_ * Documentation_ * `Bug Reports`_ * Source_ * `Say Thanks!`_ FDB is a `Python`_ library package that implements `Python Database API 2.0`_-compliant support for the open source relational database `Firebird`_ ®. In addition to the minimal feature set of the standard Python DB API, FDB also exposes the entire native @@ -40,16 +42,6 @@ * Parsing Firebird server log * Parsing Firebird gstat utility output - FDB is implemented on top of Firebird client library using ctypes, and currently uses only traditional Firebird API. - - FDB works with Firebird 2.0 and newer, and Python 2.7 and 3.4+. - - FDB is free – covered by a permissive BSD-style license that both commercial and noncommercial users should find agreeable. - - FDB is replacement for discontinued KInterbasDB library, and as such it's designed to be as much compatible - with KInterbasDB as possible, but there are some differences. See FDB documentation for full description - of these differences. - |donate| .. _Python: http://python.org @@ -59,6 +51,7 @@ .. _Home: http://www.firebirdsql.org/en/devel-python-driver/ .. _Source: https://github.com/FirebirdSQL/fdb .. _Say Thanks!: https://saythanks.io/to/pcisar + .. _Documentation: http://fdb.readthedocs.io/en/v2.0/ .. |donate| image:: https://www.firebirdsql.org/img/donate/donate_to_firebird.gif :alt: Contribute to the development @@ -70,6 +63,8 @@ :scale: 100% :target: http://fdb.readthedocs.io/en/v2.0/ + + Keywords: Firebird Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable diff -Nru fdb-2.0.0/README.rst fdb-2.0.1/README.rst --- fdb-2.0.0/README.rst 2018-04-27 11:25:31.000000000 +0000 +++ fdb-2.0.1/README.rst 2018-04-27 14:56:55.000000000 +0000 @@ -2,7 +2,9 @@ FDB - The Python driver for Firebird ==================================== -|docs| || Home_ || `Bug Reports`_ || Source_ || `Say Thanks!`_ +|docs| + +Home_ * Documentation_ * `Bug Reports`_ * Source_ * `Say Thanks!`_ FDB is a `Python`_ library package that implements `Python Database API 2.0`_-compliant support for the open source relational database `Firebird`_ ®. In addition to the minimal feature set of the standard Python DB API, FDB also exposes the entire native @@ -27,16 +29,6 @@ * Parsing Firebird server log * Parsing Firebird gstat utility output -FDB is implemented on top of Firebird client library using ctypes, and currently uses only traditional Firebird API. - -FDB works with Firebird 2.0 and newer, and Python 2.7 and 3.4+. - -FDB is free – covered by a permissive BSD-style license that both commercial and noncommercial users should find agreeable. - -FDB is replacement for discontinued KInterbasDB library, and as such it's designed to be as much compatible -with KInterbasDB as possible, but there are some differences. See FDB documentation for full description -of these differences. - |donate| .. _Python: http://python.org @@ -46,6 +38,7 @@ .. _Home: http://www.firebirdsql.org/en/devel-python-driver/ .. _Source: https://github.com/FirebirdSQL/fdb .. _Say Thanks!: https://saythanks.io/to/pcisar +.. _Documentation: http://fdb.readthedocs.io/en/v2.0/ .. |donate| image:: https://www.firebirdsql.org/img/donate/donate_to_firebird.gif :alt: Contribute to the development @@ -56,3 +49,5 @@ :alt: Documentation Status :scale: 100% :target: http://fdb.readthedocs.io/en/v2.0/ + + diff -Nru fdb-2.0.0/setup.py fdb-2.0.1/setup.py --- fdb-2.0.0/setup.py 2018-04-27 10:13:09.000000000 +0000 +++ fdb-2.0.1/setup.py 2018-04-27 14:42:51.000000000 +0000 @@ -27,7 +27,7 @@ description='The Python driver for Firebird', long_description=long_description, long_description_content_type='text/x-rst', - url='http://www.firebirdsql.org/en/devel-python-driver/', + url='https://github.com/FirebirdSQL/fdb', author='Pavel Císař', author_email='pcisar@users.sourceforge.net', classifiers=[ diff -Nru fdb-2.0.0/sphinx/changelog.txt fdb-2.0.1/sphinx/changelog.txt --- fdb-2.0.0/sphinx/changelog.txt 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/sphinx/changelog.txt 2019-07-13 09:39:00.000000000 +0000 @@ -3,6 +3,31 @@ ######### +Version 2.0.1 +============= + +Improvements +------------ + +- Enhancements to :class:`~fdb.BlobReader` - protected data as properties (blob_id, is_text, blob_charset, charset) +- Added support for utf8 database filenames and other string db connection parameters (isc_dpb_utf8_filenames) +- New attribute: :attr:`fdb.ibase.fbclient_API.client_library_name` +- ObjectList: (a) class_type property (b) Allow sort on frozen list + +Other changes +------------- + +- Better readable code with Google-style docstring and better documentation with sphinx-napoleon extension + +Bugs Fixed +---------- + +- (Unregistered) - Bug in ObjectList.any() +- (Unregistered) - fdb.schema: ObjectLists properties for user and system objects of the same type are now stable (not created on getter call) +- (Unregistered) - fdb.log: Fix minor locale problem in Python 3 +- (Unregistered) - fdb.trace: Fix parsing of IPv6 addresses + + Version 2.0 =========== diff -Nru fdb-2.0.0/sphinx/conf.py fdb-2.0.1/sphinx/conf.py --- fdb-2.0.0/sphinx/conf.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/sphinx/conf.py 2019-07-13 09:25:56.000000000 +0000 @@ -27,7 +27,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.napoleon', 'sphinx.ext.todo'] # Add any paths that contain templates here, relative to this directory. templates_path = ['.templates'] @@ -50,9 +50,9 @@ # built documents. # # The short X.Y version. -version = '2.0' +version = '2.0.1' # The full version, including alpha/beta/rc tags. -release = '2.0' +release = '2.0.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -Nru fdb-2.0.0/sphinx/reference.txt fdb-2.0.1/sphinx/reference.txt --- fdb-2.0.0/sphinx/reference.txt 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/sphinx/reference.txt 2019-07-13 09:35:28.000000000 +0000 @@ -451,9 +451,6 @@ :no-inherited-members: :undoc-members: -.. note:: - - For list of methods see :class:`fdb.schema.Schema`. Cursor ------ diff -Nru fdb-2.0.0/sphinx/.static/basic.css fdb-2.0.1/sphinx/.static/basic.css --- fdb-2.0.0/sphinx/.static/basic.css 2018-04-26 15:06:02.000000000 +0000 +++ fdb-2.0.1/sphinx/.static/basic.css 2018-04-30 12:05:08.000000000 +0000 @@ -677,7 +677,7 @@ border: 2px solid #7a9eec; border-right-style: none; border-left-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px; } @@ -686,7 +686,7 @@ border: 2px solid #fbc2c4; border-right-style: none; border-left-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; background: #fbe3e4 url(dialog-note.png) no-repeat 10px 8px; } @@ -695,7 +695,7 @@ border: 2px solid #ffd324; border-right-style: none; border-left-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; background: #fff6bf url(dialog-note.png) no-repeat 10px 8px; } @@ -704,7 +704,7 @@ border: 2px solid #ffd324; border-right-style: none; border-left-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; background: #fff6bf url(dialog-warning.png) no-repeat 10px 8px; } @@ -714,7 +714,7 @@ border: 2px solid #fbc2c4; border-left-style: none; border-right-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; } div.seealso { @@ -723,7 +723,7 @@ border: 2px solid #ffd324; border-left-style: none; border-right-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; } div.hint, div.tip { @@ -732,7 +732,7 @@ border: 2px solid #aacc99; border-left-style: none; border-right-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; } div.warning, div.error { @@ -741,7 +741,7 @@ border: 2px solid #fbc2c4; border-right-style: none; border-left-style: none; - padding: 10px 20px 10px 60px; + padding: 10px 20px 0px 60px; } p { @@ -788,3 +788,25 @@ /* text-align: center; */ } +cite { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + border: 1px solid #e1e1e8; + background: #f7f7f9; + margin: 0 0 10px; + padding: 0 5px 0 5px; + font-size: 13px; + font-style: italic; +} + +.program { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + border: 1px solid #e1e1e8; + background: #f7f7f9; + margin: 0 0 10px; + padding: 0 5px 0 5px; + font-size: 13px; +} diff -Nru fdb-2.0.0/sphinx/usage-guide.txt fdb-2.0.1/sphinx/usage-guide.txt --- fdb-2.0.0/sphinx/usage-guide.txt 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/sphinx/usage-guide.txt 2018-04-30 15:17:55.000000000 +0000 @@ -31,8 +31,8 @@ Access to the database is made available through :class:`Connection` objects. FDB provides two constructors for these: -* :func:`connect` - Returns `Connection` to database that already exists. -* :func:`create_database` - Returns `Connection` to newly created database. +* :func:`connect` - Returns :class:`Connection` to database that already exists. +* :func:`create_database` - Returns :class:`Connection` to newly created database. .. index:: @@ -49,10 +49,6 @@ To establish a connection to database, you always must specify the database, either as `connection string` parameter `dsn`, or as required combination of parameters `host`, `database` and `port`. -.. important:: - - Current driver version ignores the value of `port` parameter. If you need to specify the port number, you have to use `dsn` parameter instead. - Although specification of `user` and `password` parameters is optional (if environment variables `ISC_USER` and `ISC_PASSWORD` are set, their values are used if these parameters are ommited), it's recommended practice to use them. Parameter `role` is needed only when you use Firebird roles. Connection options are optional (see `Firebird Documentation`_ for details). However you may often want to specify `charset`, as it directs automatic conversions of string data between client and server, and automatic conversions from/to unicode performed by FDB driver (see `Data handling and conversions`_ for details). @@ -154,11 +150,11 @@ with it: * `Executing SQL Statements`_: methods :meth:`~Connection.execute_immediate` and :meth:`~Connection.cursor`. -* Dropping database: method :meth:`~Connection.drop_database`. +* `Dropping database `_: method :meth:`~Connection.drop_database`. * `Transanction management`_: methods :meth:`~Connection.begin`, :meth:`~Connection.commit`, :meth:`~Connection.rollback`, :meth:`~Connection.savepoint`, :meth:`~Connection.trans`, :meth:`~Connection.trans_info` and :meth:`~Connection.transaction_info`, and attributes :attr:`~Connection.main_transaction`, :attr:`~Connection.transactions`, :attr:`~Connection.default_tpb` and :attr:`~Connection.group`. * Work with `Database Events`_: method :meth:`~Connection.event_conduit`. * `Getting information about Firebird version`_: attributes :attr:`~Connection.server_version`, :attr:`~Connection.firebird_version`, :attr:`~Connection.version` and :attr:`~Connection.engine_version`. -* `Getting information about database`_: methods :meth:`~Connection.db_info` and :meth:`~Connection.database_info`. +* `Getting information about database`_: attribute :class:`~fdb.Connection.monitor`, methods :meth:`~Connection.db_info` and :meth:`~Connection.database_info`. * :ref:`Getting information about database metadata `: attribute :attr:`~Connection.schema` and :attr:`~Connection.ods`. @@ -180,7 +176,7 @@ - :attr:`~Connection.version` - Only Firebird version number. It's a string with format: major.minor.subrelease.build - :attr:`~Connection.engine_version` - Engine (major.minor) version as (float) number. -FDB also provides convenient constants for supported engine versions: `ODS_FB_20`,`ODS_FB_21` and `ODS_FB_25`. +FDB also provides convenient constants for supported engine versions: `ODS_FB_20`, `ODS_FB_21` and `ODS_FB_25`. .. index:: pair: Database; On-disk Structure @@ -214,7 +210,7 @@ Firebird provides various informations about server and connected database via `database_info` API call. FDB surfaces this API through methods :meth:`~Connection.db_info` and :meth:`~Connection.database_info` on Connection object. -:meth:`Connection.database_info` is a `very thin` wrapper around function `isc_database_info()`. This method does not attempt to interpret its results except with regard to whether they are a string or an integer. For example, requesting `isc_info_user_names` with the call:: +:meth:`Connection.database_info` is a `very thin` wrapper around function :meth:`~fdb.ibase.fbclient_API.isc_database_info()`. This method does not attempt to interpret its results except with regard to whether they are a string or an integer. For example, requesting `isc_info_user_names` with the call:: con.database_info(fdb.isc_info_user_names, 's') @@ -265,7 +261,7 @@ The server is currently using 8931328 bytes of memory. We are connected to the database at C:\TEMP\TEST.DB on host WEASEL. -A more convenient way to access the same functionality is via the :meth:`~Connection.db_info` method, which is high-level convenience wrapper around the `database_info()` method that parses the output of database_info into Python-friendly objects instead of returning raw binary buffers in the case of complex +A more convenient way to access the same functionality is via the :meth:`~Connection.db_info` method, which is high-level convenience wrapper around the :meth:`~fdb.Connection.database_info()` method that parses the output of database_info into Python-friendly objects instead of returning raw binary buffers in the case of complex result types. For example, requesting `isc_info_user_names` with the call:: con.db_info(fdb.isc_info_user_names) @@ -341,10 +337,10 @@ Cursor object ------------- -Because `Cursor` objects always operate in context of single :class:`Connection` (and :class:`Transaction`), `Cursor` instances are not created directly, but by constructor method. Python DB API 2.0 assume that if database engine supports transactions, it supports only one transaction per connection, hence it defines constructor method :meth:`~Connection.cursor` (and other transaction-related methods) as part of :class:`Connection` interface. However, Firebird supports multiple independent transactions per connection. To conform to Python DB API, FDB uses concept of internal :attr:`~Connection.main_transaction` and secondary :attr:`~Connection.transactions`. Cursor constructor is primarily defined by +Because :class:`~fdb.Cursor` objects always operate in context of single :class:`Connection` (and :class:`Transaction`), :class:`~fdb.Cursor` instances are not created directly, but by constructor method. Python DB API 2.0 assume that if database engine supports transactions, it supports only one transaction per connection, hence it defines constructor method :meth:`~Connection.cursor` (and other transaction-related methods) as part of :class:`Connection` interface. However, Firebird supports multiple independent transactions per connection. To conform to Python DB API, FDB uses concept of internal :attr:`~Connection.main_transaction` and secondary :attr:`~Connection.transactions`. Cursor constructor is primarily defined by :class:`Transaction`, and Cursor constructor on `Connection` is therefore a shortcut for `main_transaction.cursor()`. -`Cursor` objects are used for next operations: +:class:`~fdb.Cursor` objects are used for next operations: * Execution of SQL Statemets: methods :meth:`~Cursor.execute`, :meth:`~Cursor.executemany` and :meth:`~Cursor.callproc`. * Creating :class:`PreparedStatement` objects for efficient repeated execution of SQL statements, and to obtain additional information about SQL statements (like execution :attr:`~PreparedStatement.plan`): method :meth:`~Cursor.prep`. @@ -464,7 +460,7 @@ * :meth:`~Cursor.itermap` - Equivalent to the :meth:`~Cursor.fetchallmap`, except that it returns :ref:`iterator ` rather than materialized list. -* Call to :meth:`~Cursor.execute` returns self (Cursor instance) that itself supports the :ref:`iterator protocol `, yielding tuples of values like :meth:`~Cursor.fetchone`. +* Call to :meth:`~Cursor.execute` returns `self` (Cursor instance) that itself supports the :ref:`iterator protocol `, yielding tuples of values like :meth:`~Cursor.fetchone`. .. important:: @@ -504,7 +500,7 @@ .. tip:: - :meth:`Cursor.execute` and :meth:`Cursor.executemany` return self, so you can use calls to them + :meth:`Cursor.execute` and :meth:`Cursor.executemany` return `self`, so you can use calls to them as iterators (see example above). .. index:: @@ -743,7 +739,7 @@ Implicit Conversion of Input Parameters from Strings ---------------------------------------------------- -The database engine treats most SQL data types in a weakly typed fashion: the engine may attempt to convert the raw value to a different type, as appropriate for the current context. For instance, the SQL expressions `123` (integer) and `‘123’` (string) are treated equivalently when the value is to be inserted into an `integer` field; the same applies when `‘123’` and `123` are to be inserted into a `varchar` field. +The Firebird database engine treats most SQL data types in a weakly typed fashion: the engine may attempt to convert the raw value to a different type, as appropriate for the current context. For instance, the SQL expressions `123` (integer) and `‘123’` (string) are treated equivalently when the value is to be inserted into an `integer` field; the same applies when `‘123’` and `123` are to be inserted into a `varchar` field. This weak typing model is quite unlike Python’s dynamic yet strong typing. Although weak typing is regarded with suspicion by most experienced Python programmers, the database engine is in certain situations so aggressive about its typing model that FDB must compromise in order to remain an elegant means of programming the database engine. @@ -1241,7 +1237,7 @@ :class:`Transaction` object exposes two methods that return information about currently managed active transaction (the same methods are exposed also by :class:`Connection` object for :attr:`~Connection.main_transaction`): -:meth:`~Transaction.transaction_info` is a very thin wrapper around function `isc_transaction_info()`. This method does not attempt to interpret its results except with regard to whether they are a string or an integer. +:meth:`~Transaction.transaction_info` is a very thin wrapper around function :meth:`~fdb.ibase.fbclient_API.isc_transaction_info()`. This method does not attempt to interpret its results except with regard to whether they are a string or an integer. A more convenient way to access the same functionality is via the :meth:`~Transaction.trans_info` method, which is high-level convenience wrapper around the `transaction_info` method that parses the output of `transaction_info` into Python-friendly objects instead of returning raw binary buffers in the case of complex result types. @@ -1583,7 +1579,7 @@ Transaction Context Manager --------------------------- -FDB provides context manager :class:`TransactionContext` that allows automatic transaction management using :ref:`WITH`. It can work with any object that supports `begin()`, `commit()` and `rollback()` methods, i.e. :class:`Connection`, :class:`ConnectionGroup` or :class:`Transaction`. +FDB provides context manager :class:`TransactionContext` that allows automatic transaction management using :ref:`WITH statement `. It can work with any object that supports `begin()`, `commit()` and `rollback()` methods, i.e. :class:`Connection`, :class:`ConnectionGroup` or :class:`Transaction`. It starts transaction when WITH block is entered and commits it if no exception occurst within it, or calls `rollback()` otherwise. Exceptions raised in WITH block are never suppressed. @@ -1933,7 +1929,7 @@ LI-V2.5.2.26536 Firebird 2.5 At first glance, this method appears to duplicate the functionality of the - :attr:`fdb.Connection.server_version` property, but when working with Firebird, there is a difference. :attr:`fdb.Connection.server_version` is based on a C API call (`isc_database_info()`) that existed long before the introduction of the Services API. Some programs written before the advent of Firebird test the version number in the return value of `isc_database_info()`, and refuse to work if it indicates that the server is too old. Since the first stable version of Firebird was labeled 1.0, this pre-Firebird version testing scheme incorrectly concludes that (e.g.) Firebird 1.0 is older than Interbase 5.0. + :attr:`fdb.Connection.server_version` property, but when working with Firebird, there is a difference. :attr:`fdb.Connection.server_version` is based on a C API call (:meth:`~fdb.ibase.fbclient_API.isc_database_info`) that existed long before the introduction of the Services API. Some programs written before the advent of Firebird test the version number in the return value of `isc_database_info()`, and refuse to work if it indicates that the server is too old. Since the first stable version of Firebird was labeled 1.0, this pre-Firebird version testing scheme incorrectly concludes that (e.g.) Firebird 1.0 is older than Interbase 5.0. Firebird addresses this problem by making `isc_database_info()` return a “pseudo-InterBase” version number, whereas the Services API returns the true Firebird version, as shown: @@ -2628,6 +2624,10 @@ Working with database schema ============================ +.. versionchanged:: 2.0 + + Module now uses :class:`~fdb.utils.ObjectList` for lists of schema objects. + Description of database objects like tables, views, stored procedures, triggers or UDF functions that represent database schema is stored in set of system tables present in every database. Firebird users can query these tables to get information about these objects and their relations. But querying system tables is inconvenient, as it requires good knowledge how this information is structured and requires significant amount of Python code. Changes in system tables between Firebird versions further add to this complexity. Hence FDB provides set of classes (isolated in separate module :mod:`fdb.schema`) that transform information stored in system tables into set of Python objects that surface the vital information in meaningful way, and additionaly provide set of methods for most commonly used operations or checks. Database schema could be accessed in three different ways, each suitable for different use case: @@ -2731,7 +2731,7 @@ Methods: -- :meth:`~fdb.schema.BaseSchemaItem.accept_visitor`: :ref:`Visitor Pattern support `. +- :meth:`~fdb.schema.BaseSchemaItem.accept`: :ref:`Visitor Pattern support `. - :meth:`~fdb.schema.BaseSchemaItem.issystemobject`: Returns True if this database object is system object. - :meth:`~fdb.schema.BaseSchemaItem.get_quoted_name`: Returns quoted (if necessary) name of database object. - :meth:`~fdb.schema.BaseSchemaItem.get_dependents`: Returns list of all database objects that :ref:`depend ` on this one. @@ -2839,6 +2839,28 @@ - reporting - :meth:`~fdb.utils.ObjectList.ecount`, :meth:`~fdb.utils.ObjectList.report` and :meth:`~fdb.utils.ObjectList.ireport` - fast key access - :attr:`~fdb.utils.ObjectList.key`, :attr:`~fdb.utils.ObjectList.frozen`, :meth:`~fdb.utils.ObjectList.freeze` and :meth:`~fdb.utils.ObjectList.get` +.. important:: Schema module uses :attr:`~fdb.utils.ObjectList.frozen` ObjectLists for fast access to individual list items using their `name` as a key. + +**Examples:** + +.. code-block:: python + + con = fdb.connect(dsn='employee',user='sysdba',password='masterkey') + + # Get list of all tables that have column named 'JOB_CODE', + job_code_tables = con.schema.tables.filter(lambda tbl: tbl.columns.any("item.name=='JOB_CODE'")) + + # Sorting tables by name + con.schema.tables.sort(attrs=['name']) + # Sorting tables by number of columns + con.schema.tables.sort(expr='len(item.columns)') + + # Return (table_name, num_columns) tuples + con.schema.tables.report(['item.name', 'len(item.columns)']) + + # Get ObjectLists for tables with computed and without computed columns + computed, no_computed = con.schema.tables.split(lambda tbl: tbl.columns.any("item.iscomputed()")) + .. _sql-operations: SQL operations @@ -3482,6 +3504,10 @@ Working with monitoring tables ============================== +.. versionchanged:: 2.0 + + Module now uses :class:`~fdb.utils.ObjectList` for lists of monitoring objects. + Starting from Firebird 2.1 (ODS 11.1) its possible to monitor server-side activity happening inside a particular database. The engine offers a set of “virtual” tables (so-called "monitoring tables") that provides the user with a snapshot of the current activity within the given database. FDB provides access to this information through set of classes (isolated in separate module :mod:`fdb.monitor`) that transform information stored in monitoring tables into set of Python objects that surface the information in meaningful way, and additionaly provide set of methods for available operations or checks. Like database schema, monitoring tables could be accessed in two different ways, each suitable for different use case: @@ -3571,7 +3597,7 @@ .. index:: HOOK_API_LOADED, HOOK_DATABASE_ATTACHED, HOOK_DATABASE_ATTACH_REQUEST .. index:: HOOK_DATABASE_DETACH_REQUEST, HOOK_DATABASE_CLOSED, HOOK_SERVICE_ATTACHED -FDB provides next *hook types* (exposed as constants in *fdb* namespace): +FDB provides next `hook types` (exposed as constants in *fdb* namespace): .. data:: HOOK_API_LOADED Binary files /tmp/tmpqZUWkW/_e56VPlxML/fdb-2.0.0/test/fbtest25.fdb and /tmp/tmpqZUWkW/3v29eh9iKh/fdb-2.0.1/test/fbtest25.fdb differ diff -Nru fdb-2.0.0/test/testfdb.py fdb-2.0.1/test/testfdb.py --- fdb-2.0.0/test/testfdb.py 2018-04-26 14:39:03.000000000 +0000 +++ fdb-2.0.1/test/testfdb.py 2019-07-08 09:48:05.000000000 +0000 @@ -220,6 +220,16 @@ dpb.extend([ibase.isc_dpb_no_garbage_collect, 1, 1]) dpb.extend([ibase.isc_dpb_no_db_triggers, 1, 1]) self.assertEqual(con._dpb, fdb.bs(dpb)) + # UTF-8 filenames (FB 2.5+) + with fdb.connect(dsn=self.dbfile, user=FBTEST_USER, password=FBTEST_PASSWORD, utf8params=True) as con: + self.assertIsNotNone(con._db_handle) + dpb = [1, 0x1c, len(FBTEST_USER)] + dpb.extend(ord(x) for x in FBTEST_USER) + dpb.extend((0x1d, len(FBTEST_PASSWORD))) + dpb.extend(ord(x) for x in FBTEST_PASSWORD) + dpb.extend((ord('?'), 1, 3)) + dpb.extend((77, 1, 1)) + self.assertEqual(con._dpb, fdb.bs(dpb)) def test_properties(self): with fdb.connect(dsn=self.dbfile, user=FBTEST_USER, password=FBTEST_PASSWORD) as con: self.assertIn('Firebird', con.server_version) @@ -2112,6 +2122,10 @@ blob_reader.seek(60) self.assertEqual(blob_reader.readline(), 'The database stores segmented blobs in chunks.\n') + self.assertIsInstance(blob_reader.blob_id, ibase.GDS_QUAD) + self.assertTrue(blob_reader.is_text) + self.assertEqual(blob_reader.blob_charset, None) + self.assertEqual(blob_reader.charset, 'UTF-8') def testBlobExtended(self): blob = """Firebird supports two types of blobs, stream and segmented. The database stores segmented blobs in chunks. @@ -3433,7 +3447,7 @@ 'INTEG_26', 'INTEG_27', 'INTEG_28', 'INTEG_29', 'INTEG_30']) self.assertListEqual([x.name for x in c.indices], - ['RDB$PRIMARY7', 'RDB$FOREIGN8', 'RDB$FOREIGN9', 'NAMEX']) + ['NAMEX', 'RDB$PRIMARY7', 'RDB$FOREIGN8', 'RDB$FOREIGN9']) self.assertListEqual([x.name for x in c.triggers], ['SET_EMP_NO', 'SAVE_SALARY_CHANGE']) # @@ -6528,6 +6542,7 @@ parser = fdb.trace.TraceParser() for obj in parser.parse(linesplit_iter(trace_lines)): self.printout(str(obj)) + #print(self.output.getvalue()) self.assertEqual(self.output.getvalue(), output, "Parsed events do not match expected ones") def test_trace_init(self): trace_lines = """2014-05-23T11:00:28.5840 (3720:0000000000EFD9E8) TRACE_INIT @@ -7606,12 +7621,12 @@ EventServiceQuery(event_id=4, timestamp=datetime.datetime(2018, 4, 3, 12, 56, 27, 559000), status=' ', service_id=140138600699200, action='Repair Database', parameters=[]) """ if sys.version_info.major == 2 and sys.version_info.minor == 7 and sys.version_info.micro > 13: - output = """ServiceInfo(service_id=140646174008648L, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=385) -EventServiceQuery(event_id=1, timestamp=datetime.datetime(2018, 3, 29, 14, 2, 10, 918000), status=' ', service_id=140646174008648L, action='Start Trace Session', parameters=['Receive portion of the query:', 'retrieve 1 line of service output per call']) -ServiceInfo(service_id=140138600699200L, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=4631) -EventServiceQuery(event_id=2, timestamp=datetime.datetime(2018, 4, 3, 12, 41, 1, 797000), status=' ', service_id=140138600699200L, action=None, parameters=['retrieve the version of the server engine']) -EventServiceQuery(event_id=3, timestamp=datetime.datetime(2018, 4, 3, 12, 41, 30, 784000), status=' ', service_id=140138600699200L, action=None, parameters=['retrieve the implementation of the Firebird server']) -EventServiceQuery(event_id=4, timestamp=datetime.datetime(2018, 4, 3, 12, 56, 27, 559000), status=' ', service_id=140138600699200L, action='Repair Database', parameters=[]) + output = """ServiceInfo(service_id=140646174008648, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=385) +EventServiceQuery(event_id=1, timestamp=datetime.datetime(2018, 3, 29, 14, 2, 10, 918000), status=' ', service_id=140646174008648, action='Start Trace Session', parameters=['Receive portion of the query:', 'retrieve 1 line of service output per call']) +ServiceInfo(service_id=140138600699200, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=4631) +EventServiceQuery(event_id=2, timestamp=datetime.datetime(2018, 4, 3, 12, 41, 1, 797000), status=' ', service_id=140138600699200, action=None, parameters=['retrieve the version of the server engine']) +EventServiceQuery(event_id=3, timestamp=datetime.datetime(2018, 4, 3, 12, 41, 30, 784000), status=' ', service_id=140138600699200, action=None, parameters=['retrieve the implementation of the Firebird server']) +EventServiceQuery(event_id=4, timestamp=datetime.datetime(2018, 4, 3, 12, 56, 27, 559000), status=' ', service_id=140138600699200, action='Repair Database', parameters=[]) """ self._check_events(trace_lines, output) def test_set_context(self): @@ -7673,8 +7688,8 @@ EventError(event_id=1, timestamp=datetime.datetime(2018, 3, 22, 10, 6, 59, 509000), attachment_id=0, place='jrd8_attach_database', details=['335544344 : I/O error during "open" operation for file "/home/test.fdb"', '335544734 : Error while trying to open file', '2 : No such file or directory']) AttachmentInfo(attachment_id=519417, database='/home/test.fdb', charset='WIN1250', protocol='TCPv4', address='172.19.54.61', user='SYSDBA', role='NONE', remote_process='/usr/bin/flamerobin', remote_pid=4985) EventError(event_id=2, timestamp=datetime.datetime(2018, 3, 22, 11, 0, 59, 509000), attachment_id=519417, place='jrd8_fetch', details=['335544364 : request synchronization error']) -ServiceInfo(service_id=140138600699200L, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=4631) -EventServiceError(event_id=3, timestamp=datetime.datetime(2018, 4, 3, 12, 49, 28, 508000), service_id=140138600699200L, place='jrd8_service_query', details=['335544344 : I/O error during "open" operation for file "bug.fdb"', '335544734 : Error while trying to open file', '2 : No such file or directory']) +ServiceInfo(service_id=140138600699200, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=4631) +EventServiceError(event_id=3, timestamp=datetime.datetime(2018, 4, 3, 12, 49, 28, 508000), service_id=140138600699200, place='jrd8_service_query', details=['335544344 : I/O error during "open" operation for file "bug.fdb"', '335544734 : Error while trying to open file', '2 : No such file or directory']) """ self._check_events(trace_lines, output) def test_warning(self): @@ -7695,8 +7710,8 @@ if sys.version_info.major == 2 and sys.version_info.minor == 7 and sys.version_info.micro > 13: output = """AttachmentInfo(attachment_id=0, database='/home/test.fdb', charset='NONE', protocol='TCPv4', address='127.0.0.1', user='sysdba', role='NONE', remote_process='/usr/bin/flamerobin', remote_pid=4985) EventWarning(event_id=1, timestamp=datetime.datetime(2018, 3, 22, 10, 6, 59, 509000), attachment_id=0, place='jrd8_attach_database', details=['Some reason for the warning.']) -ServiceInfo(service_id=140138600699200L, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=4631) -EventServiceWarning(event_id=2, timestamp=datetime.datetime(2018, 4, 3, 12, 49, 28, 508000), service_id=140138600699200L, place='jrd8_service_query', details=['Some reason for the warning.']) +ServiceInfo(service_id=140138600699200, user='SYSDBA', protocol='TCPv4', address='127.0.0.1', remote_process='/job/fbtrace', remote_pid=4631) +EventServiceWarning(event_id=2, timestamp=datetime.datetime(2018, 4, 3, 12, 49, 28, 508000), service_id=140138600699200, place='jrd8_service_query', details=['Some reason for the warning.']) """ self._check_events(trace_lines, output) def test_sweep_start(self): @@ -8700,7 +8715,8 @@ self.assertFalse(olist.all('item.size > 0')) self.assertTrue(olist.all('item.size < 200')) self.assertTrue(olist.any('item.size > 0')) - self.assertFalse(olist.any('item.size < 200')) + self.assertTrue(olist.any('item.size < 200')) + self.assertFalse(olist.any('item.size > 300')) class TestGstatParse(FDBTestBase): def setUp(self):