mysql-connector-c++-1.1.7/.bzrignore000644 015771 000012 00000000423 12645244436 017764 0ustar00pb2userwheel000000 000000 *.lo *.la *.spec *.vcproj *.vcxproj *.vcxproj.* *.sln *.ncb *.suo *.user *.pdb *.manifest *.wixobj *.msi *.diff Makefile Makefile.in CMakeCache.txt .deps .libs CMakeFiles *.dir [dD]ebug [rR]el[wW]ith[dD]eb[iI]nfo [rR]elease cppconn/config.h driver/nativeapi/binding_config.h mysql-connector-c++-1.1.7/ANNOUNCEMENT000644 015771 000012 00000007447 12645244436 017614 0ustar00pb2userwheel000000 000000 MySQL Connector/C++ This is a release of MySQL Connector/C++, Oracle's dual-license C++ API for connecting client applications to MySQL. Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. -------------------------------------------------------------------------------- Dear MySQL Users, A new GA (general availability) version of MySQL Connector/C++ has been made available: MySQL Connector/C++ 1.1.7 GA. The MySQL Connector/C++ provides a C++ API for connecting client applications to the MySQL Server 5.5 or newer. You can download the production release at: http://dev.mysql.com/downloads/connector/cpp/1.1.html MySQL Connector C++ (Commercial) will be available for download on the My Oracle Support (MOS) website. This release will be available on eDelivery (OSDC) in next month's upload cycle. The MySQL driver for C++ offers an easy to use API derived from JDBC 4.0. MySQL Workbench has used it successfully for years. We have improved the driver since the last GA release. Please see the documentation and the CHANGES file in the source distribution for a detailed description of bugs that have been fixed. Bug descriptions are also listed below. Enjoy! ====================================================================== Changes in MySQL Connector/C++ 1.1.7 Configuration Notes * Binary distributions for this release of MySQL Connector/C++ were linked against libmysqlclient from MySQL 5.7.10, except for OS X 10.8/10.9, for which distributions were linked against MySQL 5.7.9. This enables Connector/C++ to take advantage of features present in recent client library versions. Some examples: + Support for the MySQL JSON data type is available. Current versions of MySQL Workbench require JSON support, so to build MySQL Workbench 6.3.5 or higher from source, it is necessary to use a version of Connector/C++ at least as recent as 1.1.7. + Applications will attempt to establish a secure (encrypted) connection by default whenever the server is enabled to support secure connections, and fall back to an unencrypted connection otherwise. (This is as described at Configuring MySQL to Use Secure Connections (http://dev.mysql.com/doc/refman/5.7/en/using-secure -connections.html).) To enforce a secure connection, such that an error occurs if secure connections are not available, applications can enable the sslEnforce connection option. To build Connector/C++ from source, you must use either a General Availability version of MySQL 5.7 (5.7.9 or higher) or Connector/C 6.1.8 or higher. Set the MYSQL_DIR CMake option appropriately at configuration time as necessary. (Bug #22351273) Security Notes * The linked OpenSSL library for Connector/C++ Commercial has been updated to version 1.0.1q. Issues fixed in the new OpenSSL version are described at http://www.openssl.org/news/vulnerabilities.html. This change does not affect Oracle-produced MySQL Community builds of Connector/C++, which use the yaSSL library instead. Spatial Data Support * The required version of the Boost library for Connector/C++ builds has been raised to 1.56.0. Bugs Fixed * MySQL_Prepared_ResultSet::relative() failed to fetch the record due to a missing proxy->fetch() call. (Bug #21152054) * During Connector/C++ builds, the MySQL Server CXXFLAGS and CFLAGS values were used rather than the system default values. To specify explicitly to use the server values, enable the new USE_SERVER_CXXFLAGS CMake option. (Bug #77655, Bug #21391025) Enjoy! mysql-connector-c++-1.1.7/CHANGES000644 015771 000012 00000063031 12645244436 016761 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ GA 1.1.7 - - Add JSON support - Allow building without server flags (Bug#21391025) - Correct relative() not seeking after changing position.(Bug#21152054) GA 1.1.6 - - C/C++ won't build against Boost-devel-1.41.0-25.EL6.I686 (Bug#20125824) - Make install fail for out of source build (Bug#19447498) - Segmentation fault in retrieval of value using getter methods when defaultstatementresulttype=forward_only and row position is after last row. (Bug#20085944) - C/C++ should provide libmysqlclient and boost version macros with which it is build. (Bug#75250) - C++11 support and replace deprecated auto_ptr. (Bug#75251) - wasNull() method call before fetching the data results in assert failure (Bug#19938873) - Memory leak if result set of prepared statement used (Bug#18135088/wl#7925) - ResultSet::getString does not return fractional seconds from DATETIME(N) columns (Bug#68523) - make install/fast fails if static library is not built (Bug#52281) - MySQL_ResultSet::getString() returns bad value for BIT data (Bug#66235) GA 1.1.5 - - DatabaseMetaData::getProcedures() returns syntax error for connection option metadatauseinfoschema=false (Bug#19505421) - DatabaseMetaData::getColumns() returns empty resultset when metadataUseInfoSchema is true and for no schema. (Bug#19147897) - ResultSetMetaData::getColumnName() returns display name instead of actual column name. (Bug#19244736) - ResultSetMetaData::getTables() not returning result for VIEW when metadatauseinfoschema=false. (Bug#19505348) - Version macros missing from installed headers file. (Bug#19553971) - Getting multiple resultset from procedure using prepared statement gives error (Bug#19147677). - Connection losses are not detected while fetching resultset using next() (Bug#18886278/69031). - Remove boost variant from API (wl#7030) - Make close() method or destructor of Connection object to always close the connection with server (wl#7028) - Added max_statement_timeout and other connect options (MYSQL_DEFAULT_AUTH, MYSQL_PLUGIN_DIR, MYSQL_SET_CHARSET_DIR, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_LOCAL_INFILE) (Bug#19479950) - Added missing sort order for DatabaseMetaData::getImportedKeys() and DatabaseMetaData::getIndexInfo() for no_i_s case. (Bug#19505248) - There is no reconnection function in Connector/C++ (Bug#14207722) - WB sends unnecessary COM_PING operations. (Bug#17186530) - Double free or corruption error due to global extern string variable localhost referenced at more then one places (Bug#19910311) - Assertion failure in getClientOption when the provided option is not set (Bug#19938922) - Memory leak while adding parameter OPT_CONNECT_ATTR_ADD to options list (Bug#19938970) - CMake picking up libmysqlclient from system path (Bug#19940663) GA 1.1.4 - - Both static and dynamic driver libraries are now linked statically against libmysql library - Cannot Connect error when using legacy authentication. (Bug#16970753/69492) - Connector/C++ doesn't implement MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH. Introduced connection options "sslVerify"(boolean), "sslCRL" and "sslCRLPath"(string). (Bug#18461451) - Methods returning driver version information are now parametrized, and those parameters take their values from cmake config (Bug#14680878/66975) - Added MYSQL_OPT_CONNECT_ATTR_ADD connection option accepting std::map argument and calls mysql_options4(). (Bug#18803313) - MySQL_ResultSetMetaData::getColumnTypeName() returns UNKNOWN for LONG_BLOB fields. (Bug#18803414/72700) - Missing collation info in the column metadata methods for a result. (Bug#18803345/72698) - Added connection option "rsaKey" to specify RSA public key path name (wl#7972). - Built against libmysql 5.6. GA 1.1.3 - 2013-03-22 - Added boolean connection option OPT_ENABLE_CLEARTEXT_PLUGIN allowing to enable cleartext libmysql plugin. That plugin is required for some authentication methods, e.g. PAM. (Bug#16520952) - getBestRowIdentifier() now considers unique not nullable indexes in case when primary key does not exist. (Bug#16277170) - False value of the metadataUseInfoSchema connection option had no effect in database metadata object. GA 1.1.2 - 2013-01-16 - Expired password support. Connection options OPT_CAN_HANDLE_EXPIRED_PASSWORDS(bool, application can deal with expired passwords), and preInit(string, commands to run prior to driver initialization commands) have been introduced. (Bug#15936764/67325) - postInit connection string has been introduced. Similar to preInit, but commands are run after driver's initialization. - Statement::executeUpdate can now execute multiple statements. CLIENT_MULTI_STATEMENTS connection option still has to be selected. getUpdateCount will return data for the last executed statement. - ABI change - MySQL_Connection class object size changed. If you don't use that class directly you shouldn't be affected by that. - Built against libmysql 5.6.10 GA 1.1.1 - 2012-08-06 - DatabaseMetaData::getSQLKeywords() updated to match MySQL 5.5. Note that C/C++, just like C/JDBC, returns the same list for every MySQL database version. (Ulf) - Added MySQL_Connection::getLastStatementInfo() which returns back the value of the mysql_info() function of libmysql / Connector/C. (Andrey) - Added new method ResultSetMetaData::isNumeric() and implemented it in all classes that subclass from it. (Andrey) - Fixed the bug causing compilation errors in Microsoft Visual Studio 2010 if stdint.h was included. See http://bugs.mysql.com/bug.php?id=60307 - Fixed bug making statement that did not raise any warning to return warnings from previously executed statement. - Fixed stores(Lower|Mixed)Case(Quoted)Identifiers methods. - Built against libmysql 5.5.27 enabling support of authentification plugins and IPv6. GA 1.1.0 - 2010-09-13 - Added Driver::threadInit() and Driver::threadEnd() methods. Every thread of a threaded client must call Driver::threadInit() at the very start of the thread before it does anything else with Connector/C++ and every thread must call Driver::threadEnd() when it finishes. You can find an example demonstrating the use in examples/pthreads.cpp. It is strongly discouraged to share connections between threads. It is theoretically possible, if you set certain undocumented mutexes, but it is not supported at all. Use one connection per thread. Do not have two threads using the same connection at the same time. Please check the C API notes on threading on the MySQL manual. Connector/C++ wraps the C API. (Lawrin, Andrey, Ulf) - Fixed ResultSetMetaData::getColumnType() to return sql::DataType::VARCHAR even for multi-type character sets. (Fix from Andrey) - Fixed ResultSetMetaData::getColumnDisplaySize() to return number of characters instead of number of bytes. However, there are cases when the MySQL server returns wrong or insufficient meta data, see also http://bugs.mysql.com/bug.php?id=6399 . Application developers can rely on getColumnDisplaySize() returning at least the number of required characters. Application developers shall not expect the exact number for a given result set. The driver cannot get any closer but returning the maximum number for a given result set (Fix from Andrey) - Changed FindMySQL.cm so it looks for mysqlclient in the ENV{MySQL_DIR}\lib, as that is where it's located in (some) Connector/C distros. (Lawrin) - Fixed bug in CmakeLists.txt - it didn't really use ENV{BOOST_ROOT}, boost wasn't searched in the directory set in that environment variable. (Lawrin) - Fixed http://bugs.mysql.com/bug.php?id=51562 : error messages did not get reported properly if error occured after query execution and before fetching data within the underlying C API call mysql_use|store_result. (Andrey) - BIT fields are now correctly decoded (Workbench bug #36239). (Andrey) - Connection::getClientOption(const sql::SQLString & optionName, void * optionValue) now accepts the optionName values "metadataUseInfoSchema", "defaultStatementResultType", "defaultPreparedStatementResultType", "characterSetResults". In the previous version only "metadataUseInfoSchema" was allowed. The same is true for Connection::setClientOption(). - Fixed Bug #45048 "prepared statements corrupt the heap". ResultBind is back in the prepared statement, but shared with the result set. (Andrey) - get_driver_instance() is only available in dynamic library builds, static builds won't have this symbol. This is done, because someone might decided to load the dll with LoadLibrary/dlopen and needs an entry point to start using the library (some kind of a Driver Manager). For those, who don't use cmake for building you need to define mysqlcppconn_EXPORTS if you are loading dynamically and want to use that entry point. (Andrey) - ABI change - added support for optional run-time dynamic loading of the MySQL Client Library. This is useful if you want to re-distribute a certain client library with the connector and make sure that it gets used. It also allows you to use a different client library for every connection. As it is an advanced feature it is not enabled by default. By default the MySQL Client Library will be linked at compile time just as in every version before. - Fixed bug in ResultSetMetaData for normal statements and prepared ones, getScale and getPrecision did return wrong results. (Andrey) - Fixed http://bugs.mysql.com/bug.php?id=45846 . Excluding dynamically generated and platform specific header files source packages generated using cpack (Ulf). - Connection map property OPT_RECONNECT is now of type boolean (was long long). - We now check LDFLAGS, CXXFLAGS and CPPFLAGS from the environment for every binary we generate. (Ulf, Kent) - Fixed http://bugs.mysql.com/bug.php?id=45843: cmake error if configuring an out of source build [when not calling cmake in the root directory]. (Ulf) - Fixed http://bugs.mysql.com/bug.php?id=44931: missing includes when using GCC 4.4. Note that GCC 4.4 is not yet in use for any official MySQL builds. (Ulf, Lawrin) - Fixed a performance issue of Prepared Statements. Reading large result sets has been slow - think O(n^2). Patch by Frank Schoenheit from the OpenOffice.org Base team. (Ulf) - Exchanged most use cases of std::auto_ptr with boost::scoped_ptr. Migrated from own solution to boost::scoped_array. In addition, migrated from another own solution to boost::shared_ptr/weak_ptr for guarding access around result sets. (Andrey) - API incompatible change: ConnectPropertyVal is no more a struct by a typedef that uses boost::variant. This will break your build but is pretty easy to fix. If you had code like --- { sql::ConnectPropertyVal tmp; tmp.str.val=passwd.c_str(); tmp.str.len=passwd.length(); connection_properties["password"] = tmp; } --- Your new code you will like this: --- connection_properties["password"] = sql::ConnectPropertyVal(passwd); --- Which is simpler. (Andrey) - Fixed a bug in PS, which in combination of preparing a stored procedures without any parameters was leading to exception, which was a problem, and was leading to another problem which manifested itself with double free. All similar code snippets in the Connector were fixed. (Andrey) - The driver makes use of some Boost components (http://www.boost.org). You need to have Boost 1.34.0 or newer installed on your system in order to compile the driver from source. Binary distributions have no additional dependencies over 1.0.5. - API change: parameter to setNextQuery in SQLWarning got const qualifier. SQLWarning itself is now an interface with protected destructor. GA 1.0.5 - 2009-04-20 - Changed the interface of sql::ConnectionMetaData, sql::ResultSetMetaData and sql::ParameterMetaData to have a protected destructor. In this way the client code doesn't need, and won't be able, to destruct the metadata objects returned by the connector. The connector will handle their destruction. This enables statements like : connection->getMetaData->getSchema(); without the result of leaking memory because we lost the pointer returned by getMetaData(). (Lawrin, Andrey) - Large overhaul of the code to improve the memory management to not leak in exceptional situations. Big improvement compared to Beta1. (Andrey) - Fixed the interface of sql::Driver and sql::Connection so they accept the options map by alias instead of by value. (Andrey) - Changed the return type of sql::SQLException::getSQLState() from std::string to const char * to be consistent with std::exception::what(). (Andrey) - Implemented getResultSetType() and setResultSetType() for Statement. Used are TYPE_FORWARD_ONLY, which means unbuffered result set and TYPE_SCROLL_INSENSITIVE, which means buffered result set. (Andrey) - Implemented getResultSetType() for PreparedStatement. The setter is not implemented because currently PreparedStatement can't do refetching and storing the result means the bind buffers will be correct. (Andrey) - Added "defaultStatementResultType" to MySQL_Connection::setClientOption() as an option. Also the method now returns `sql::Connection *`. (Andrey) - Added Result::getType() and implemented it in the three result set classes. (Andrey) - Enabled tracing functionality when building with VC8 and up (VS2005 and up). (Andrey) - Added better support for named pipes, on Windows. Use pipe:// and add the path to the pipe. Shared memory connections are currently not supported. (Andrey) - Fixed a bug in MySQL_Connection::setSessionVariable() which led to exception being thrown. (Andrey) Beta 1.0.4 - 2009-03-31 - Prepared support for upcoming Connector/C. (Georg) - Added Windows installer. (Georg) - Bumping up CMake minimum version requirement from 2.4.2 to 2.6.2. We need the latest version for Windows. (Lawrin) - Added "metadataUseInfoSchema" to connection propery map which allows you to control the use of the INFORMATION_SCHEMA for meta data. (Andrey) - Fixed a bug in all implementations of ResultSet::relative() which was giving wrong return value although positioning was working correctly. (Andrey) - Fixed a leak in MySQL_PreparedResultSet when the result was containing a BLOB column. (Andrey) - Implemented MySQL_ConnectionMetaData::supportsConvert(from, to). (Andrey) - Introduced sql::DataType::YEAR to complement MySQL's YEAR type. (Andrey) - Introduced PreparedStatement::getMetaData(). (Andrey) - Introduced ResultSetMetaData::isZerofill(), which is not in the JDBC specification. (Andrey) - Fixed all implementations of ResultSet::isNull() to check whether the current position is on a real row, not isBeforeFirst() nor isAfterLast(), like all getXXX methods do. (Andrey) - Implementation for MySQL_DatabaseMetaData::getProcedures() when INFORMATION_SCHEMA is asked not to be used. (Andrey) - Removed MySQL_DatabaseMetaData::getProcedureColumns() from the interface. Until now it was returning always an empty result set. Full implementation will be added at a later stage. (Andrey) - Changed a bunch of methods of DatabaseMetaData()::getXXX, which returned `int` to return `unsigned int` because it makes more sense. (Andrey) Alpha 1.0.3 - 2009-03-03 - Added new tests at test/unit/classes. Those tests are mostly about code coverage. Most of the actual functionality of the driver is tested by the tests found at test/CJUnitPort. (Ulf) - New data types added to the list returned by DatabaseMetaData::getTypeInfo(); FLOAT UNSIGED, DECIMAL UNSIGNED, DOUBLE UNSIGNED. Those tests may not be in the JDBC specification. However, due to the change you should be able to look up every type and type name returned by, for example, ResultSetMetaData::getColumnTypeName(). (Andrey) - MySQL_Driver::getPatchVersion introducted. (Andrey) - Major performance improvements due to new buffered resultset implementation by Andrey. (Ulf) - Addition of test/unit/README with instructions for writing bug/regression tests. (Ulf) - Experimental support for STLPort. This feature may be removed again at any time later without prior warning! Check cmake -L for configuration instructions. (Andrey) - Fixed a bug in MySQL_PreparedResultSet::getString(). Returned string had real data but the length was random. Now, the string is initialized with correct length and thus is binary safe. (Andrey) - Added properties-enabled (map of key->value) methods for connecting, which add many connect options. (Andrey) -- Driver::connect( map ) -- Connection::Connection( map ) - New BLOB implementation. Got rid of sql::Blob in favor of std::istream. C++'s IOStream library is very powerful, similar to PHP's streams. It makes no sense to reinvent the wheel. For example one can pass a std::istringstream object to setBlob() if the data is in memory, or just open a file std::fstream and let it stream to the DB, or write own stream. Similar will be true for getBlob() where we can just copy data, if buffered result set, or stream, if we implement it. (Andrey) - Implemented ResultSet::getBlob() which returns std::stream. (Andrey) - Fixed MySQL_DatabaseMetaData::getTablePrivileges() to work correctly. Test cases added in the first unit testing framework. (Andrey) - Implemented MySQL_Connection::setSessionVariable() for setting variables like sql_mode. (Andrey) - Implemented MySQL_DatabaseMetaData::getColumnPrivileges(). (Andrey) - cppconn/datatype.h changed and used again. Reimplemented the type subsystem to be more usable - more types for binary and non-binary strings. (Andrey) - Implementation for MySQL_DatabaseMetaData::getImportedKeys() for MySQL versions before 5.1.16 using SHOW, and above using INFORMATION_SCHEMA. (Andrey) - Implemented MySQL_ConnectionMetaData::getProcedureColumns(). (Andrey) - make package_source packs now with bzip2. (Andrey) - Re-added getTypeInfo() with information about all types supported by MySQL and the sql::DataType. (Andrey) - Exchanged the implementation of MySQL_ConstructedResultSet to use more efficient non O(n) but O(1) access method. This should improve the speed with which the metadata result sets are used. Also, there is less copy during the construction of the result set, which means that all result sets returned from the metadata functions will be faster. (Andrey) - Introduced, internally, sql::mysql::MyVal which has implicit constructors used in mysql_metadata.cpp to create result sets with more native data instead of always string (varchar). (Andrey) - Renamed ResultSet::getLong() to ResultSet::getInt64(). resultset.h includes typdefs for Windows to be able to use int64_t. (Andrey) - Introduced ResultSet::getUInt() and ResultSet::getUInt64(). (Andrey) - Corrected handling of unsigned server types. Now returning correct values. (Andrey) - Fixed handling of numeric columns in ResultSetMetaData::isCaseSensitive to return false. (Andrey) - Better implementation for ResultSetMetaData::isReadOnly. Values generated from views are read-only. Seems that these generated values don't have `db` in MYSQL_FIELD set, while all normal columns do have. (Andrey) - Implemented MySQL_DatabaseMetaData::getExportedKeys(). (Andrey) - Implemented MySQL_DatabaseMetaData::getCrossReference(). (Andrey) Alpha 1.0.2 - 2008-12-19 - Adding test/unit as a basis for general unit tests based on the new test framework, see test/unit/example for basic usage examples (Ulf) - Fixed MySQL_PreparedStatement::setBlob() to really work. In the tests there is a simple example of a class implementing sql::Blob. (Andrey) - Addition of a new unit test framework for JDBC compliance and regression testing. (Lawrin) - Implemented MySQL_ResultSetMetaData::getPrecision() and MySQL_Prepared_ResultSetMetaData::getPrecision(), updating example. (Andrey) - Fixing bug in FLOAT handling. (Andrey) - Fixing bug in getString(): getString() is binary safe now (Andrey), new example. (Ulf) - Fixing bugs in MySQL_PreparedStatements: setBigInt() and setDatetime() have decremented the internal column index before forwarding the request. This resulted in double-decrement and wrong internal column index. Typical error message: setString() ... invalid "parameterIndex" (Ulf) - Adding PHP script examples/cpp_trace_analyzer.php to filter the output of the debug trace. Please see the inline comments for documentation. This script is unsupported! We do no promise to maintain it. (Ulf) - Fixed bugs in MySQL_DatabaseMetaData : All supportsCatalogXXXXX methods were returning `true` and all supportSchemaXXXX methods false, which is not as it should be. Now it is reversed, to be consistent with the rest. (Andrey) - Implemented MySQL_PreparedStatement::clearParameters(). (Andrey) - Fixed a bug in MySQL_ConnectionMetaData::getColumns() which was performing a cartesian product of the columns in the table times the columns matching columnNamePattern. example/connection_meta_schemaobj.cpp extended to cover the function. (Andrey) - Fixed lame bug in MySQL_ConnectionMetaData::getIndexInfo() which did not work because the schema name wasn't included in the query sent to the server. (Andrey) - Implemented MySQL_PreparedStatement::setNull(). (Andrey) - Reverted implementation of MySQL_DatabaseMetaData::getTypeInfo(). Now unimplemented. In addition, removed cppconn/datatype.h for now till we havea proper implementation of the types. - DATE, DATETIME and TIME are now being handled when calling MySQL_PreparedResultSet:: -- getString() -- getDouble() -- getInt() -- getLong() -- getBoolean() - Fixed MySQL_PreparedStatementResultSet::getDouble() to return proper value when the underlying type is MYSQL_TYPE_FLOAT. (Andrey) - Changed ResultSetMetaData:: -- getColumnDisplaySize() -- getPrecision() -- getScale() to return unsigned int instead of signed int. (Andrey) - Implemented getScale(), getPrecision() and getColumnDisplaySize() for MySQL_ResultSetMetaData and MySQL_Prepared_ResultSetMetaData. (Andrey) Alpha 1.0.1 - 2008-12-01 - New directory layout - MySQL Workbench 5.1 using Connector/C++ for its database connectivity. - Addition of Connector/J tests converted - Changing sql::DbcException to implement the interface of JDBC's SQLException. And renamed it to sql::SQLException. - Renamed sql::DbcInvalidArgument to sql::InvalidArgumentException - Renamed sql::DbcMethodNotImplemented to sql::MethodNotImplementedException - All tests changed to create TAP compliant output - Introduction of experimental CPack support, see make help - Metadata: switching to column names "TABLE_CAT" (was: TABLE_CATALOG) and "TABLE_SCHEM" (was: TABLE_SCHEMA) for JDBC compliance - ConnectionMetaData::getImportedKeys(): PKTABLE_CATALOG -> PKTABLE_CAT, PKTABLE_SCHEMA -> PKTABLE_SCHEM, FKTABLE_CATALOG -> FKTABLE_CAT, FKTABLE_SCHEMA -> FKTABLE_SCHEM - ConnectionMetaData::getPrimaryKeys(): COLUMN -> COLUMN_NAME, SEQUENCE -> KEY_SEQ, INDEX_NAME -> PK_NAME - ConnectionMetaData::getProcedures: PROCEDURE_SCHEMA -> PROCEDURE_SCHEM - ConnectionMetaData::getTables: TABLE_COMMENT -> REMARKS - All examples can be given optional connection parameters on the command line, for example `examples/connect tcp://host:port user pass database` or `examples/connect unix:///path/to/mysql.sock user pass database` - Adding experimental GCov support, cmake -DMYSQLCPPCONN_GCOV_ENABLE:BOOL=1 - ConnectionMetaData::getCatalogTerm() returns n/a, there is no counterpart to catalog in Connector/C++ - Addition of ConnectionMetaData::getSchemas() and Connection::setSchema(). None of them is in the JDBC standard - Driver Manager removed - `(n)make install` works. You can change the default installation path. Read carefully the messages after executing cmake. Installed are the static and the dynamic version of the library, libmysqlcppconn as well as the generic interface cppconn + 3 MySQL specific headers -- mysql_driver.h (if you want to get your connections from the driver instead of instantiating a MySQL_Connection object. This makes your code pretty portable against the common interface) -- mysql_connection.h - If you intend to link directly to the MySQL_Connection class and use its specifics not found in sql::Connection However, you can make your application fully abstract by not using the two headers above but the generic headers. - sql::mysql::MySQL_SQLException is gone. There is no distinction between server and client (= Connector) caused errors based on the type of the exception. However, you can still check the error code to figure out the reason. Preview 1.0.0 - 2008-08-05 - First public release mysql-connector-c++-1.1.7/CMakeLists.txt000755 015771 000012 00000037430 12645244436 020535 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # PROJECT(MYSQLCPPCONN) cmake_minimum_required(VERSION 2.6.2) IF(COMMAND cmake_policy AND POLICY CMP0015) cmake_policy(SET CMP0015 NEW) ENDIF(COMMAND cmake_policy AND POLICY CMP0015) INCLUDE(VersionInfo.cmake) OPTION(TAR_LAYOUT "Use directory layout for an unpacked TAR install") OPTION(RPM_LAYOUT "Use directory layout for an RPM install") IF(TAR_LAYOUT OR NOT CMAKE_VERSION OR CMAKE_VERSION VERSION_LESS "2.8.5") SET(INSTALL_LIBDIR lib) ELSE() INCLUDE(GNUInstallDirs) SET(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}) ENDIF() SET(EDIT_WARNING_MESSAGE "Please do not edit this file - it is generated by cmake. Edit its source file instead.") # Configuring header file with driver version info CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/driver/version_info.h.cmake ${CMAKE_BINARY_DIR}/driver/version_info.h @ONLY) # This is needed by windows installer and fro CPACK IF(EXISTS "${CMAKE_SOURCE_DIR}/COPYING") SET(LICENSE_FILENAME "${CMAKE_SOURCE_DIR}/COPYING") ELSE(EXISTS "${CMAKE_SOURCE_DIR}/COPYING") SET(LICENSE_FILENAME "${CMAKE_SOURCE_DIR}/LICENSE.mysql") ENDIF(EXISTS "${CMAKE_SOURCE_DIR}/COPYING") # Creating file with version info that will be used for installer # We have to do this trick because of license filename that is looked in this CMAKE_SOURCE_DIR (installer's cmake is run separately) IF(WIN32) FILE(WRITE "${CMAKE_BINARY_DIR}/win/config.cmake" "SET(CONNECTOR_PRODUCT_VERSION ${CONNECTOR_VERSION})\n" "SET(LICENSE_FILENAME \"${LICENSE_FILENAME}\")\n") ENDIF(WIN32) #----------------- # CPPFLAGS, CXXFLAGS and LDFLAGS from the environment IF(CMAKE_ENABLE_C++11) INCLUDE(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) IF(COMPILER_SUPPORTS_CXX11) MESSAGE(STATUS "Compiler supports C++11. Adding -std=c++11 flags") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") ELSEIF(COMPILER_SUPPORTS_CXX0X) MESSAGE(STATUS "Compiler supports C++11. Adding -std=c++0x flag.") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") ELSE() MESSAGE(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} doesn't support C++11. Please use a different compiler.") ENDIF(COMPILER_SUPPORTS_CXX11) ENDIF(CMAKE_ENABLE_C++11) #----------------- # Changing CRT from dynamic to static (Windows Only) IF(WIN32) INCLUDE(${CMAKE_SOURCE_DIR}/changeCrt.cmake) CHANGE_CRT("/MT") ENDIF(WIN32) #----------------- # ICU SET(MYSQLCPPCONN_ICU_ENABLE 0 CACHE BOOL "development only: search icu although we do not make use of it yet.") IF(MYSQLCPPCONN_ICU_ENABLE) SET(MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE) SET(MYSQLCPPCONN_ICU_LIBRARY) SET(MYSQLCPPCONN_ICU_INCLUDE) FIND_PROGRAM (MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE icu-config) IF (NOT MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE) SET (MYSQLCPPCONN_ICU_FOUND FALSE) MESSAGE(STATUS "icu-config not found") ELSE (NOT MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE) EXEC_PROGRAM ("${MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE} --ldflags-libsonly" OUTPUT_VARIABLE MYSQLCPPCONN_ICU_LIBRARY RETURN_VALUE ERROR_CODE ) EXEC_PROGRAM ("${MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE} --cppflags-searchpath|sed s/^-I//" OUTPUT_VARIABLE MYSQLCPPCONN_ICU_INCLUDE RETURN_VALUE ERROR_CODE ) EXEC_PROGRAM ("${MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE} --ldflags-searchpath|sed s/^-L//" OUTPUT_VARIABLE MYSQLCPPCONN_ICU_LDLIB RETURN_VALUE ERROR_CODE ) IF (MYSQLCPPCONN_ICU_LIBRARY) SET (MYSQLCPPCONN_ICU_FOUND TRUE) ENDIF (MYSQLCPPCONN_ICU_LIBRARY) MESSAGE(STATUS "ICU::CONFIG: ${MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE}") MESSAGE(STATUS "ICU::LIBRARY: ${MYSQLCPPCONN_ICU_LIBRARY}") MESSAGE(STATUS "ICU::INCLUDE: ${MYSQLCPPCONN_ICU_INCLUDE}") MESSAGE(STATUS "ICU::LDLIB: ${MYSQLCPPCONN_ICU_LDLIB}") INCLUDE_DIRECTORIES(${MYSQLCPPCONN_ICU_INCLUDE}) LINK_DIRECTORIES(${MYSQLCPPCONN_ICU_LDLIB}) ENDIF (NOT MYSQLCPPCONN_ICU_CONFIG_EXECUTABLE) ENDIF(MYSQLCPPCONN_ICU_ENABLE) #----------------- #----------------- # BOOST SET(ENV_BOOST $ENV{BOOST_ROOT}) IF(NOT BOOST_ROOT AND ENV_BOOST) SET(BOOST_ROOT ${ENV_BOOST}) ENDIF(NOT BOOST_ROOT AND ENV_BOOST) IF(NOT BOOST_ROOT AND WIN32) SET(BOOST_ROOT "C:/Program Files/Boost") ENDIF(NOT BOOST_ROOT AND WIN32) # Prefer static linking in all cases SET(Boost_ADDITIONAL_VERSIONS "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39") SET(Boost_NO_BOOST_CMAKE ON CACHE BOOL "Enable fix for FindBoost.cmake") SET(MYSQLCPPCONN_BOOST_COMPONENTS thread date_time) SET(Boost_USE_STATIC_LIBS TRUE) #FIND_PACKAGE(Boost COMPONENTS ${MYSQLCPPCONN_BOOST_COMPONENTS}) FIND_PACKAGE(Boost) IF(NOT Boost_FOUND) # Try dynamic SET(Boost_USE_STATIC_LIBS FALSE) FIND_PACKAGE(Boost COMPONENTS ${MYSQLCPPCONN_BOOST_COMPONENTS}) IF(NOT Boost_FOUND) MESSAGE(FATAL_ERROR "Boost or some of its libraries found. If not in standard place please set -DBOOST_ROOT:STRING=") ENDIF(NOT Boost_FOUND) ENDIF(NOT Boost_FOUND) SET(MYSQLCPPCONN_BOOST_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}) SET(MYSQLCPPCONN_BOOST_SYSTEM_LIBS ${Boost_SYSTEM_LIBRARY}) SET(MYSQLCPPCONN_BOOST_THREAD_LIBS ${Boost_THREAD_LIBRARY}) SET(MYSQLCPPCONN_BOOST_LIBRARY_DIRS ${Boost_LIBRARY_DIRS}) INCLUDE_DIRECTORIES(${MYSQLCPPCONN_BOOST_INCLUDE_DIRS}) MESSAGE(STATUS "BOOST_INCLUDE_DIRS=${MYSQLCPPCONN_BOOST_INCLUDE_DIRS}") #----------------- IF(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) ENDIF(COMMAND cmake_policy) INCLUDE(CheckIncludeFiles) INCLUDE(CheckFunctionExists) INCLUDE(CheckTypeSize) #---------------------- # STLPORT - BEGIN # SET(MYSQLCPPCONN_STLPORT_ENABLE 0 CACHE BOOL "stlport-enabled") IF(MYSQLCPPCONN_STLPORT_ENABLE) MESSAGE(STATUS "Looking for STLPort") FIND_PATH(STLPORT_INCLUDE_DIR stl_user_config.h $ENV{STLPORT_INCLUDE_DIR} /usr/include/stlport /usr/local/include/stlport) IF(STLPORT_INCLUDE_DIR) MESSAGE(STATUS "Using STLPort from : ${STLPORT_INCLUDE_DIR}") INCLUDE_DIRECTORIES(STLPORT_INCLUDE_DIR) SET(MYSQLCPPCONN_STLPORT_LIB "stlport") ELSE(STLPORT_INCLUDE_DIR) MESSAGE(FATAL_ERROR "STLPORT not found. Please set \$ENV{STLPORT_INCLUDE_DIR} if installed in non-standard location") ENDIF(STLPORT_INCLUDE_DIR) # We want to set the inclusion of the library globally ADD_DEFINITIONS(-library=stlport4) # Not a macro defintion, but CMake manual says I can!! ;) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -library=stlport4") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -library=stlport4") SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -library=stlport4") ELSE(MYSQLCPPCONN_STLPORT_ENABLE) SET(MYSQLCPPCONN_STLPORT_LIB "") ENDIF(MYSQLCPPCONN_STLPORT_ENABLE) # # STLPORT - END #---------------------- # Make tests cover methods that throw not implemented to detect API changes? SET(MYSQLCPPCONN_TEST_NOT_IMPLEMENTED 0 CACHE BOOL "HEAD/trunk QA: invoke methods that should return not implemented to detect API changes") INCLUDE(${CMAKE_SOURCE_DIR}/FindMySQL.cmake) SET(MYSQLCLIENT_STATIC_BINDING 1 CACHE BOOL "enable static binding") IF(MYSQLCLIENT_STATIC_BINDING AND EXISTS "${CMAKE_SOURCE_DIR}/cmake/mysql_version_info.cmake") INCLUDE(${CMAKE_SOURCE_DIR}/cmake/mysql_version_info.cmake) IF(NOT LIBMYSQL_CPP_VERSION STREQUAL "") SET(MYSQL_VERSION "${LIBMYSQL_CPP_VERSION}") ELSEIF(NOT MYSQL_CPP_SERVER_VERSION STREQUAL "") SET(MYSQL_VERSION "${MYSQL_CPP_SERVER_VERSION}") ENDIF(NOT LIBMYSQL_CPP_VERSION STREQUAL "") STRING(REGEX MATCHALL "([0-9]+.[0-9]+.[0-9]+)" MYSQL_VERSION "${MYSQL_VERSION}") IF(LIBMYSQL_CPP_VERSION_ID) SET(MYSQL_NUM_VERSION ${LIBMYSQL_CPP_VERSION_ID}) ELSEIF(MYSQL_CPP_SERVER_VERSION_ID) SET(MYSQL_NUM_VERSION ${MYSQL_CPP_SERVER_VERSION_ID}) ENDIF(LIBMYSQL_CPP_VERSION_ID) ENDIF() OPTION(USE_SERVER_CXXFLAGS "USE MYSQL_CXXFLAGS on connector build" 0) message(STATUS "USE_SERVER_FLAGS : ${USE_SERVER_CXXFLAGS}") if (USE_SERVER_CXXFLAGS) SET(MYSQLCPPCONN_COMPILE_FLAGS_ENV "$ENV{CPPFLAGS} ${MYSQL_CXXFLAGS} $ENV{CXXFLAGS}") else (USE_SERVER_CXXFLAGS) SET(MYSQLCPPCONN_COMPILE_FLAGS_ENV "$ENV{CPPFLAGS} $ENV{CXXFLAGS}") endif(USE_SERVER_CXXFLAGS) MESSAGE(STATUS "Environment compile flags: ${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") SET(MYSQLCPPCONN_LINK_FLAGS_ENV "$ENV{LDFLAGS}") MESSAGE(STATUS "Environment link flags: ${MYSQLCPPCONN_LINK_FLAGS_ENV}") # Configuring header file with DM version info CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cppconn/version_info.h.cmake ${CMAKE_BINARY_DIR}/cppconn/version_info.h @ONLY) # # ---------------------------------------------------------------------- # Create package script # ---------------------------------------------------------------------- IF(NOT CONNECTOR_PLATFORM) IF(WIN32) IF(CMAKE_SIZEOF_VOID_P MATCHES 8) SET(CONNECTOR_PLATFORM "winx64") ELSE(CMAKE_SIZEOF_VOID_P MATCHES 8) SET(CONNECTOR_PLATFORM "win32") ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8) ELSE(WIN32) SET(CONNECTOR_PLATFORM "unknown") ENDIF(WIN32) ENDIF(NOT CONNECTOR_PLATFORM) #CPACK version variables are initialized in VersionInfo.cmake # Get the part of the package name for this product IF(MYSQL_SERVER_SUFFIX STREQUAL "-community") SET(CPACK_SERVER_SUFFIX "") ELSE(MYSQL_SERVER_SUFFIX STREQUAL "-community") SET(CPACK_SERVER_SUFFIX ${MYSQL_SERVER_SUFFIX}) ENDIF(MYSQL_SERVER_SUFFIX STREQUAL "-community") IF(EXTRA_NAME_SUFFIX) SET(CPACK_PACKAGE_NAME "mysql-connector-c++${EXTRA_NAME_SUFFIX}") ELSE(EXTRA_NAME_SUFFIX) SET(CPACK_PACKAGE_NAME "mysql-connector-c++") ENDIF(EXTRA_NAME_SUFFIX) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Connector/C++, a library for connecting to MySQL servers.") SET(CPACK_PACKAGE_VENDOR "Oracle and/or its affiliates") SET(CPACK_RPM_PACKAGE_DESCRIPTION "The MySQL Connector/C++ is a MySQL database connector for C++. The MySQL Driver for C++ can be used to connect to the MySQL Server from C++ applications. The MySQL Driver for C++ mimics the JDBC 4.0 API. It is recommended to use the connector with MySQL 5.1 or later. Note - its full functionality is not available when connecting to MySQL 5.0. The MySQL Driver for C++ cannot connect to MySQL 4.1 or earlier. MySQL is a trademark of ${CPACK_PACKAGE_VENDOR} The MySQL software has Dual Licensing, which means you can use the MySQL software free of charge under the GNU General Public License (http://www.gnu.org/licenses/). You can also purchase commercial MySQL licenses from ${CPACK_PACKAGE_VENDOR} if you do not wish to be QLCPPCONN_VERSION in the manual for further info.") SET(CPACK_RESOURCE_FILE_LICENSE "${LICENSE_FILENAME}") SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README") SET(CPACK_RESOURCE_FILE_INSTALL "${CMAKE_SOURCE_DIR}/INSTALL") SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${MYSQLCPPCONN_VERSION}") SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}-${MYSQLCPPCONN_VERSION}-${CONNECTOR_PLATFORM}") IF(WIN32) SET(CPACK_GENERATOR "ZIP") SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-noinstall-${MYSQLCPPCONN_VERSION}-${CONNECTOR_PLATFORM}") ELSE(WIN32) SET(CPACK_GENERATOR "TGZ") SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}") ENDIF(WIN32) SET(DOC_DESTINATION ".") IF(RPM_LAYOUT) SET(DOC_DESTINATION "share/doc/${CPACK_PACKAGE_NAME}-${MYSQLCPPCONN_VERSION}") ENDIF() INSTALL(FILES ${CPACK_RESOURCE_FILE_README} ${CPACK_RESOURCE_FILE_INSTALL} ${CPACK_RESOURCE_FILE_LICENSE} "${CMAKE_SOURCE_DIR}/Licenses_for_Third-Party_Components.txt" "${CMAKE_SOURCE_DIR}/ANNOUNCEMENT" DESTINATION ${DOC_DESTINATION} OPTIONAL) SET(COMMON_IGNORE_FILES "/CMakeFiles/" "/Testing/" "/.bzr/" "_CPack_Packages/" "~" ".swp" ".log" ".gz" ".directory$" "CMakeCache.txt" "Makefile" "install_manifest.txt" ) SET(PRJ_COMMON_IGNORE_FILES ${COMMON_IGNORE_FILES} "ANNOUNCEMENT_102_ALPHA" "ANNOUNCEMENT_103_ALPHA" "ANNOUNCEMENT_104_BETA" "ANNOUNCEMENT_105_GA" "ANNOUNCEMENT_110_GA" "ANNOUNCEMENT_111_GA" "ANNOUNCEMENT_DRAFT" ) SET(CPACK_SOURCE_IGNORE_FILES ${PRJ_COMMON_IGNORE_FILES} "cppconn/config.h$" "cppconn/version_info.h$" "driver/nativeapi/binding_config.h$" "driver/version_info.h$" ) SET(CPACK_PACKAGE_IGNORE_FILES ${PRJ_COMMON_IGNORE_FILES} "something_there" ) SET(CPACK_SOURCE_GENERATOR "TGZ") SET(MYSQLCPPCONN_GCOV_ENABLE 0 CACHE BOOL "gcov-enabled") IF(CMAKE_COMPILER_IS_GNUCC) ADD_DEFINITIONS("-Wall -fPIC -Woverloaded-virtual") IF (MYSQLCPPCONN_GCOV_ENABLE) ADD_DEFINITIONS("-fprofile-arcs -ftest-coverage") ENDIF (MYSQLCPPCONN_GCOV_ENABLE) ENDIF(CMAKE_COMPILER_IS_GNUCC) # SET(CPACK_*) before the INCLUDE(CPack) INCLUDE(CPack) IF(WIN32) STRING(REGEX REPLACE "MYSQLCPPCONN" "MySQL/ConnectorCPP" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") ENDIF(WIN32) MESSAGE(STATUS "Installation path is: ${CMAKE_INSTALL_PREFIX} (overwrite with -DCMAKE_INSTALL_PREFIX=/your/path)") INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/cppconn) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/cppconn) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/driver/nativeapi) ADD_SUBDIRECTORY(cppconn) ADD_SUBDIRECTORY(driver) ADD_SUBDIRECTORY(examples) ADD_SUBDIRECTORY(test) ADD_SUBDIRECTORY(test/framework) ADD_SUBDIRECTORY(test/CJUnitTestsPort) ADD_SUBDIRECTORY(test/unit) IF(DEFINED CMAKE_SYSTEM_NAME AND ${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") # see also README IF(${CMAKE_C_COMPILER} MATCHES "gcc$") MESSAGE("NOTE") MESSAGE("You seem to be using GCC on SunOS.") MESSAGE("This is not recommended. Compilation") MESSAGE("might fail due to compile flags") MESSAGE("returned by the MySQL tool mysql_config.") MESSAGE("In case of an error, try commenting out:") MESSAGE("# ADD_DEFINITIONS(\"\${MYSQL_CXXFLAGS}\")") MESSAGE("in the file FindMySQL.cm") ENDIF(${CMAKE_C_COMPILER} MATCHES "gcc$") IF(${CMAKE_C_COMPILER} MATCHES "gcc$") IF(${CMAKE_CXX_COMPILER} MATCHES "CC$") MESSAGE("NOTE") MESSAGE("You seem to be using the GCC C-compiler") MESSAGE("together with the Sun CC C++-compiler.") MESSAGE("Linking of the resulting binaries") MESSAGE("might fail. In case of an error,") MESSAGE("try using Sun compilers only") ENDIF(${CMAKE_CXX_COMPILER} MATCHES "CC$") ELSEIF(${CMAKE_C_COMPILER} MATCHES "cc$" AND ${CMAKE_CXX_COMPILER} MATCHES "[c|g]\\+\\+$") MESSAGE("NOTE") MESSAGE("You seem to be using the GCC C-compiler") MESSAGE("together with the Sun CC C++-compiler.") MESSAGE("Linking of the resulting binaries") MESSAGE("might fail. In case of an error,") MESSAGE("try using Sun compilers only") ENDIF(${CMAKE_C_COMPILER} MATCHES "gcc$") ENDIF(DEFINED CMAKE_SYSTEM_NAME AND ${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") INSTALL(FILES "BUILDINFO" DESTINATION . OPTIONAL) mysql-connector-c++-1.1.7/COPYING000644 015771 000012 00000043254 12645244436 017026 0ustar00pb2userwheel000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. mysql-connector-c++-1.1.7/FindMySQL.cmake000644 015771 000012 00000065140 12645244436 020541 0ustar00pb2userwheel000000 000000 # -*- indent-tabs-mode:nil; -*- # vim: set expandtab: # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ########################################################################## ########################################################################## # # Configuration variables, all optional, are # # MYSQL_DIR - Set in environment or as parameter to "cmake", # this is the top directory of the MySQL Server or # Connector/C install # MYSQL_INCLUDE_DIR - Set in environment or as parameter to "cmake", # this is the include directory where to find # the client library # MYSQL_LIB_DIR - Set in environment or as parameter to "cmake", # this is the library directory where to find # the client library # MYSQLCLIENT_STATIC_LINKING # - Specify that you want static linking, dynamic # linking is the default # MYSQLCLIENT_NO_THREADS # - Specify to link against the single threaded # library, "libmysqlclient". Note that in 5.5 # and up "libmysqlclient" is multithreaded and # "libmysqlclient_r" just a soft link to it # MYSQL_CONFIG_EXECUTABLE # - "mysql_config" executable to use # MYSQL_CXX_LINKAGE - Specify that client library needs C++ linking # MYSQL_EXTRA_LIBRARIES # - Libraries to add to the linkage # MYSQL_CFLAGS - C compiler flags # MYSQL_CXXFLAGS - C++ compiler flags # MYSQL_LINK_FLAGS - User defined extra linkage flags # FINDMYSQL_DEBUG - Set if want debug output from this script # # Note that most variables above, if not set by the user they will be # set by this include file. # # In addition, the below CMake variables are set by this include file # # MYSQL_VERSION - Three position numeric version, like 5.6.41 # MYSQL_VERSION_ID - Numeric padded version, 5.13.4 => 51304 # MYSQL_NUM_VERSION - Same as MYSQL_VERSION_ID, for compatibility # MYSQL_LIB - Path to the client library # MYSQL_LIBRARIES - Library name, might be "-lmysqlclient" while # MYSQL_LIB is the path to the library # MYSQL_CLIENT_LIBS - Same as MYSQL_LIBRARIES, for compatibility # # (1) If MYSQL_INCLUDE_DIR or MYSQL_LIB_DIR are given, these are # used and an error is reported if can't be used # (2) If MYSQL_CONFIG_EXECUTABLE is given, it is used to get # headers and libraries # (3) If MYSQL_DIR is given and "${MYSQL_DIR}/bin/mysql_config" is # found, then same as (2) # (4) If MYSQL_DIR is given and no "${MYSQL_DIR}/bin/mysql_config", # search MYSQL_DIR # # FIXME if we get a "mysql_config" on Windows, things needs to change # FIXME rename the VERSION variables above # FIXME let MYSQL_VERSION include "-beta" etc? # FIXME can mysql_config --version be C/C verson? # FIXME if no mysql_config, find version from include/mysql_version.h? # #define MYSQL_SERVER_VERSION "5.7.5-m15" # #define MYSQL_VERSION_ID 50705 # #define LIBMYSQL_VERSION "6.1.5" # #define LIBMYSQL_VERSION_ID 60105 # FIXME can MYSQL_LIB_DIR be a list of paths? # FIXME is MYSQLCLIENT_LIBS a better name? # FIXME cache variables, makes them command line args? # FIXME really do include_directories() and link_directories()? Likely # FIXME add check that if not static, not picked up .a or mysqlclient.lib # FIXME MYSQL_VERSION_ID need to take into account Cluster versions # and Connector/C versions # FIXME handle MYSQL_VERSION_ID, LIBMYSQL_VERSION and LIBMYSQL_VERSION_ID? # ########################################################################## ########################################################################## # # Check the input data # ########################################################################## # If using both MYSQL_DIR as a cmake argument and set in environment, # and not empty strings, they better be the same. Else stop and complain set(ENV_OR_OPT_VARS MYSQL_DIR MYSQL_INCLUDE_DIR MYSQL_LIB_DIR MYSQL_CFLAGS MYSQL_CXXFLAGS MYSQL_CONFIG_EXECUTABLE MYSQLCLIENT_STATIC_LINKING MYSQLCLIENT_NO_THREADS MYSQL_CXX_LINKAGE MYSQL_EXTRA_LIBRARIES MYSQL_LINK_FLAGS ) # Mark the variable names that have values that are paths set(ENV_OR_OPT_PATH_VARS MYSQL_DIR MYSQL_INCLUDE_DIR MYSQL_LIB_DIR ) foreach(_xvar ${ENV_OR_OPT_VARS}) if((DEFINED ${_xvar}) AND (DEFINED ENV{${_xvar}}) AND (NOT "${${_xvar}}" STREQUAL "") AND (NOT "$ENV{${_xvar}}" STREQUAL "") AND (NOT "$ENV{${_xvar}}" STREQUAL "${${_xvar}}")) message(FATAL_ERROR "Please pass -D${_xvar}=... as an argument or " "set ${_xvar} in the environment, but not both") endif() # Now we know both are not set, set the CMake variable if needed if((DEFINED ENV{${_xvar}}) AND (NOT "$ENV{${_xvar}}" STREQUAL "")) set(${_xvar} $ENV{${_xvar}}) endif() # Notmalize the path if the variable is set and is a path if(${_xvar}) list(FIND ENV_OR_OPT_PATH_VARS ${_xvar} _index) if (${_index} GREATER -1) file(TO_CMAKE_PATH "${${_xvar}}" ${_xvar}) endif() endif() endforeach() if(MYSQL_CONFIG_EXECUTABLE) set(_mysql_config_set_by_user 1) else() # If MYSQL_DIR is set, set MYSQL_CONFIG_EXECUTABLE if((NOT WIN32) AND (DEFINED MYSQL_DIR) AND (EXISTS "${MYSQL_DIR}/bin/mysql_config")) set(MYSQL_CONFIG_EXECUTABLE "${MYSQL_DIR}/bin/mysql_config") set(_mysql_config_in_mysql_dir 1) endif() endif() ########################################################################## # # Data and basic settings # ########################################################################## # Set sub directory to search in # dist = for mysql binary distributions # build = for custom built tree if(CMAKE_BUILD_TYPE STREQUAL Debug) set(_lib_suffix_dist debug) set(_lib_suffix_build Debug) else() set(_lib_suffix_dist opt) set(_lib_suffix_build Release) add_definitions(-DDBUG_OFF) # FIXME what?! endif() set(_exe_fallback_path /usr/bin /usr/local/bin /opt/mysql/mysql/bin /usr/local/mysql/bin ) set(_include_fallback_path /usr/include/mysql /usr/local/include/mysql /opt/mysql/mysql/include /opt/mysql/mysql/include/mysql /usr/local/mysql/include /usr/local/mysql/include/mysql $ENV{ProgramFiles}/MySQL/*/include $ENV{SystemDrive}/MySQL/*/include ) set(_lib_fallback_path /usr/lib/mysql /usr/local/lib/mysql /usr/local/mysql/lib /usr/local/mysql/lib/mysql /opt/mysql/mysql/lib /opt/mysql/mysql/lib/mysql $ENV{ProgramFiles}/MySQL/*/lib/${_lib_suffix_dist} $ENV{ProgramFiles}/MySQL/*/lib $ENV{SystemDrive}/MySQL/*/lib/${_lib_suffix_dist} $ENV{SystemDrive}/MySQL/*/lib ) set(_lib_subdirs # Paths in build tree, really being too nice libmysql/${_lib_suffix_build} client/${_lib_suffix_build} libmysql_r/.libs libmysql/.libs libmysql # Install sub directories lib/mysql lib/${_lib_suffix_dist} # Need to be before "lib" lib ) set(_static_subdirs mysql ${_lib_suffix_dist} ) if(MSVC90) set(_vs_subdir vs9) elseif(MSVC10) set(_vs_subdir vs10) elseif(MSVC11) set(_vs_subdir vs11) elseif(MSVC12) set(_vs_subdir vs12) elseif(MSVC13) set(_vs_subdir vs13) elseif(MSVC14) set(_vs_subdir vs14) elseif(MSVC15) set(_vs_subdir vs15) endif() if(_vs_subdir) if("${_lib_suffix_dist}" STREQUAL "debug") set(_vs_subdir "${_vs_subdir}/debug") endif() list(INSERT _lib_subdirs 0 "lib/${_vs_subdir}") endif() # For Windows, the client library name differs, so easy to # make sure find_library() picks the right one. For Unix, it # is the file extension that differs. In the static library # case we know it is ".a", so we add it to the library name # we search for to make sure it is picked in the static case. if(WIN32) set(_dynamic_libs "libmysql") set(_static_libs "mysqlclient") set(_static_lib_ext ".lib") # Careful, can be import library for DLL elseif(MYSQLCLIENT_NO_THREADS) # In 5.1 and below there is a single threaded library set(_dynamic_libs "mysqlclient") set(_static_libs "libmysqlclient.a") set(_static_lib_ext ".a") else() # We try the multithreaded "libmysqlclient_r" first and if not # there, pick "libmysqlclient" that in 5.5 and up is multithreaded # anyway (soft link "libmysqlclient_r" is not installed MySQL Server # 5.6 and Debian/Ubuntu and might go in 5.7 for all installs) set(_dynamic_libs "mysqlclient_r" "mysqlclient") set(_static_libs "libmysqlclient_r.a" "libmysqlclient.a") set(_static_lib_ext ".a") endif() if(MYSQLCLIENT_STATIC_LINKING) set(_link_type "static") set(_search_libs ${_static_libs}) else() set(_link_type "dynamic") set(_search_libs ${_dynamic_libs}) endif() # Just to pretty print in error messages string(REPLACE ";" " " _pp_search_libs "${_search_libs}") string(REPLACE ";" " " _pp_lib_subdirs "${_lib_subdirs}") string(REPLACE ";" " " _pp_lib_fallback_path "${_lib_fallback_path}") string(REPLACE ";" " " _pp_include_fallback_path "${_include_fallback_path}") message(STATUS "You will link ${_link_type}ally to the MySQL client" " library (set with -DMYSQLCLIENT_STATIC_LINKING=)") message(STATUS "Searching for ${_link_type} libraries with the base name(s) \"${_pp_search_libs}\"") ########################################################################## # # Macros # ########################################################################## # ---------------------------------------------------------------------- # # Macro that runs "mysql_config ${_opt}" and return the line after # trimming away ending space/newline. # # _mysql_conf( # _var - output variable name, will contain a ';' separated list # _opt - the flag to give to mysql_config # # ---------------------------------------------------------------------- macro(_mysql_conf _var _opt) execute_process( COMMAND ${MYSQL_CONFIG_EXECUTABLE} ${_opt} OUTPUT_VARIABLE ${_var} OUTPUT_STRIP_TRAILING_WHITESPACE ) endmacro() # ---------------------------------------------------------------------- # # Macro that runs "mysql_config ${_opt}", selects output args using a # regex, and clean it up a bit removing space/tab/newline before # setting it to a variable. # # _mysql_config( # _var - output variable name, will contain a ';' separated list # _regex - regular expression matching the prefix of args to select # _opt - the flag to give to mysql_config # # ---------------------------------------------------------------------- macro(_mysql_config _var _regex _opt) _mysql_conf(_mysql_config_output ${_opt}) string(REGEX MATCHALL "${_regex}([^ ]+)" _mysql_config_output "${_mysql_config_output}") string(REGEX REPLACE "^[ \t]+" "" _mysql_config_output "${_mysql_config_output}") string(REGEX REPLACE "${_regex}" "" _mysql_config_output "${_mysql_config_output}") separate_arguments(_mysql_config_output) set(${_var} ${_mysql_config_output}) endmacro() # ---------------------------------------------------------------------- # # Macro that runs "mysql_config ${_opt}" and selects output using a # prefix regex. Cleans it up a bit removing space/tab/newline. Then # removes the prefix on all in the list, and finally replace what # matches another regular expression with a replacement string. # # _mysql_config_replace( # _var - output variable name, will contain a ';' separated list # _regex1 - regular expression to match out arguments # _replace - what to replace match _regex1 with # _regex2 - regular expression matching the prefix of args to select # _opt - the flag to give to mysql_config # # ---------------------------------------------------------------------- macro(_mysql_config_replace _var _regex1 _replace _regex2 _opt) _mysql_conf(_mysql_config_output ${_opt}) string(REGEX MATCHALL "${_regex2}([^ ]+)" _mysql_config_output "${_mysql_config_output}") string(REGEX REPLACE "^[ \t]+" "" _mysql_config_output "${_mysql_config_output}") string(REGEX REPLACE "${_regex2}" "" _mysql_config_output "${_mysql_config_output}") string(REGEX REPLACE "${_regex1}" "${_replace}" _mysql_config_output "${_mysql_config_output}") separate_arguments(_mysql_config_output) set(${_var} ${_mysql_config_output}) endmacro() # ---------------------------------------------------------------------- # # Macro to check that we found a library and that we got the right type # # ---------------------------------------------------------------------- macro(_check_lib_search_error _lib_dir_var _lib_var _exta_err_string) set(_lib "${${_lib_var}}") set(_lib_dir "${${_lib_dir_var}}") if(FINDMYSQL_DEBUG) message("_lib \"${_lib}\"") message("_lib_dir \"${_lib_dir}\"") message("_lib_var \"${_lib_var}\"") message("_lib_dir_var \"${_lib_dir_var}\"") endif() set(_err_string "Could not find ${_link_type} " "\"${_pp_search_libs}\" in ${_lib_dir_var} " "\"${_lib_dir}\" ${_exta_err_string}") if(NOT ${_lib_var}) message(FATAL_ERROR ${_err_string}) endif() # find_library() try find a shared library first, then a static # one. For Windows the library has a different name, but for # Unix only the extension differs. So we check here that we # got the library kind we expected. if(NOT WIN32) if(NOT MYSQLCLIENT_STATIC_LINKING) get_filename_component(_ext ${_lib} EXT) if(${_ext} STREQUAL ${_static_lib_ext}) message(FATAL_ERROR ${_err_string}) endif() endif() endif() endmacro() ########################################################################## # # Try find MYSQL_CONFIG_EXECUTABLE if not set, and find version # ########################################################################## if(NOT WIN32) if(NOT MYSQL_CONFIG_EXECUTABLE) find_program(MYSQL_CONFIG_EXECUTABLE NAMES mysql_config DOC "full path of mysql_config" PATHS ${_exe_fallback_path} ) endif() if(MYSQL_CONFIG_EXECUTABLE) message(STATUS "mysql_config was found ${MYSQL_CONFIG_EXECUTABLE}") _mysql_conf(MYSQL_VERSION "--version") endif() endif() ########################################################################## # # Find MYSQL_INCLUDE_DIR # ########################################################################## if(FINDMYSQL_DEBUG AND MYSQL_INCLUDE_DIR) message("DBG: User gave MYSQL_INCLUDE_DIR = \"${MYSQL_INCLUDE_DIR}\"") endif() if(FINDMYSQL_DEBUG AND MYSQL_DIR) message("DBG: User gave MYSQL_DIR = \"${MYSQL_DIR}\"") endif() if(MYSQL_INCLUDE_DIR) if(FINDMYSQL_DEBUG) message("DBG: Using MYSQL_INCLUDE_DIR to find \"mysql.h\"") endif() if(NOT EXISTS "${MYSQL_INCLUDE_DIR}/mysql.h") message(FATAL_ERROR "MYSQL_INCLUDE_DIR given, but no \"mysql.h\" " "in \"${MYSQL_INCLUDE_DIR}\"") endif() elseif(MYSQL_DIR AND (NOT _mysql_config_in_mysql_dir) AND (NOT _mysql_config_set_by_user)) if(FINDMYSQL_DEBUG) message("DBG: Using MYSQL_DIR without \"mysql_config\" to find \"mysql.h\"") endif() set(MYSQL_INCLUDE_DIR "${MYSQL_DIR}/include") if(NOT EXISTS "${MYSQL_INCLUDE_DIR}/mysql.h") message(FATAL_ERROR "MYSQL_DIR given, but no \"mysql.h\" " "in \"${MYSQL_INCLUDE_DIR}\"") endif() elseif(MYSQL_CONFIG_EXECUTABLE) if(FINDMYSQL_DEBUG) message("DBG: Using \"mysql_config\" to find \"mysql.h\"") endif() # This code assumes there is just one "-I...." and that # no space between "-I" and the path _mysql_config(MYSQL_INCLUDE_DIR "(^| )-I" "--include") if(NOT MYSQL_INCLUDE_DIR) message(FATAL_ERROR "Could not find the include dir from running " "\"${MYSQL_CONFIG_EXECUTABLE}\"") endif() if(NOT EXISTS "${MYSQL_INCLUDE_DIR}/mysql.h") message(FATAL_ERROR "Could not find \"mysql.h\" in \"${MYSQL_INCLUDE_DIR}\" " "found from running \"${MYSQL_CONFIG_EXECUTABLE}\"") endif() else() if(FINDMYSQL_DEBUG) message("DBG: Using find_path() searching " "\"${_pp_include_fallback_path}\" to find \"mysql.h\"") endif() # No specific paths, try some common install paths find_path(MYSQL_INCLUDE_DIR mysql.h ${_include_fallback_path}) if(NOT MYSQL_INCLUDE_DIR) message(FATAL_ERROR "Could not find \"mysql.h\" from searching " "\"${_pp_include_fallback_path}\"") endif() endif() if(FINDMYSQL_DEBUG) message("DBG: MYSQL_INCLUDE_DIR = \"${MYSQL_INCLUDE_DIR}\"") endif() ########################################################################## # # Find MYSQL_LIB_DIR, MYSQL_LIB and MYSQL_LIBRARIES # ########################################################################## if(FINDMYSQL_DEBUG AND MYSQL_LIB_DIR) message("DBG: User gave MYSQL_LIB_DIR = \"${MYSQL_LIB_DIR}\"") endif() if(MYSQL_LIB_DIR) if(FINDMYSQL_DEBUG) message("DBG: Using find_library() searching MYSQL_LIB_DIR") endif() find_library(MYSQL_LIB NAMES ${_search_libs} PATHS "${MYSQL_LIB_DIR}" NO_DEFAULT_PATH ) _check_lib_search_error(MYSQL_LIB_DIR MYSQL_LIB "") set(MYSQL_LIBRARIES ${MYSQL_LIB}) elseif(MYSQL_DIR AND (NOT _mysql_config_in_mysql_dir) AND (NOT _mysql_config_set_by_user)) if(FINDMYSQL_DEBUG) message("DBG: Using find_library() searching " "MYSQL_DIR and \"${_pp_lib_subdirs}\"") endif() find_library(MYSQL_LIB NAMES ${_search_libs} PATHS "${MYSQL_DIR}" PATH_SUFFIXES ${_lib_subdirs} NO_DEFAULT_PATH ) _check_lib_search_error(MYSQL_DIR MYSQL_LIB "in \"${_pp_lib_subdirs}\"") get_filename_component(MYSQL_LIB_DIR "${MYSQL_LIB}" PATH) set(MYSQL_LIBRARIES "${MYSQL_LIB}") elseif(MYSQL_CONFIG_EXECUTABLE) if(FINDMYSQL_DEBUG) message("DBG: Using \"mysql_config\" to find the libraries") endif() # This code assumes there is just one "-L...." and that # no space between "-L" and the path _mysql_config(MYSQL_LIB_DIR "(^| )-L" "--libs") if(NOT MYSQL_LIB_DIR) message(FATAL_ERROR "Could not find the library dir from running " "\"${MYSQL_CONFIG_EXECUTABLE}\"") endif() if(NOT EXISTS "${MYSQL_LIB_DIR}") message(FATAL_ERROR "Could not find the directory \"${MYSQL_LIB_DIR}\" " "found from running \"${MYSQL_CONFIG_EXECUTABLE}\"") endif() # We have the assumed MYSQL_LIB_DIR. The output from "mysql_config" # might not be correct for static libraries, so we might need to # adjust MYSQL_LIB_DIR later on. if(MYSQLCLIENT_STATIC_LINKING) # Find the static library, might be one level down find_library(MYSQL_LIB NAMES ${_search_libs} PATHS ${MYSQL_LIB_DIR} PATH_SUFFIXES ${_static_subdirs} NO_DEFAULT_PATH ) _check_lib_search_error(MYSQL_LIB_DIR MYSQL_LIB "in \"${_static_subdirs}\"") # Adjust MYSQL_LIB_DIR in case it changes get_filename_component(MYSQL_LIB_DIR "${MYSQL_LIB}" PATH) # Replace the current library references with the full path # to the library, i.e. the -L will be ignored _mysql_config_replace(MYSQL_LIBRARIES "(mysqlclient|mysqlclient_r)" "${MYSQL_LIB}" "(^| )-l" "--libs") else() _mysql_config(MYSQL_LIBRARIES "(^| )-l" "--libs") # First library is assumed to be the client library list(GET MYSQL_LIBRARIES 0 _search_libs) find_library(MYSQL_LIB NAMES ${_search_libs} PATHS ${MYSQL_LIB_DIR} NO_DEFAULT_PATH ) _check_lib_search_error(MYSQL_LIB_DIR MYSQL_LIB "") endif() else() if(FINDMYSQL_DEBUG) message("DBG: Using find_library() searching " "\"${_pp_lib_fallback_path}\" to find the client library") endif() # Search standard places find_library(MYSQL_LIB NAMES ${_search_libs} PATHS ${_lib_fallback_path} ) if(NOT MYSQL_LIB) message(FATAL_ERROR "Could not find \"${_pp_search_libs}\" from searching " "\"${_pp_lib_fallback_path}\"") endif() get_filename_component(MYSQL_LIB_DIR "${MYSQL_LIB}" PATH) endif() ########################################################################## # # Add more libraries to MYSQL_LIBRARIES # ########################################################################## # FIXME needed?! if(MYSQLCLIENT_STATIC_LINKING AND NOT WIN32 AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") list(APPEND MYSQL_LIBRARIES "rt") endif() if(MYSQL_EXTRA_LIBRARIES) separate_arguments(MYSQL_EXTRA_LIBRARIES) list(APPEND MYSQL_LIBRARIES ${MYSQL_EXTRA_LIBRARIES}) endif() # For compatibility SET(MYSQL_CLIENT_LIBS ${MYSQL_LIBRARIES}) ########################################################################## # # If not found MySQL Serverv version, compile a small client app # and let it write a small cmake file with the settings # ########################################################################## if(MYSQL_INCLUDE_DIR AND NOT MYSQL_VERSION) # Write the C source file that will include the MySQL headers set(GETMYSQLVERSION_SOURCEFILE "${CMAKE_CURRENT_BINARY_DIR}/getmysqlversion.c") file(WRITE "${GETMYSQLVERSION_SOURCEFILE}" "#include \n" "#include \n" "int main() {\n" " printf(\"%s\", MYSQL_SERVER_VERSION);\n" "}\n" ) # Compile and run the created executable, store output in MYSQL_VERSION try_run(_run_result _compile_result "${CMAKE_BINARY_DIR}" "${GETMYSQLVERSION_SOURCEFILE}" CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${MYSQL_INCLUDE_DIR}" RUN_OUTPUT_VARIABLE MYSQL_VERSION ) if(FINDMYSQL_DEBUG) if(NOT _compile_result) message("DBG: Could not compile \"getmysqlversion.c\"") endif() if(_run_result) message("DBG: Running \"getmysqlversion\" returned ${_run_result}") endif() endif() endif() ########################################################################## # # Clean up MYSQL_VERSION and create MYSQL_VERSION_ID/MYSQL_NUM_VERSION # ########################################################################## if(NOT MYSQL_VERSION) message(FATAL_ERROR "Could not determine the MySQL Server version") endif() # Clean up so only numeric, in case of "-alpha" or similar string(REGEX MATCHALL "([0-9]+.[0-9]+.[0-9]+)" MYSQL_VERSION "${MYSQL_VERSION}") # To create a fully numeric version, first normalize so N.NN.NN string(REGEX REPLACE "[.]([0-9])[.]" ".0\\1." MYSQL_VERSION_ID "${MYSQL_VERSION}") string(REGEX REPLACE "[.]([0-9])$" ".0\\1" MYSQL_VERSION_ID "${MYSQL_VERSION_ID}") # Finally remove the dot string(REGEX REPLACE "[.]" "" MYSQL_VERSION_ID "${MYSQL_VERSION_ID}") set(MYSQL_NUM_VERSION ${MYSQL_VERSION_ID}) ########################################################################## # # Try determine if to use C++ linkage, and also find C++ flags # ########################################################################## if(NOT WIN32) if(MYSQL_CONFIG_EXECUTABLE) if(NOT MYSQL_CFLAGS) _mysql_conf(MYSQL_CFLAGS "--cflags") endif() if(NOT MYSQL_CXXFLAGS) if(MYSQL_CXX_LINKAGE OR MYSQL_VERSION_ID GREATER 50603) _mysql_conf(MYSQL_CXXFLAGS "--cxxflags") set(MYSQL_CXX_LINKAGE 1) else() set(MYSQL_CXXFLAGS "${MYSQL_CFLAGS}") endif() endif() # FIXME this should not be needed, caller of this module should set # it's own flags and just use the library on it's on terms # (change the infe message if enabling this code) # if(NOT MYSQL_LINK_FLAGS) # # Find -mcpu -march -mt -m32 -m64 and other flags starting with "-m" # string(REGEX MATCHALL "(^| )-m([^\r\n ]+)" MYSQL_LINK_FLAGS "${MYSQL_CXXFLAGS}") # string(REGEX REPLACE "^ " "" MYSQL_LINK_FLAGS "${MYSQL_LINK_FLAGS}") # string(REGEX REPLACE "; " ";" MYSQL_LINK_FLAGS "${MYSQL_LINK_FLAGS}") # endif() endif() endif() ########################################################################## # # Inform CMake where to look for headers and libraries # ########################################################################## # string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKEBT) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MYSQL_CXXFLAGS}") # set(CMAKE_CXX_FLAGS_${CMAKEBT} "${CMAKE_CXX_FLAGS_${CMAKEBT}} ${MYSQL_CXXFLAGS}") include_directories("${MYSQL_INCLUDE_DIR}") link_directories("${MYSQL_LIB_DIR}") ########################################################################## # # Report # ########################################################################## message(STATUS "MySQL client environment/cmake variables set that the user can override") message(STATUS " MYSQL_DIR : ${MYSQL_DIR}") message(STATUS " MYSQL_INCLUDE_DIR : ${MYSQL_INCLUDE_DIR}") message(STATUS " MYSQL_LIB_DIR : ${MYSQL_LIB_DIR}") message(STATUS " MYSQL_CONFIG_EXECUTABLE : ${MYSQL_CONFIG_EXECUTABLE}") message(STATUS " MYSQL_CXX_LINKAGE : ${MYSQL_CXX_LINKAGE}") message(STATUS " MYSQL_CFLAGS : ${MYSQL_CFLAGS}") message(STATUS " MYSQL_CXXFLAGS : ${MYSQL_CXXFLAGS}") message(STATUS " MYSQLCLIENT_STATIC_LINKING : ${MYSQLCLIENT_STATIC_LINKING}") message(STATUS " MYSQLCLIENT_NO_THREADS : ${MYSQLCLIENT_NO_THREADS}") message(STATUS "MySQL client optional environment/cmake variables set by the user") message(STATUS " MYSQL_EXTRA_LIBRARIES : ${MYSQL_EXTRA_LIBRARIES}") message(STATUS " MYSQL_LINK_FLAGS : ${MYSQL_LINK_FLAGS}") message(STATUS "MySQL client settings that the user can't override") message(STATUS " MYSQL_VERSION : ${MYSQL_VERSION}") message(STATUS " MYSQL_VERSION_ID : ${MYSQL_VERSION_ID}") message(STATUS " MYSQL_LIB : ${MYSQL_LIB}") message(STATUS " MYSQL_LIBRARIES : ${MYSQL_LIBRARIES}") mysql-connector-c++-1.1.7/INSTALL000644 015771 000012 00000024120 12645244436 017013 0ustar00pb2userwheel000000 000000 MySQL Connector/C++ This is a release of MySQL Connector/C++, Oracle's dual-license C++ API for connecting client applications to MySQL. Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. -------------------------------------------------------------------------------- CONTENTS * Contact * Installation * Prerequisites for building Connector/C++ * Building on Unix * Run CMake to build a Makefile * Use make to build the libraries * CMake options: MySQL installation path, debug version and more * Building on Solaris * Building on Windows * Source layout * (if binary package) Further Platform Notes on Building CONTACT For general discussion of the MySQL Connector/C++ please use the C/C++ community forum at http://forums.mysql.com/list.php?167 or join the MySQL Connector/C++ mailing list at http://lists.mysql.com . Bugs can be reported at http://bugs.mysql.com . See also https://wikis.oracle.com/pages/viewpage.action?pageId=27394600 INSTALLATION The MySQL Driver for C++ is distributed in source and binary form. The binary distributions are available as TAR.GZ archives for all supported platforms but Windows. On Windows you either use a MSI Installer or unpack a ZIP archive to an appropriate place. Please check the Reference Manual for further information at: http://dev.mysql.com/doc/refman/5.5/en/connector-cpp.html Notes on building the driver from source can be found in the Reference Manual and below. At the end of this file you may find settings we have used to build a binary package for your platform. PREREQUISITES FOR BUILDING CONNECTOR/C++ The MySQL Connector/C++ is based on the MySQL client libary (MySQL C API). Connector C/C++ is linked against the MySQL client library. You need to have the MySQL client library installed in order to compile the Connector/C++. Typically the MySQL client library gets installed by installing the MySQL Server. However, check your operating system documentation for other installation options. Alternatively you can install the new MySQL Connector/C. The MySQL Connector/C is a standalone version of the MySQL client library. You need to have CMake 2.6.2 (http://www.cmake.org). NOTE: cmake binaries are available for most systems. You do not need to build cmake yourself. As of version 1.1.0 Connector/C++ makes use of Boost (http://www.boost.org). You need to have Boost 1.34.0 or newer installed on your build system. The MySQL driver for C++ makes use of Boost variant, any and some pointers. All of those are "headers only". When installing Boost on your system, you can disable all components that require building any kind of binaries. Connector/C++ source version 1.1.5 must use Boost 1.54.0. Also applications using Connector/C++ 1.1.5 should use Boost 1.54.0. BUILDING ON UNIX The MySQL Connector/C++ is using the cross platform make CMake. CMake creates classical Makefiles. Please visit http://www.cmake.org for further information and documentation. 1. Run CMake to build a Makefile me@host:/path/to/mysql-connector-cpp> cmake . -- Check for working C compiler: /usr/local/bin/gcc -- Check for working C compiler: /usr/local/bin/gcc -- works -- Check size of void* -- Check size of void* - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- mysql_config was found /usr/bin/mysql_config -- MySQL Include dir: /usr/include/mysql -- MySQL Library : -- MySQL Library dir: /usr/lib64/mysql;/usr/lib64 [...] -- Configuring done -- Generating done -- Build files have been written to: /path/to/mysql-connector-cpp Read on at point 3) in case of configure problems. 2. Use make to build the libraries me@host:/path/to/mysql-connector-cpp> make clean me@host:/path/to/mysql-connector-cpp> make Scanning dependencies of target mysqlcppconn [ 0%] Building CXX object driver/CMakeFiles/mysqlcppconn.dir/mysql_art_resultset.cpp.o [ 1%] Building CXX object driver/CMakeFiles/mysqlcppconn.dir/mysql_art_rset_metadata.cpp.o [ 2%] Building CXX object driver/CMakeFiles/mysqlcppconn.dir/mysql_connection.cpp.o [...] [100%] Building CXX object test/unit/template_bug_group/CMakeFiles/bug456.dir/bug456.o Linking CXX executable bug456 If all goes well, you will find the Connector/C++ library in /path/to/driver/libcppmysqlcppconn.so . In case of problems read on below before you ask for assistance. If you want to install the libraries on your system proceed with make install. me@host:/path/to/mysql-connector-cpp> make install 3. CMake options: MySQL installation path, debug version and more In case of configure and/or compile problems check the list of CMake options: me@host:/path/to/mysql-connector-cpp> cmake -L [...] CMAKE_BUILD_TYPE:STRING= CMAKE_INSTALL_PREFIX:PATH=/usr/local MYSQLCLIENT_STATIC_BINDING:BOOL=1 MYSQLCPPCONN_BUILD_EXAMPLES:BOOL=1 MYSQLCPPCONN_DT_RPATH:STRING= MYSQLCPPCONN_DYNLOAD_MYSQL_LIB:FILEPATH=/usr/lib64/libmysqlclient_r.so MYSQLCPPCONN_GCOV_ENABLE:BOOL=0 MYSQLCPPCONN_ICU_ENABLE:BOOL=0 MYSQLCPPCONN_STLPORT_ENABLE:BOOL=0 MYSQLCPPCONN_TEST_NOT_IMPLEMENTED:BOOL=0 MYSQLCPPCONN_TRACE_ENABLE:BOOL=0 MYSQL_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/mysql_config You may also try cmake -LA to get a list of all options including the advanced options. For example, if your MySQL Server installation path is not /usr/local/mysql and you want to build a debug version of the MySQL Connector/C++ use: me@host:/path/to/mysql-connector-cpp> cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DMYSQL_CONFIG_EXECUTABLE:FILEPATH=/path/to/my/mysql/server/bin/mysql_config . Verify your settings with cmake -L: me@host:/path/to/mysql-connector-cpp> cmake -L [...] CMAKE_BUILD_TYPE:STRING= CMAKE_INSTALL_PREFIX:PATH=/usr/local MYSQLCLIENT_STATIC_BINDING:BOOL=1 MYSQLCPPCONN_BUILD_EXAMPLES:BOOL=1 MYSQLCPPCONN_DT_RPATH:STRING= MYSQLCPPCONN_DYNLOAD_MYSQL_LIB:FILEPATH=/usr/lib64/libmysqlclient_r.so MYSQLCPPCONN_GCOV_ENABLE:BOOL=0 MYSQLCPPCONN_ICU_ENABLE:BOOL=0 MYSQLCPPCONN_STLPORT_ENABLE:BOOL=0 MYSQLCPPCONN_TEST_NOT_IMPLEMENTED:BOOL=0 MYSQLCPPCONN_TRACE_ENABLE:BOOL=0 MYSQL_CONFIG_EXECUTABLE:FILEPATH=/path/to/my/mysql/server/bin/mysql_config Proceed with make clean; make as described at point 2.) NOTE: cmake does cache settings in the file CMakeCache.txt. Make sure that cmake does not use old and unwanted settings from CMakeCache.txt. This may cause compile problems. If so, delete CMakeCache.txt, configure custom settings with cmake -D, if any and try compiling again. BUILDING ON SOLARIS Use the Sun compiler to build the MySQL Connector/C++. Ensure that your environment points cmake to the appropriate compiler binaries. The binary distributions of the MySQL Server are build using Sun compilers. The MySQL tool mysql_config returns compiler flags suitable for Sun compilers but possibly not suitable for GCC. If you plan to use GCC on Solaris to compile MySQL Connector/C++, you might need to insert SET(MYSQL_CXXFLAGS "") at the end of the file /path/to/mysql-connector-cpp/FindMySQL.cm. However, its recommended to use Sun Studio on Solaris. No changes are required when using the Sun compilers! Make sure that you do not mix Sun compilers with GNU compilers when building the MySQL Connector/C++. For example, do not use GCC as a C compiler and Sun CC as a C++ compiler. The linker might fail to link the results from both compilers to one binary. BUILDING ON WINDOWS The MySQL Connector/C++ is using the cross platform make CMake. CMake creates classical Makefiles. Please visit http://www.cmake.org for further information and documentation. You need to have the environment variables set for the Visual Studio toolchain. Visual Studio includes a batch file to set these for you, and installs a shortcut into the Start menu to open a command prompt with these variables set. You need to set MYSQL_DIR to point to where the MySQL server is installed, using the short-style filenames: set MYSQL_DIR=C:\PROGRA~1\MySQL\MYSQLS~1.0 Build Connector/C++ using the "cmake" command-line tool by doing the following from the source root directory (in a command prompt window); cmake -G "Visual Studio 8 2005" This produces a project file that you can open with Visual Studio or build from the command line with either of: devenv.com MySQLCPPCONN.sln /build Release devenv.com MySQLCPPCONN.sln /build RelWithDebInfo To compile the "Debug" build, you must run set the cmake build type so the correct version of the MySQL client libraries are used: cmake -G "Visual Studio 8 2005" -DCMAKE_BUILD_TYPE=Debug devenv.com MySQLCPPCONN.sln /build Debug Upon completion; you will find the executables in the subdirectories of the "bin" and "lib" directories. Different versions of CMake come with different "generators". A generator is the component of CMake that is responsible for writing the build files. If, for example, cmake --help does not list a generator for Visual Studio 9 2008, try a more recent version of CMake. Connector C/C++ supports only Microsoft Visual Studio 2003 and above on Windows. SOURCE LAYOUT The MySQL Connector/C++ distribution contains the following directories: |-- cppconn <-- Header files of the public interface |-- driver <-- Connector/C++ source code |-- examples <-- Basic examples |-- test <-- Tests, so to say: more examples |-- thread <-- Thread abstraction, unused --- win <-- Windows MSI Installer FURTHER PLATFORM NOTES ON BUILDING If this INSTALL file is contained in a binary package, you will see below what settings we have used to create the binary. If this INSTALL file is contained in a source package and, you have build issues, please download a binary package for your platform and check the platform specific settings found in its INSTALL file. It may help to check the settings used by us for building. mysql-connector-c++-1.1.7/Licenses_for_Third-Party_Components.txt000644 015771 000012 00000311371 12645244436 025601 0ustar00pb2userwheel000000 000000 Appendix A. Licenses for Third-Party Components The following is a list of the libraries we have included with the MySQL Server source and components used to test MySQL. We are thankful to all individuals that have created these. Some of the components require that their licensing terms be included in the documentation of products that include them. Cross references to these licensing terms are given with the applicable items in the list. * GroupLens Research Project The MySQL Quality Assurance team would like to acknowledge the use of the MovieLens Data Sets (10 million ratings and 100,000 tags for 10681 movies by 71567 users) to help test MySQL products and to thank the GroupLens Research Project at the University of Minnesota for making the data sets available. MySQL 5.5 * Section A.3, "dtoa.c License" * Section A.4, "Editline Library (libedit) License" * Section A.5, "FindGTest.cmake License" * Section A.6, "Fred Fish's Dbug Library License" * Section A.7, "getarg License" * Section A.9, "GNU General Public License Version 2.0, June 1991" * Section A.11, "GNU Libtool License" * Section A.12, "GNU Readline License" * Section A.13, "Google Controlling Master Thread I/O Rate Patch License" * Section A.14, "Google Perftools (TCMalloc utility) License" * Section A.15, "Google SMP Patch License" * Section A.16, "lib_sql.cc License" * Section A.17, "libevent License" * Section A.18, "Linux-PAM License" * Section A.22, "md5 (Message-Digest Algorithm 5) License" * Section A.23, "nt_servc (Windows NT Service class library) License" * Section A.24, "OpenPAM License" * Section A.26, "Percona Multiple I/O Threads Patch License" * Section A.27, "RegEX-Spencer Library License" * Section A.28, "RFC 3174 - US Secure Hash Algorithm 1 (SHA1) License" * Section A.29, "Richard A. O'Keefe String Library License" * Section A.30, "SHA-1 in C License" * Section A.32, "zlib License" MySQL Connector/C * Section A.6, "Fred Fish's Dbug Library License" * Section A.27, "RegEX-Spencer Library License" * Section A.28, "RFC 3174 - US Secure Hash Algorithm 1 (SHA1) License" * Section A.32, "zlib License" MySQL Connector/CPP * Section A.2, "Boost Library License" MySQL Connector/J * Section A.1, "Ant-Contrib License" * Section A.31, "Simple Logging Facade for Java (SLF4J) License" MySQL Connector/Net * Section A.28, "RFC 3174 - US Secure Hash Algorithm 1 (SHA1) License" * Section A.32, "zlib License" * Section A.33, "ZLIB.NET License" MySQL Proxy * Section A.8, "GLib License (for MySQL Proxy)" * Section A.10, "GNU Lesser General Public License Version 2.1, February 1999" * Section A.17, "libevent License" * Section A.19, "LPeg Library License" * Section A.20, "Lua (liblua) License" * Section A.21, "LuaFileSystem Library License" * Section A.25, "PCRE License" A.1. Ant-Contrib License The following software may be included in this product: Ant-Contrib Ant-Contrib Copyright (c) 2001-2003 Ant-Contrib project. All rights reserved. Licensed under the Apache 1.1 License Agreement, a copy of which is r eproduced below. The Apache Software License, Version 1.1 Copyright (c) 2001-2003 Ant-Contrib project. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowlegement: "This product includes software developed by the Ant-Contrib project (http://sourceforge.net/projects/ant-cont rib)." Alternately, this acknowlegement may appear in the software itsel f, if and wherever such third-party acknowlegements normally appear. 4. The name Ant-Contrib must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact ant-contrib-developers@lists.sourceforge.net. 5. Products derived from this software may not be called "Ant-Contri b" nor may "Ant-Contrib" appear in their names without prior written permission of the Ant-Contrib project. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ANT-CONTRIB PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.2. Boost Library License The following software may be included in this product: Boost C++ Libraries Use of any of this software is governed by the terms of the license below: Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. A.3. dtoa.c License The following software may be included in this product: dtoa.c The author of this software is David M. Gay. Copyright (c) 1991, 2000, 2001 by Lucent Technologies. Permission to use, copy, modify, and distribute this software for any purpose without fee is hereby granted, provided that this entire notice is included in all copies of any software which is or includes a copy or modification of this software and in all copies of the supporting documentation for such software. THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. A.4. Editline Library (libedit) License The following software may be included in this product: Editline Library (libedit) Some files are: Copyright (c) 1992, 1993 The Regents of the University of California. All rights reserved. This code is derived from software contributed to Berkeley by Christos Zoulas of Cornell University. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Some files are: Copyright (c) 2001 The NetBSD Foundation, Inc. All rights reserved. This code is derived from software contributed to The NetBSD Foundati on by Anthony Mallet. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Some files are: Copyright (c) 1997 The NetBSD Foundation, Inc. All rights reserved. This code is derived from software contributed to The NetBSD Foundati on by Jaromir Dolecek. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Some files are: Copyright (c) 1998 Todd C. Miller Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. A.5. FindGTest.cmake License The following software may be included in this product: FindGTest.cmake helper script (part of CMake) Copyright 2009 Kitware, Inc. Copyright 2009 Philip Lowman Copyright 2009 Daniel Blezek Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPO SE. See the License for more information. ===================================================================== ===== (To distributed this file outside of CMake, substitute the full License text for the above reference.) Thanks to Daniel Blezek for the GTEST_ADD_TESTS code Text of Copyright.txt mentioned above: CMake - Cross Platform Makefile Generator Copyright 2000-2009 Kitware, Inc., Insight Software Consortium All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution . * Neither the names of Kitware, Inc., the Insight Software Consortium , nor the names of their contributors may be used to endorse or promo te products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL , SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.6. Fred Fish's Dbug Library License The following software may be included in this product: Fred Fish's Dbug Library N O T I C E Copyright Abandoned, 1987, Fred Fish This previously copyrighted work has been placed into the publi c domain by the author and may be freely used for any purpose , private or commercial. Because of the number of inquiries I was receiving about the us e of this product in commercially developed works I have decided t o simply make it public domain to further its unrestricted use. I specifically would be most happy to see this material become a part of the standard Unix distributions by AT&T and the Berkele y Computer Science Research Group, and a standard part of the GN U system from the Free Software Foundation. I would appreciate it, as a courtesy, if this notice is left i n all copies and derivative works. Thank you. The author makes no warranty of any kind with respect to thi s product and explicitly disclaims any implied warranties of mer - chantability or fitness for any particular purpose. The dbug_analyze.c file is subject to the following notice: Copyright June 1987, Binayak Banerjee All rights reserved. This program may be freely distributed under the same terms and conditions as Fred Fish's Dbug package. A.7. getarg License The following software may be included in this product: getarg Function (getarg.h, getarg.c files) Copyright (c) 1997 - 2000 Kungliga Tekniska HУЖgskolan (Royal Institute of Technology, Stockholm, Sweden). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.8. GLib License (for MySQL Proxy) The following software may be included in this product: GLib You are receiving a copy of the GLib library in both source and object code in the following [proxy install dir]/lib/ and [proxy install dir]/licenses/lgpl folders. The terms of the Oracle license do NOT apply to the GLib library; it is licensed under the following license, separately from the Oracle programs you receive. If you do not wish to install this library, you may create an "exclude" file and run tar with the X option, as in the following example, but the Oracle program might not operate properly or at all without the library: tar -xvfX where the exclude-file contains, e.g.: /lib/libglib-2.0.so.0.1600.6 /lib/libglib-2.0.so.0 ... Example: tar -xvfX mysql-proxy-0.8.1-solaris10-x86-64bit.tar.gz Exclude Exclude File: mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libglib-2.0.so mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libglib-2.0.so.0 mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libglib-2.0.so.0.1600.6 mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libgmodule-2.0.so mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libgmodule-2.0.so.0 mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libgmodule-2.0.so.0.1600.6 mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libgthread-2.0.so mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libgthread-2.0.so.0 mysql-proxy-0.8.1-solaris10-x86-64bit/lib/libgthread-2.0.so.0.1600.6 mysql-proxy-0.8.1-solaris10-x86-64bit/licenses/lgpl/glib-2.16.6.tar.g z This component is licensed under Section A.10, "GNU Lesser General Public License Version 2.1, February 1999." A.9. GNU General Public License Version 2.0, June 1991 The following applies to all products licensed under the GNU General Public License, Version 2.0: You may not use the identified files except in compliance with the GNU General Public License, Version 2.0 (the "License.") You may obtain a copy of the License at http://www.gnu.org/licenses/gpl-2.0.txt. A copy of the license is also reproduced below. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change fre e software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit t o using it. (Some other Free Software Foundation software is covered b y the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that yo u have the freedom to distribute copies of free software (and charge fo r this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights . These restrictions translate to certain responsibilities for you if y ou distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certai n that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the origina l, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making th e program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at al l. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below , refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation i n the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Progra m is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty ; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fe e. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that i n whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provid e a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Progra m with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following : a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Section s 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License . However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject t o these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein . You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do no t excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under thi s License and any other pertinent obligations, then as a consequence yo u may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program b y all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended t o apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willin g to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Progra m specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published b y the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by t he Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by t he two goals of preserving the free status of all derivatives of our fre e software and of promoting the sharing and reuse of software generally . NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIN D, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLI ED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUC H DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make i t free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safes t to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper ma il. If the program is interactive, make it output a short notice like thi s when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free software, and you are welcome to redistribute it under certain conditions; type 'show c' for details. The hypothetical commands 'show w' and 'show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than 'show w' and 'show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or yo ur school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program 'Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your progra m into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. A.10. GNU Lesser General Public License Version 2.1, February 1999 The following applies to all products licensed under the GNU Lesser General Public License, Version 2.1: You may not use the identified files except in compliance with the GNU Lesser General Public License, Version 2.1 (the "License"). You may obtain a copy of the License at http://www.gnu.org/licenses/lgpl-2.1.html. A copy of the license is also reproduced below. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also count s as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whethe r this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations bel ow. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure tha t you have the freedom to distribute copies of free software (and charg e for this service if you wish); that you receive source code or can ge t it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender thes e rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether grati s or for a fee, you must give the recipients all the rights that we gav e you. You must make sure that they, too, receive or can get the sourc e code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence o f any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or usin g a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantage s are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certai n special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of th e users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter mus t be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms o f this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translate d straightforwardly into another language. (Hereinafter, translation i s included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code mean s all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are no t covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output fro m such a program is covered only if its contents constitute a work base d on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that , in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Librar y with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Publi c License instead of this License to a given copy of the Library. To d o this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2 , instead of to this License. (If a newer version than version 2 of th e ordinary GNU General Public License has appeared, then you can specif y that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, whic h must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled o r linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header fil e that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivativ e work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do on e of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in th e Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system , rather than copying library functions into the executable, and (2 ) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with . c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the abov e specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you canno t use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combine d library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies , or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on th e Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Librar y subject to these terms and conditions. You may not impose any furthe r restrictions on the recipients' exercise of the rights granted herein . You are not responsible for enforcing compliance by third parties wit h this License. 11. If, as a consequence of a court judgment or allegation of paten t infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do no t excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under thi s License and any other pertinent obligations, then as a consequence yo u may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library b y all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willin g to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Librar y specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published b y the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free statu s of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUC H DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version . This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Softwa re Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper ma il. You should also get your employer (if you work as a programmer) or yo ur school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! A.11. GNU Libtool License The following software may be included in this product: GNU Libtool (The GNU Portable Library Tool) If you are receiving a copy of the Oracle software in source code, you are also receiving a copy of two files (ltmain.sh and ltdl.h) generated by the GNU Libtool in source code. If you received the Oracle software under a license other than a commercial (non-GPL) license, then the terms of the Oracle license do NOT apply to these files from GNU Libtool; they are licensed under the following licenses, separately from the Oracle programs you receive. Oracle elects to use GNU General Public License version 2 (GPL) for any software where a choice of GPL or GNU Lesser/Library General Public License (LGPL) license versions are made available with the language indicating that GPL/LGPL or any later version may be used, or where a choice of which version of the GPL/LGPL is applied is unspecified. From GNU Libtool: ltmain.sh - Provide generalized library-building support services. NOTE: Changing this file will not affect anything until you rerun configure. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Originally by Gordon Matzigkeit, 1996 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception to the GNU General Public License, if you distribute this file as part of a program that contains a configuration script generated by Autoconf, you may include it under the same distribution terms that you use for the rest of that program. This component is licensed under Section A.9, "GNU General Public License Version 2.0, June 1991" A.12. GNU Readline License The following software may be included in this product: GNU Readline Library GNU Readline Library With respect to MySQL Server/Cluster software licensed under GNU General Public License, you are receiving a copy of the GNU Readline Library in source code. The terms of any Oracle license that might accompany the Oracle programs do NOT apply to the GNU Readline Library; it is licensed under the following license, separately from the Oracle programs you receive. Oracle elects to use GNU General Public License version 2 (GPL) for any software where a choice of GPL license versions are made available with the language indicating that GPLv2 or any later version may be used, or where a choice of which version of the GPL is applied is unspecified. This component is licensed under Section A.9, "GNU General Public License Version 2.0, June 1991" A.13. Google Controlling Master Thread I/O Rate Patch License The following software may be included in this product: Google Controlling master thread I/O rate patch Copyright (c) 2009, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in th e documentation and/or other materials provided with the distributio n. * Neither the name of the Google Inc. nor the names of its contribut ors may be used to endorse or promote products derived from this softw are without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.14. Google Perftools (TCMalloc utility) License The following software may be included in this product: Google Perftools (TCMalloc utility) Copyright (c) 1998-2006, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.15. Google SMP Patch License The following software may be included in this product: Google SMP Patch Google SMP patch Copyright (c) 2008, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in th e documentation and/or other materials provided with the distributio n. * Neither the name of the Google Inc. nor the names of its contribut ors may be used to endorse or promote products derived from this softw are without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.16. lib_sql.cc License The following software may be included in this product: lib_sql.cc Copyright (c) 2000 SWsoft company This material is provided "as is", with absolutely no warranty expressed or implied. Any use is at your own risk. Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above notices are retained, and a notice that the code was modified is included with the above copyrigh t notice. This code was modified by the MySQL team. A.17. libevent License The following software may be included in this product: libevent Copyright (c) 2000-2007 Niels Provos All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in th e documentation and/or other materials provided with the distributio n. 3. The name of the author may not be used to endorse or promote produ cts derived from this software without specific prior written permissi on. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN TIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME D. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE == Parts developed by Adam Langley == == log.c Based on err.c, which was adapted from OpenBSD libc *err*warncode. Copyright (c) 2005 Nick Mathewson Copyright (c) 2000 Dug Song Copyright (c) 1993 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == == min_heap.h Copyright (c) 2006 Maxim Yegorushkin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == == win32.c Copyright 2000-2002 Niels Provos Copyright 2003 Michael A. Davis All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == A.18. Linux-PAM License The following software may be included in this product: Linux-PAM (pam-devel, Pluggable authentication modules for Linux) Copyright Theodore Ts'o, 1996. All rights reserved. (For the avoidance of doubt, Oracle uses and distributes this component under the terms below and elects not to do so under the GPL even though the GPL is referenced as an option below.) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, and the entire permission notice in its entirety, including the disclaimer of warranties. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. ALTERNATIVELY, this product may be distributed under the terms of the GNU Public License, in which case the provisions of the GPL are required INSTEAD OF the above restrictions. (This clause is necessary due to a potential bad interaction between the GPL and the restrictions contained in a BSD-style copyright.) THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.19. LPeg Library License The following software may be included in this product: LPeg Use of any of this software is governed by the terms of the license b elow: Copyright (c) 2008 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the ri ghts to use, copy, modify, merge, publish, distribute, sublicense, and/or sel l copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be includ ed in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE SS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI TY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE A UTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFT WARE. A.20. Lua (liblua) License The following software may be included in this product: Lua (liblua) Copyright (c) 1994-2008 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. A.21. LuaFileSystem Library License The following software may be included in this product: LuaFileSystem Copyright (c) 2003 Kepler Project. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. A.22. md5 (Message-Digest Algorithm 5) License The following software may be included in this product: md5 (Message-Digest Algorithm 5) This code implements the MD5 message-digest algorithm. The algorithm is due to Ron Rivest. This code was written by Colin Plumb in 1993, no copyright is claimed. This code is in the public domain; do with it what you wish. Equivalent code is available from RSA Data Security, Inc. This code has been tested against that, and is equivalent, except that you don't need to include two pages of legalese with every copy. The code has been modified by Mikael Ronstroem to handle calculating a hash value of a key that is always a multiple of 4 bytes long. Word 0 of the calculated 4-word hash value is returned as the hash value. A.23. nt_servc (Windows NT Service class library) License The following software may be included in this product: nt_servc (Windows NT Service class library) Windows NT Service class library Copyright Abandoned 1998 Irena Pancirov - Irnet Snc This file is public domain and comes with NO WARRANTY of any kind A.24. OpenPAM License The following software may be included in this product: OpenPAM Copyright (c) 2002-2003 Networks Associates Technology, Inc. Copyright (c) 2004-2007 Dag-Erling SmУИrgrav All rights reserved. This software was developed for the FreeBSD Project by ThinkSec AS and Network Associates Laboratories, the Security Research Division of Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS research program. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.25. PCRE License The following software may be included in this product: PCRE (Perl Compatible Regular Expressions) Library PCRE LICENCE PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Release 7 of PCRE is distributed under the terms of the "BSD" licence, as specified below. The documentation for PCRE, supplied in the "doc" directory, is distributed under the same terms as the software itself. The basic library functions are written in C and are freestanding. Also included in the distribution is a set of C++ wrapper functions. THE BASIC LIBRARY FUNCTIONS --------------------------- Written by: Philip Hazel Email local part: ph10 Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. Phone: +44 1223 334714. Copyright (c) 1997-2006 University of Cambridge All rights reserved. THE C++ WRAPPER FUNCTIONS ------------------------- Contributed by: Google Inc. Copyright (c) 2006, Google Inc. All rights reserved. THE "BSD" LICENCE ----------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the name of Google Inc. nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. End A.26. Percona Multiple I/O Threads Patch License The following software may be included in this product: Percona Multiple I/O threads patch Copyright (c) 2008, 2009 Percona Inc All rights reserved. Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in th e documentation and/or other materials provided with the distributio n. * Neither the name of Percona Inc. nor the names of its contributors may be used to endorse or promote products derived from this softw are without specific prior written permission of Percona Inc. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. A.27. RegEX-Spencer Library License The following software may be included in this product: Henry Spencer's Regular-Expression Library (RegEX-Spencer) Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved. This software is not subject to any license of the American Telephone and Telegraph Company or of the Regents of the University of Californ ia. Permission is granted to anyone to use this software for any purpose on any computer system, and to alter it and redistribute it, subject to the following restrictions: 1. The author is not responsible for the consequences of use of this software, no matter how awful, even if they arise from flaws in it . 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. Since few users ever read sources, credits must appear in the documentation. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Since few users ever read sources, credits must appear in the documentation. 4. This notice may not be removed or altered. A.28. RFC 3174 - US Secure Hash Algorithm 1 (SHA1) License The following software may be included in this product: RFC 3174 - US Secure Hash Algorithm 1 (SHA1) RFC 3174 - US Secure Hash Algorithm 1 (SHA1) Copyright (C) The Internet Society (2001). All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Acknowledgement Funding for the RFC Editor function is currently provided by the Internet Society. A.29. Richard A. O'Keefe String Library License The following software may be included in this product: Richard A. O'Keefe String Library The Richard O'Keefe String Library is subject to the following notice : These files are in the public domain. This includes getopt.c, which is the work of Henry Spencer, University of Toronto Zoology, who says of it "None of this software is derived from Bell software. I had no access to the source for Bell's versions at the time I wrote it. This software is hereby explicitly placed in the public domain. It may be used for any purpose on any machine by anyone." I would greatly prefer it if *my* material received no military use. The t_ctype.h file is subject to the following notice: Copyright (C) 1998, 1999 by Pruet Boonma, all rights reserved. Copyright (C) 1998 by Theppitak Karoonboonyanan, all rights reserved. Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies. Smaphan Raruenrom and Pruet Boonma makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. A.30. SHA-1 in C License The following software may be included in this product: SHA-1 in C SHA-1 in C By Steve Reid 100% Public Domain A.31. Simple Logging Facade for Java (SLF4J) License The following software may be included in this product: Simple Logging Facade for Java (SLF4J) Copyright (c) 2004-2008 QOS.ch All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. A.32. zlib License The following software may be included in this product: zlib Oracle gratefully acknowledges the contributions of Jean-loup Gailly and Mark Adler in creating the zlib general purpose compression library which is used in this product. zlib.h -- interface of the 'zlib' general purpose compression library Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.3, July 18th, 2005 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.5, April 19th, 2010 Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied war ranty. In no event will the authors be held liable for any damages arising f rom the use of this software. Permission is granted to anyone to use this sof tware for any purpose,including commercial applications, and to alter it an d redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must n ot claim that you wrote the original software. If you use this softwa re in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must n ot be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribu tion. Jean-loup Gailly jloup@gzip.org Mark Adler madler@alumni.caltech.edu A.33. ZLIB.NET License The following software may be included in this product: ZLIB.NET Copyright (c) 2006-2007, ComponentAce http://www.componentace.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mysql-connector-c++-1.1.7/README000644 015771 000012 00000003434 12645244436 016647 0ustar00pb2userwheel000000 000000 MySQL Connector/C++ 1.1 This is a release of MySQL Connector/C++, Oracle's dual-license C++ API for connecting client applications to MySQL. For the avoidance of doubt, this particular copy of the software is released under the version 2 of the GNU General Public License. MySQL Connector/C++ is brought to you by Oracle. Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. License information can be found in the COPYING file. MySQL FOSS License Exception We want free and open source software applications under certain licenses to be able to use the GPL-licensed MySQL Connector/C++ (specified GPL-licensed MySQL client libraries) despite the fact that not all such FOSS licenses are compatible with version 2 of the GNU General Public License. Therefore there are special exceptions to the terms and conditions of the GPLv2 as applied to these client libraries, which are identified and described in more detail in the FOSS License Exception at This distribution may include materials developed by third parties. For license and attribution notices for these materials, please refer to the documentation that accompanies this distribution (see the "Licenses for Third-Party Components" appendix) or view the online documentation at . GPLv2 Disclaimer For the avoidance of doubt, except that if any license choice other than GPL or LGPL is available it will apply instead, Oracle elects to use only the General Public License version 2 (GPLv2) at this time for any software where a choice of GPL license versions is made available with the language indicating that GPLv2 or any later version may be used, or where a choice of which version of the GPL is applied is otherwise unspecified. mysql-connector-c++-1.1.7/VersionInfo.cmake000644 015771 000012 00000005063 12645244436 021232 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(CONNECTOR_MAJOR "1") SET(CONNECTOR_MINOR "1") SET(CONNECTOR_PATCH "7") SET(CONNECTOR_LEVEL "") # "-alpha", "-beta", empty if GA SET(CONNECTOR_QUALITY "GA") # Bump this every time we change the API/ABI SET(MYSQLCPPCONN_SOVERSION "7") IF(CONNECTOR_MINOR LESS 10) SET(CONNECTOR_MINOR_PADDED "0${CONNECTOR_MINOR}") ELSE(CONNECTOR_MINOR LESS 10) SET(CONNECTOR_MINOR_PADDED "${CONNECTOR_MINOR}") ENDIF(CONNECTOR_MINOR LESS 10) # If driver survives 100th patch this has to be changed IF(CONNECTOR_PATCH LESS 10) SET(CONNECTOR_PATCH_PADDED "000${CONNECTOR_PATCH}") ELSE(CONNECTOR_PATCH LESS 10) SET(CONNECTOR_PATCH_PADDED "00${CONNECTOR_PATCH}") ENDIF(CONNECTOR_PATCH LESS 10) SET(CONNECTOR_BASE_VERSION "${CONNECTOR_MAJOR}.${CONNECTOR_MINOR}") SET(CONNECTOR_BASE_PREVIOUS "1.0") SET(CONNECTOR_NUMERIC_VERSION "${CONNECTOR_BASE_VERSION}.${CONNECTOR_PATCH}") SET(CONNECTOR_VERSION "${CONNECTOR_NUMERIC_VERSION}${CONNECTOR_LEVEL}") SET(CPACK_PACKAGE_VERSION_MAJOR ${CONNECTOR_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${CONNECTOR_MINOR}) SET(CPACK_PACKAGE_VERSION_PATCH ${CONNECTOR_PATCH}) SET(CPACK_PACKAGE_RELEASE_TYPE "") # Needed for CPACK configuraiton, used for file name construction. Thus leaving it as is IF(EXTRA_VERSION) SET(MYSQLCPPCONN_VERSION "${CONNECTOR_NUMERIC_VERSION}${EXTRA_VERSION}${CPACK_PACKAGE_RELEASE_TYPE}") ELSE(EXTRA_VERSION) SET(MYSQLCPPCONN_VERSION "${CONNECTOR_NUMERIC_VERSION}${CPACK_PACKAGE_RELEASE_TYPE}") ENDIF(EXTRA_VERSION) mysql-connector-c++-1.1.7/changeCrt.cmake000644 015771 000012 00000004142 12645244436 020664 0ustar00pb2userwheel000000 000000 # Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ########################################################################## # The parameter can be either T or D MACRO(CHANGE_CRT _switch2use) # Or should that be check for VS? IF(WIN32) SET(switch2change "D") IF(_switch2use STREQUAL "D" OR _switch2use STREQUAL "MD" OR _switch2use STREQUAL "/MD") SET(switch2use "D") SET(switch2change "T") ELSE(switch2use STREQUAL "D" OR _switch2use STREQUAL "MD" OR _switch2use STREQUAL "/MD") #Default is to change to /MT SET(switch2use "T") ENDIF(_switch2use STREQUAL "D" OR _switch2use STREQUAL "MD" OR _switch2use STREQUAL "/MD") FOREACH(flags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO) IF(${flags} MATCHES "/M${switch2change}") STRING(REGEX REPLACE "/M${switch2change}" "/M${switch2use}" ${flags} "${${flags}}") ENDIF(${flags} MATCHES "/M${switch2change}") ENDFOREACH(flags) ENDIF(WIN32) ENDMACRO(CHANGE_CRT _switch2use) mysql-connector-c++-1.1.7/cppconn/CMakeLists.txt000644 015771 000012 00000005371 12645244436 022171 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H) CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H) CHECK_TYPE_SIZE("int8_t" HAVE_INT8_T) CHECK_TYPE_SIZE("uint8_t" HAVE_UINT8_T) CHECK_TYPE_SIZE("int16_t" HAVE_INT16_T) CHECK_TYPE_SIZE("uint16_t" HAVE_UINT16_T) CHECK_TYPE_SIZE("int32_t" HAVE_INT32_T) CHECK_TYPE_SIZE("uint32_t" HAVE_UINT32_T) CHECK_TYPE_SIZE("int64_t" HAVE_INT64_T) CHECK_TYPE_SIZE("uint64_t" HAVE_UINT64_T) CHECK_TYPE_SIZE("__int8" HAVE_MS_INT8) CHECK_TYPE_SIZE("unsigned __int8" HAVE_MS_UINT8) CHECK_TYPE_SIZE("__int16" HAVE_MS_INT16) CHECK_TYPE_SIZE("unsigned __int16" HAVE_MS_UINT16) CHECK_TYPE_SIZE("__int32" HAVE_MS_INT32) CHECK_TYPE_SIZE("unsigned __int32" HAVE_MS_UINT32) CHECK_TYPE_SIZE("__int64" HAVE_MS_INT64) CHECK_TYPE_SIZE("unsigned __int64" HAVE_MS_UINT64) CHECK_FUNCTION_EXISTS(strtold HAVE_FUNCTION_STRTOLD) CHECK_FUNCTION_EXISTS(strtol HAVE_FUNCTION_STRTOL) CHECK_FUNCTION_EXISTS(strtoll HAVE_FUNCTION_STRTOLL) CHECK_FUNCTION_EXISTS(strtoul HAVE_FUNCTION_STRTOUL) CHECK_FUNCTION_EXISTS(strtoull HAVE_FUNCTION_STRTOULL) CHECK_FUNCTION_EXISTS(strtoimax HAVE_FUNCTION_STRTOIMAX) CHECK_FUNCTION_EXISTS(strtoumax HAVE_FUNCTION_STRTOUMAX) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cm ${CMAKE_CURRENT_BINARY_DIR}/config.h) SET(MYSQLCPPCONN_INSTALL_HEADERS build_config.h ${CMAKE_CURRENT_BINARY_DIR}/config.h connection.h datatype.h driver.h exception.h metadata.h parameter_metadata.h prepared_statement.h resultset.h resultset_metadata.h statement.h sqlstring.h warning.h ${CMAKE_CURRENT_BINARY_DIR}/version_info.h variant.h) INSTALL(FILES ${MYSQLCPPCONN_INSTALL_HEADERS} DESTINATION include/cppconn) mysql-connector-c++-1.1.7/cppconn/build_config.h000644 015771 000012 00000003252 12645244436 022222 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_BUILD_CONFIG_H_ #define _SQL_BUILD_CONFIG_H_ #ifndef CPPCONN_PUBLIC_FUNC #if defined(_WIN32) // mysqlcppconn_EXPORTS is added by cmake and defined for dynamic lib build only #ifdef mysqlcppconn_EXPORTS #define CPPCONN_PUBLIC_FUNC __declspec(dllexport) #else // this is for static build #ifdef CPPCONN_LIB_BUILD #define CPPCONN_PUBLIC_FUNC #else // this is for clients using dynamic lib #define CPPCONN_PUBLIC_FUNC __declspec(dllimport) #endif #endif #else #define CPPCONN_PUBLIC_FUNC #endif #endif //#ifndef CPPCONN_PUBLIC_FUNC #endif //#ifndef _SQL_BUILD_CONFIG_H_ mysql-connector-c++-1.1.7/cppconn/config.h.cm000644 015771 000012 00000005646 12645244436 021452 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPL as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // libmysql defines HAVE_STRTOUL (on win), so we have to follow different pattern in definitions names // to avoid annoying warnings. #cmakedefine HAVE_FUNCTION_STRTOLD 1 #cmakedefine HAVE_FUNCTION_STRTOLL 1 #cmakedefine HAVE_FUNCTION_STRTOL 1 #cmakedefine HAVE_FUNCTION_STRTOULL 1 #cmakedefine HAVE_FUNCTION_STRTOUL 1 #cmakedefine HAVE_FUNCTION_STRTOIMAX 1 #cmakedefine HAVE_FUNCTION_STRTOUMAX 1 #cmakedefine HAVE_STDINT_H 1 #cmakedefine HAVE_INTTYPES_H 1 #cmakedefine HAVE_INT8_T 1 #cmakedefine HAVE_UINT8_T 1 #cmakedefine HAVE_INT16_T 1 #cmakedefine HAVE_UINT16_T 1 #cmakedefine HAVE_INT32_T 1 #cmakedefine HAVE_UINT32_T 1 #cmakedefine HAVE_INT32_T 1 #cmakedefine HAVE_UINT32_T 1 #cmakedefine HAVE_INT64_T 1 #cmakedefine HAVE_UINT64_T 1 #cmakedefine HAVE_MS_INT8 1 #cmakedefine HAVE_MS_UINT8 1 #cmakedefine HAVE_MS_INT16 1 #cmakedefine HAVE_MS_UINT16 1 #cmakedefine HAVE_MS_INT32 1 #cmakedefine HAVE_MS_UINT32 1 #cmakedefine HAVE_MS_INT64 1 #cmakedefine HAVE_MS_UINT64 1 #ifdef HAVE_STDINT_H #include #endif #if defined(HAVE_INTTYPES_H) && !defined(_WIN32) #include #endif #if defined(_WIN32) #ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES #if _MSC_VER >= 1600 #include #else #if !defined(HAVE_INT8_T) && defined(HAVE_MS_INT8) typedef __int8 int8_t; #endif #ifdef HAVE_MS_UINT8 typedef unsigned __int8 uint8_t; #endif #ifdef HAVE_MS_INT16 typedef __int16 int16_t; #endif #ifdef HAVE_MS_UINT16 typedef unsigned __int16 uint16_t; #endif #ifdef HAVE_MS_INT32 typedef __int32 int32_t; #endif #ifdef HAVE_MS_UINT32 typedef unsigned __int32 uint32_t; #endif #ifdef HAVE_MS_INT64 typedef __int64 int64_t; #endif #ifdef HAVE_MS_UINT64 typedef unsigned __int64 uint64_t; #endif #endif // _MSC_VER >= 1600 #endif // CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES #endif // _WIN32 mysql-connector-c++-1.1.7/cppconn/connection.h000644 015771 000012 00000010713 12645244436 021735 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_CONNECTION_H_ #define _SQL_CONNECTION_H_ #include #include "build_config.h" #include "warning.h" #include "sqlstring.h" #include "variant.h" namespace sql { typedef sql::Variant ConnectPropertyVal; typedef std::map< sql::SQLString, ConnectPropertyVal > ConnectOptionsMap; class DatabaseMetaData; class PreparedStatement; class Statement; class Driver; typedef enum transaction_isolation { TRANSACTION_NONE= 0, TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_REPEATABLE_READ, TRANSACTION_SERIALIZABLE } enum_transaction_isolation; class Savepoint { /* Prevent use of these */ Savepoint(const Savepoint &); void operator=(Savepoint &); public: Savepoint() {}; virtual ~Savepoint() {}; virtual int getSavepointId() = 0; virtual sql::SQLString getSavepointName() = 0; }; class CPPCONN_PUBLIC_FUNC Connection { /* Prevent use of these */ Connection(const Connection &); void operator=(Connection &); public: Connection() {}; virtual ~Connection() {}; virtual void clearWarnings() = 0; virtual Statement *createStatement() = 0; virtual void close() = 0; virtual void commit() = 0; virtual bool getAutoCommit() = 0; virtual sql::SQLString getCatalog() = 0; virtual Driver *getDriver() = 0; virtual sql::SQLString getSchema() = 0; virtual sql::SQLString getClientInfo() = 0; virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0; virtual sql::SQLString getClientOption(const sql::SQLString & optionName) = 0; virtual DatabaseMetaData * getMetaData() = 0; virtual enum_transaction_isolation getTransactionIsolation() = 0; virtual const SQLWarning * getWarnings() = 0; virtual bool isClosed() = 0; virtual bool isReadOnly() = 0; virtual bool isValid() = 0; virtual bool reconnect() = 0; virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0; virtual void releaseSavepoint(Savepoint * savepoint) = 0; virtual void rollback() = 0; virtual void rollback(Savepoint * savepoint) = 0; virtual void setAutoCommit(bool autoCommit) = 0; virtual void setCatalog(const sql::SQLString& catalog) = 0; virtual void setSchema(const sql::SQLString& catalog) = 0; virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0; virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue) = 0; virtual void setHoldability(int holdability) = 0; virtual void setReadOnly(bool readOnly) = 0; virtual Savepoint * setSavepoint() = 0; virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0; virtual void setTransactionIsolation(enum_transaction_isolation level) = 0; /* virtual void setTypeMap(Map map) = 0; */ }; } /* namespace sql */ #endif // _SQL_CONNECTION_H_ mysql-connector-c++-1.1.7/cppconn/datatype.h000644 015771 000012 00000003043 12645244436 021407 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_DATATYPE_H_ #define _SQL_DATATYPE_H_ namespace sql { class DataType { DataType(); public: enum { UNKNOWN = 0, BIT, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT, REAL, DOUBLE, DECIMAL, NUMERIC, CHAR, BINARY, VARCHAR, VARBINARY, LONGVARCHAR, LONGVARBINARY, TIMESTAMP, DATE, TIME, YEAR, GEOMETRY, ENUM, SET, SQLNULL, JSON }; }; } /* namespace */ #endif /* _SQL_DATATYPE_H_ */ mysql-connector-c++-1.1.7/cppconn/driver.h000644 015771 000012 00000004033 12645244436 021067 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_DRIVER_H_ #define _SQL_DRIVER_H_ #include "connection.h" #include "build_config.h" namespace sql { class CPPCONN_PUBLIC_FUNC Driver { protected: virtual ~Driver() {} public: // Attempts to make a database connection to the given URL. virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0; virtual Connection * connect(ConnectOptionsMap & options) = 0; virtual int getMajorVersion() = 0; virtual int getMinorVersion() = 0; virtual int getPatchVersion() = 0; virtual const sql::SQLString & getName() = 0; virtual void threadInit() = 0; virtual void threadEnd() = 0; }; } /* namespace sql */ extern "C" { CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance(); /* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */ CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib); } #endif /* _SQL_DRIVER_H_ */ mysql-connector-c++-1.1.7/cppconn/exception.h000644 015771 000012 00000011170 12645244436 021572 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_EXCEPTION_H_ #define _SQL_EXCEPTION_H_ #include "build_config.h" #include #include #include namespace sql { #define MEMORY_ALLOC_OPERATORS(Class) \ void* operator new(size_t size) throw (std::bad_alloc) { return ::operator new(size); } \ void* operator new(size_t, void*) throw(); \ void* operator new(size_t, const std::nothrow_t&) throw(); \ void* operator new[](size_t) throw (std::bad_alloc); \ void* operator new[](size_t, void*) throw(); \ void* operator new[](size_t, const std::nothrow_t&) throw(); \ void* operator new(size_t N, std::allocator&); #ifdef _WIN32 #pragma warning (disable : 4290) //warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #pragma warning(push) #pragma warning(disable: 4275) #endif class CPPCONN_PUBLIC_FUNC SQLException : public std::runtime_error { #ifdef _WIN32 #pragma warning(pop) #endif protected: const std::string sql_state; const int errNo; public: SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {} SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) : std::runtime_error (reason ), sql_state (SQLState ), errNo (vendorCode) {} SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {} SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {} SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {} const std::string & getSQLState() const { return sql_state; } const char * getSQLStateCStr() const { return sql_state.c_str(); } int getErrorCode() const { return errNo; } virtual ~SQLException() throw () {}; protected: MEMORY_ALLOC_OPERATORS(SQLException) }; struct CPPCONN_PUBLIC_FUNC MethodNotImplementedException : public SQLException { MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC InvalidArgumentException : public SQLException { InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC InvalidInstanceException : public SQLException { InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC NonScrollableException : public SQLException { NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {} }; struct CPPCONN_PUBLIC_FUNC SQLUnsupportedOptionException : public SQLException { SQLUnsupportedOptionException(const SQLUnsupportedOptionException& e, const std::string conn_option) : SQLException(e.what(), e.sql_state, e.errNo), option(conn_option ) {} SQLUnsupportedOptionException(const std::string& reason, const std::string conn_option) : SQLException(reason, "", 0), option(conn_option ) {} const char *getConnectionOption() const { return option.c_str(); } ~SQLUnsupportedOptionException() throw () {}; protected: const std::string option; }; } /* namespace sql */ #endif /* _SQL_EXCEPTION_H_ */ mysql-connector-c++-1.1.7/cppconn/metadata.h000644 015771 000012 00000033456 12645244436 021367 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_METADATA_H_ #define _SQL_METADATA_H_ #include #include #include "datatype.h" #include "sqlstring.h" namespace sql { class ResultSet; class DatabaseMetaData { protected: virtual ~DatabaseMetaData() {} public: enum { attributeNoNulls = 0, attributeNullable, attributeNullableUnknown }; enum { bestRowTemporary = 0, bestRowTransaction, bestRowSession }; enum { bestRowUnknown = 0, bestRowNotPseudo, bestRowPseudo }; enum { columnNoNulls = 0, columnNullable, columnNullableUnknown }; enum { importedKeyCascade = 0, importedKeyInitiallyDeferred, importedKeyInitiallyImmediate, importedKeyNoAction, importedKeyNotDeferrable, importedKeyRestrict, importedKeySetDefault, importedKeySetNull }; enum { procedureColumnIn = 0, procedureColumnInOut, procedureColumnOut, procedureColumnResult, procedureColumnReturn, procedureColumnUnknown, procedureNoNulls, procedureNoResult, procedureNullable, procedureNullableUnknown, procedureResultUnknown, procedureReturnsResult }; enum { sqlStateSQL99 = 0, sqlStateXOpen }; enum { tableIndexClustered = 0, tableIndexHashed, tableIndexOther, tableIndexStatistic }; enum { versionColumnUnknown = 0, versionColumnNotPseudo = 1, versionColumnPseudo = 2 }; enum { typeNoNulls = 0, typeNullable = 1, typeNullableUnknown = 2 }; enum { typePredNone = 0, typePredChar = 1, typePredBasic= 2, typeSearchable = 3 }; virtual bool allProceduresAreCallable() = 0; virtual bool allTablesAreSelectable() = 0; virtual bool dataDefinitionCausesTransactionCommit() = 0; virtual bool dataDefinitionIgnoredInTransactions() = 0; virtual bool deletesAreDetected(int type) = 0; virtual bool doesMaxRowSizeIncludeBlobs() = 0; virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0; virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0; virtual ResultSet * getCatalogs() = 0; virtual const sql::SQLString& getCatalogSeparator() = 0; virtual const sql::SQLString& getCatalogTerm() = 0; virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0; virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0; virtual Connection * getConnection() = 0; virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0; virtual unsigned int getDatabaseMajorVersion() = 0; virtual unsigned int getDatabaseMinorVersion() = 0; virtual unsigned int getDatabasePatchVersion() = 0; virtual const sql::SQLString& getDatabaseProductName() = 0; virtual SQLString getDatabaseProductVersion() = 0; virtual int getDefaultTransactionIsolation() = 0; virtual unsigned int getDriverMajorVersion() = 0; virtual unsigned int getDriverMinorVersion() = 0; virtual unsigned int getDriverPatchVersion() = 0; virtual const sql::SQLString& getDriverName() = 0; virtual const sql::SQLString& getDriverVersion() = 0; virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual const sql::SQLString& getExtraNameCharacters() = 0; virtual const sql::SQLString& getIdentifierQuoteString() = 0; virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0; virtual unsigned int getCDBCMajorVersion() = 0; virtual unsigned int getCDBCMinorVersion() = 0; virtual unsigned int getMaxBinaryLiteralLength() = 0; virtual unsigned int getMaxCatalogNameLength() = 0; virtual unsigned int getMaxCharLiteralLength() = 0; virtual unsigned int getMaxColumnNameLength() = 0; virtual unsigned int getMaxColumnsInGroupBy() = 0; virtual unsigned int getMaxColumnsInIndex() = 0; virtual unsigned int getMaxColumnsInOrderBy() = 0; virtual unsigned int getMaxColumnsInSelect() = 0; virtual unsigned int getMaxColumnsInTable() = 0; virtual unsigned int getMaxConnections() = 0; virtual unsigned int getMaxCursorNameLength() = 0; virtual unsigned int getMaxIndexLength() = 0; virtual unsigned int getMaxProcedureNameLength() = 0; virtual unsigned int getMaxRowSize() = 0; virtual unsigned int getMaxSchemaNameLength() = 0; virtual unsigned int getMaxStatementLength() = 0; virtual unsigned int getMaxStatements() = 0; virtual unsigned int getMaxTableNameLength() = 0; virtual unsigned int getMaxTablesInSelect() = 0; virtual unsigned int getMaxUserNameLength() = 0; virtual const sql::SQLString& getNumericFunctions() = 0; virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0; virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0; virtual const sql::SQLString& getProcedureTerm() = 0; virtual int getResultSetHoldability() = 0; virtual ResultSet * getSchemas() = 0; virtual const sql::SQLString& getSchemaTerm() = 0; virtual ResultSet * getSchemaCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0; virtual ResultSet * getSchemaCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0; virtual const sql::SQLString& getSearchStringEscape() = 0; virtual const sql::SQLString& getSQLKeywords() = 0; virtual int getSQLStateType() = 0; virtual const sql::SQLString& getStringFunctions() = 0; virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0; virtual const sql::SQLString& getSystemFunctions() = 0; virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list &types) = 0; virtual ResultSet * getTableTypes() = 0; virtual ResultSet * getTableCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; virtual ResultSet * getTableCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; virtual const sql::SQLString& getTimeDateFunctions() = 0; virtual ResultSet * getTypeInfo() = 0; virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list &types) = 0; virtual SQLString getURL() = 0; virtual SQLString getUserName() = 0; virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual bool insertsAreDetected(int type) = 0; virtual bool isCatalogAtStart() = 0; virtual bool isReadOnly() = 0; virtual bool locatorsUpdateCopy() = 0; virtual bool nullPlusNonNullIsNull() = 0; virtual bool nullsAreSortedAtEnd() = 0; virtual bool nullsAreSortedAtStart() = 0; virtual bool nullsAreSortedHigh() = 0; virtual bool nullsAreSortedLow() = 0; virtual bool othersDeletesAreVisible(int type) = 0; virtual bool othersInsertsAreVisible(int type) = 0; virtual bool othersUpdatesAreVisible(int type) = 0; virtual bool ownDeletesAreVisible(int type) = 0; virtual bool ownInsertsAreVisible(int type) = 0; virtual bool ownUpdatesAreVisible(int type) = 0; virtual bool storesLowerCaseIdentifiers() = 0; virtual bool storesLowerCaseQuotedIdentifiers() = 0; virtual bool storesMixedCaseIdentifiers() = 0; virtual bool storesMixedCaseQuotedIdentifiers() = 0; virtual bool storesUpperCaseIdentifiers() = 0; virtual bool storesUpperCaseQuotedIdentifiers() = 0; virtual bool supportsAlterTableWithAddColumn() = 0; virtual bool supportsAlterTableWithDropColumn() = 0; virtual bool supportsANSI92EntryLevelSQL() = 0; virtual bool supportsANSI92FullSQL() = 0; virtual bool supportsANSI92IntermediateSQL() = 0; virtual bool supportsBatchUpdates() = 0; virtual bool supportsCatalogsInDataManipulation() = 0; virtual bool supportsCatalogsInIndexDefinitions() = 0; virtual bool supportsCatalogsInPrivilegeDefinitions() = 0; virtual bool supportsCatalogsInProcedureCalls() = 0; virtual bool supportsCatalogsInTableDefinitions() = 0; virtual bool supportsColumnAliasing() = 0; virtual bool supportsConvert() = 0; virtual bool supportsConvert(int fromType, int toType) = 0; virtual bool supportsCoreSQLGrammar() = 0; virtual bool supportsCorrelatedSubqueries() = 0; virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0; virtual bool supportsDataManipulationTransactionsOnly() = 0; virtual bool supportsDifferentTableCorrelationNames() = 0; virtual bool supportsExpressionsInOrderBy() = 0; virtual bool supportsExtendedSQLGrammar() = 0; virtual bool supportsFullOuterJoins() = 0; virtual bool supportsGetGeneratedKeys() = 0; virtual bool supportsGroupBy() = 0; virtual bool supportsGroupByBeyondSelect() = 0; virtual bool supportsGroupByUnrelated() = 0; virtual bool supportsIntegrityEnhancementFacility() = 0; virtual bool supportsLikeEscapeClause() = 0; virtual bool supportsLimitedOuterJoins() = 0; virtual bool supportsMinimumSQLGrammar() = 0; virtual bool supportsMixedCaseIdentifiers() = 0; virtual bool supportsMixedCaseQuotedIdentifiers() = 0; virtual bool supportsMultipleOpenResults() = 0; virtual bool supportsMultipleResultSets() = 0; virtual bool supportsMultipleTransactions() = 0; virtual bool supportsNamedParameters() = 0; virtual bool supportsNonNullableColumns() = 0; virtual bool supportsOpenCursorsAcrossCommit() = 0; virtual bool supportsOpenCursorsAcrossRollback() = 0; virtual bool supportsOpenStatementsAcrossCommit() = 0; virtual bool supportsOpenStatementsAcrossRollback() = 0; virtual bool supportsOrderByUnrelated() = 0; virtual bool supportsOuterJoins() = 0; virtual bool supportsPositionedDelete() = 0; virtual bool supportsPositionedUpdate() = 0; virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0; virtual bool supportsResultSetHoldability(int holdability) = 0; virtual bool supportsResultSetType(int type) = 0; virtual bool supportsSavepoints() = 0; virtual bool supportsSchemasInDataManipulation() = 0; virtual bool supportsSchemasInIndexDefinitions() = 0; virtual bool supportsSchemasInPrivilegeDefinitions() = 0; virtual bool supportsSchemasInProcedureCalls() = 0; virtual bool supportsSchemasInTableDefinitions() = 0; virtual bool supportsSelectForUpdate() = 0; virtual bool supportsStatementPooling() = 0; virtual bool supportsStoredProcedures() = 0; virtual bool supportsSubqueriesInComparisons() = 0; virtual bool supportsSubqueriesInExists() = 0; virtual bool supportsSubqueriesInIns() = 0; virtual bool supportsSubqueriesInQuantifieds() = 0; virtual bool supportsTableCorrelationNames() = 0; virtual bool supportsTransactionIsolationLevel(int level) = 0; virtual bool supportsTransactions() = 0; virtual bool supportsTypeConversion() = 0; /* SDBC */ virtual bool supportsUnion() = 0; virtual bool supportsUnionAll() = 0; virtual bool updatesAreDetected(int type) = 0; virtual bool usesLocalFilePerTable() = 0; virtual bool usesLocalFiles() = 0; virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0; virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "", const sql::SQLString& schemaName = "", const sql::SQLString& objectType = "", bool includingDdl = true, const sql::SQLString& objectName = "", const sql::SQLString& contextTableName = "") = 0; virtual ResultSet *getSchemaObjectTypes() = 0; }; } /* namespace sql */ #endif /* _SQL_METADATA_H_ */ mysql-connector-c++-1.1.7/cppconn/parameter_metadata.h000644 015771 000012 00000003731 12645244436 023420 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_PARAMETER_METADATA_H_ #define _SQL_PARAMETER_METADATA_H_ #include namespace sql { class ParameterMetaData { public: enum { parameterModeIn, parameterModeInOut, parameterModeOut, parameterModeUnknown }; enum { parameterNoNulls, parameterNullable, parameterNullableUnknown }; virtual sql::SQLString getParameterClassName(unsigned int param) = 0; virtual int getParameterCount() = 0; virtual int getParameterMode(unsigned int param) = 0; virtual int getParameterType(unsigned int param) = 0; virtual sql::SQLString getParameterTypeName(unsigned int param) = 0; virtual int getPrecision(unsigned int param) = 0; virtual int getScale(unsigned int param) = 0; virtual int isNullable(unsigned int param) = 0; virtual bool isSigned(unsigned int param) = 0; protected: virtual ~ParameterMetaData() {} }; } /* namespace sql */ #endif /* _SQL_PARAMETER_METADATA_H_ */ mysql-connector-c++-1.1.7/cppconn/prepared_statement.h000644 015771 000012 00000005435 12645244436 023471 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_PREPARED_STATEMENT_H_ #define _SQL_PREPARED_STATEMENT_H_ #include #include "statement.h" namespace sql { class Connection; class ResultSet; class ResultSetMetaData; class ParameterMetaData; class PreparedStatement : public Statement { public: virtual ~PreparedStatement() {} virtual void clearParameters() = 0; virtual bool execute(const sql::SQLString& sql) = 0; virtual bool execute() = 0; virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0; virtual ResultSet *executeQuery() = 0; virtual int executeUpdate(const sql::SQLString& sql) = 0; virtual int executeUpdate() = 0; virtual ResultSetMetaData * getMetaData() = 0; virtual ParameterMetaData * getParameterMetaData() = 0; virtual bool getMoreResults() = 0; virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0; virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0; virtual void setBoolean(unsigned int parameterIndex, bool value) = 0; virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0; virtual void setDouble(unsigned int parameterIndex, double value) = 0; virtual void setInt(unsigned int parameterIndex, int32_t value) = 0; virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0; virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0; virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0; virtual void setNull(unsigned int parameterIndex, int sqlType) = 0; virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0; virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0; }; } /* namespace sql */ #endif /* _SQL_PREPARED_STATEMENT_H_ */ mysql-connector-c++-1.1.7/cppconn/resultset.h000644 015771 000012 00000010544 12645244436 021632 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_RESULTSET_H_ #define _SQL_RESULTSET_H_ #include "config.h" #include #include #include #include "sqlstring.h" #include "resultset_metadata.h" namespace sql { class Statement; class RowID { public: virtual ~RowID() {} }; class ResultSet { public: enum { CLOSE_CURSORS_AT_COMMIT, HOLD_CURSORS_OVER_COMMIT }; enum { CONCUR_READ_ONLY, CONCUR_UPDATABLE }; enum { FETCH_FORWARD, FETCH_REVERSE, FETCH_UNKNOWN }; typedef enum { TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, TYPE_SCROLL_SENSITIVE } enum_type; virtual ~ResultSet() {} virtual bool absolute(int row) = 0; virtual void afterLast() = 0; virtual void beforeFirst() = 0; virtual void cancelRowUpdates() = 0; virtual void clearWarnings() = 0; virtual void close() = 0; virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0; virtual bool first() = 0; virtual std::istream * getBlob(uint32_t columnIndex) const = 0; virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0; virtual bool getBoolean(uint32_t columnIndex) const = 0; virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0; virtual int getConcurrency() = 0; virtual SQLString getCursorName() = 0; virtual long double getDouble(uint32_t columnIndex) const = 0; virtual long double getDouble(const sql::SQLString& columnLabel) const = 0; virtual int getFetchDirection() = 0; virtual size_t getFetchSize() = 0; virtual int getHoldability() = 0; virtual int32_t getInt(uint32_t columnIndex) const = 0; virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0; virtual uint32_t getUInt(uint32_t columnIndex) const = 0; virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0; virtual int64_t getInt64(uint32_t columnIndex) const = 0; virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0; virtual uint64_t getUInt64(uint32_t columnIndex) const = 0; virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0; virtual ResultSetMetaData * getMetaData() const = 0; virtual size_t getRow() const = 0; virtual RowID * getRowId(uint32_t columnIndex) = 0; virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0; virtual const Statement * getStatement() const = 0; virtual SQLString getString(uint32_t columnIndex) const = 0; virtual SQLString getString(const sql::SQLString& columnLabel) const = 0; virtual enum_type getType() const = 0; virtual void getWarnings() = 0; virtual void insertRow() = 0; virtual bool isAfterLast() const = 0; virtual bool isBeforeFirst() const = 0; virtual bool isClosed() const = 0; virtual bool isFirst() const = 0; virtual bool isLast() const = 0; virtual bool isNull(uint32_t columnIndex) const = 0; virtual bool isNull(const sql::SQLString& columnLabel) const = 0; virtual bool last() = 0; virtual bool next() = 0; virtual void moveToCurrentRow() = 0; virtual void moveToInsertRow() = 0; virtual bool previous() = 0; virtual void refreshRow() = 0; virtual bool relative(int rows) = 0; virtual bool rowDeleted() = 0; virtual bool rowInserted() = 0; virtual bool rowUpdated() = 0; virtual void setFetchSize(size_t rows) = 0; virtual size_t rowsCount() const = 0; virtual bool wasNull() const = 0; }; } /* namespace sql */ #endif /* _SQL_RESULTSET_H_ */ mysql-connector-c++-1.1.7/cppconn/resultset_metadata.h000644 015771 000012 00000005365 12645244436 023477 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_RESULTSET_METADATA_H_ #define _SQL_RESULTSET_METADATA_H_ #include "sqlstring.h" #include "datatype.h" namespace sql { class ResultSetMetaData { public: enum { columnNoNulls, columnNullable, columnNullableUnknown }; virtual SQLString getCatalogName(unsigned int column) = 0; virtual unsigned int getColumnCount() = 0; virtual unsigned int getColumnDisplaySize(unsigned int column) = 0; virtual SQLString getColumnLabel(unsigned int column) = 0; virtual SQLString getColumnName(unsigned int column) = 0; virtual int getColumnType(unsigned int column) = 0; virtual SQLString getColumnTypeName(unsigned int column) = 0; virtual SQLString getColumnCharset(unsigned int columnIndex) = 0; virtual SQLString getColumnCollation(unsigned int columnIndex) = 0; virtual unsigned int getPrecision(unsigned int column) = 0; virtual unsigned int getScale(unsigned int column) = 0; virtual SQLString getSchemaName(unsigned int column) = 0; virtual SQLString getTableName(unsigned int column) = 0; virtual bool isAutoIncrement(unsigned int column) = 0; virtual bool isCaseSensitive(unsigned int column) = 0; virtual bool isCurrency(unsigned int column) = 0; virtual bool isDefinitelyWritable(unsigned int column) = 0; virtual int isNullable(unsigned int column) = 0; virtual bool isNumeric(unsigned int column) = 0; virtual bool isReadOnly(unsigned int column) = 0; virtual bool isSearchable(unsigned int column) = 0; virtual bool isSigned(unsigned int column) = 0; virtual bool isWritable(unsigned int column) = 0; virtual bool isZerofill(unsigned int column) = 0; protected: virtual ~ResultSetMetaData() {} }; } /* namespace sql */ #endif /* _SQL_RESULTSET_METADATA_H_ */ mysql-connector-c++-1.1.7/cppconn/sqlstring.h000644 015771 000012 00000012641 12645244436 021626 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_STRING_H_ #define _SQL_STRING_H_ #include #include #include "build_config.h" #include namespace sql { class CPPCONN_PUBLIC_FUNC SQLString { std::string realStr; public: #ifdef _WIN32 //TODO something less dirty-hackish. static const size_t npos = static_cast(-1); #else static const size_t npos = std::string::npos; #endif ~SQLString() {} SQLString() {} SQLString(const SQLString & other) : realStr(other.realStr) {} SQLString(const std::string & other) : realStr(other) {} SQLString(const char other[]) : realStr(other) {} SQLString(const char * s, size_t n) : realStr(s, n) {} // Needed for stuff like SQLString str= "char * string constant" const SQLString & operator=(const char * s) { realStr = s; return *this; } const SQLString & operator=(const std::string & rhs) { realStr = rhs; return *this; } const SQLString & operator=(const SQLString & rhs) { realStr = rhs.realStr; return *this; } // Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var; operator const std::string &() const { return realStr; } /** For access std::string methods. Not sure we need it. Makes it look like some smart ptr. possibly operator* - will look even more like smart ptr */ std::string * operator ->() { return & realStr; } int compare(const SQLString& str) const { return realStr.compare(str.realStr); } int compare(const char * s) const { return realStr.compare(s); } int compare(size_t pos1, size_t n1, const char * s) const { return realStr.compare(pos1, n1, s); } int caseCompare(const SQLString &s) const { std::string tmp(realStr), str(s); std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); std::transform(str.begin(), str.end(), str.begin(), ::tolower); return tmp.compare(str); } int caseCompare(const char * s) const { std::string tmp(realStr), str(s); std::transform(str.begin(), str.end(), str.begin(), ::tolower); std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); return tmp.compare(str); } int caseCompare(size_t pos1, size_t n1, const char * s) const { std::string tmp(realStr.c_str() + pos1, n1), str(s); std::transform(str.begin(), str.end(), str.begin(), ::tolower); std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); return tmp.compare(str); } const std::string & asStdString() const { return realStr; } const char * c_str() const { return realStr.c_str(); } size_t length() const { return realStr.length(); } SQLString & append(const std::string & str) { realStr.append(str); return *this; } SQLString & append(const char * s) { realStr.append(s); return *this; } const char& operator[](size_t pos) const { return realStr[pos]; } size_t find(char c, size_t pos = 0) const { return realStr.find(c, pos); } size_t find(const SQLString & s, size_t pos = 0) const { return realStr.find(s.realStr, pos); } SQLString substr(size_t pos = 0, size_t n = npos) const { return realStr.substr(pos, n); } const SQLString& replace(size_t pos1, size_t n1, const SQLString & s) { realStr.replace(pos1, n1, s.realStr); return *this; } size_t find_first_of(char c, size_t pos = 0) const { return realStr.find_first_of(c, pos); } size_t find_last_of(char c, size_t pos = npos) const { return realStr.find_last_of(c, pos); } const SQLString & operator+=(const SQLString & op2) { realStr += op2.realStr; return *this; } }; /* Operators that can and have to be not a member. */ inline const SQLString operator+(const SQLString & op1, const SQLString & op2) { return sql::SQLString(op1.asStdString() + op2.asStdString()); } inline bool operator ==(const SQLString & op1, const SQLString & op2) { return (op1.asStdString() == op2.asStdString()); } inline bool operator !=(const SQLString & op1, const SQLString & op2) { return (op1.asStdString() != op2.asStdString()); } inline bool operator <(const SQLString & op1, const SQLString & op2) { return op1.asStdString() < op2.asStdString(); } }// namespace sql namespace std { // operator << for SQLString output inline ostream & operator << (ostream & os, const sql::SQLString & str ) { return os << str.asStdString(); } } #endif mysql-connector-c++-1.1.7/cppconn/statement.h000644 015771 000012 00000004660 12645244436 021606 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_STATEMENT_H_ #define _SQL_STATEMENT_H_ #include "config.h" #include "resultset.h" #include namespace sql { class ResultSet; class Connection; class SQLWarning; class Statement { public: virtual ~Statement() {}; virtual Connection * getConnection() = 0; virtual void cancel() = 0; virtual void clearWarnings() = 0; virtual void close() = 0; virtual bool execute(const sql::SQLString& sql) = 0; virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0; virtual int executeUpdate(const sql::SQLString& sql) = 0; virtual size_t getFetchSize() = 0; virtual unsigned int getMaxFieldSize() = 0; virtual uint64_t getMaxRows() = 0; virtual bool getMoreResults() = 0; virtual unsigned int getQueryTimeout() = 0; virtual ResultSet * getResultSet() = 0; virtual sql::ResultSet::enum_type getResultSetType() = 0; virtual uint64_t getUpdateCount() = 0; virtual const SQLWarning * getWarnings() = 0; virtual void setCursorName(const sql::SQLString & name) = 0; virtual void setEscapeProcessing(bool enable) = 0; virtual void setFetchSize(size_t rows) = 0; virtual void setMaxFieldSize(unsigned int max) = 0; virtual void setMaxRows(unsigned int max) = 0; virtual void setQueryTimeout(unsigned int seconds) = 0; virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0; }; } /* namespace sql */ #endif /* _SQL_STATEMENT_H_ */ mysql-connector-c++-1.1.7/cppconn/variant.h000644 015771 000012 00000015124 12645244436 021243 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_VARIANT_H_ #define _SQL_VARIANT_H_ #include #include #include #include #include #include "build_config.h" #include "sqlstring.h" #include "exception.h" namespace sql { class BaseVariantImpl { public: BaseVariantImpl (void *ptr, sql::SQLString vtype) : cvptr(ptr), vTypeName(vtype) {} virtual ~BaseVariantImpl() { cvptr=NULL; } virtual BaseVariantImpl* Clone()=0; template T* get() const { if (typeid(T).name() == typeid(void).name()) { return static_cast< T * > (cvptr); } if ((vTypeName == typeid(std::string).name() && typeid(T).name() == typeid(sql::SQLString).name()) || (vTypeName == typeid(sql::SQLString).name() && typeid(T).name() == typeid(std::string).name()) || (vTypeName == typeid(std::map< std::string, std::string >).name() && typeid(T).name() == typeid(std::map< sql::SQLString, sql::SQLString >).name()) || (vTypeName == typeid(std::map< sql::SQLString, sql::SQLString >).name() && typeid(T).name() == typeid(std::map< std::string, std::string >).name()) || (vTypeName == typeid(std::list< std::string >).name() && typeid(T).name() == typeid(std::list< sql::SQLString >).name()) || (vTypeName == typeid(std::list< sql::SQLString >).name() && typeid(T).name() == typeid(std::list< std::string >).name())) { return static_cast< T * > (cvptr); } if (typeid(T).name() != vTypeName) { throw sql::InvalidArgumentException("Variant type doesn't match."); } return static_cast< T * > (cvptr); } protected: void *cvptr; sql::SQLString vTypeName; }; template class VariantImpl : public BaseVariantImpl { public: VariantImpl(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {} ~VariantImpl() { destroy_content(); } VariantImpl(VariantImpl& that) : BaseVariantImpl(that) { copy_content(that); } VariantImpl& operator=(VariantImpl& that) { if (this != &that) { destroy_content(); if (cvptr == NULL) { copy_content(that); } } return *this; } virtual VariantImpl* Clone() { return new VariantImpl(*this); } private: void destroy_content() { T *tmp=static_cast< T * >(cvptr); if (tmp) { delete tmp; cvptr=NULL; } } void copy_content(BaseVariantImpl& that) { cvptr=new T (*(static_cast< T * > (that.get< void >()))); } }; template class VariantMap : public BaseVariantImpl { public: VariantMap(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {} ~VariantMap() { destroy_content(); } VariantMap(VariantMap& that) : BaseVariantImpl(that) { if (this != &that) { copy_content(that); } } VariantMap& operator=(VariantMap& that) { if (this != &that) { destroy_content(); copy_content(that); } return *this; } virtual VariantMap* Clone() { return new VariantMap(*this); } private: void destroy_content() { T *tmp=static_cast< T *> (cvptr); if (tmp) { tmp->clear(); delete tmp; cvptr=NULL; } } void copy_content(VariantMap& var) { T *tmp=static_cast< T *> (var.cvptr); if (tmp) { cvptr=new T(); typename T::const_iterator cit=tmp->begin(); while(cit != tmp->end()) { (static_cast< T * >(cvptr))->insert( std::make_pair(sql::SQLString(cit->first), sql::SQLString(cit->second))); ++cit; } } } }; template class VariantList : public BaseVariantImpl { public: VariantList(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {} ~VariantList() { destroy_content(); } VariantList(VariantList& that) : BaseVariantImpl(that) { if (this != &that) { copy_content(that); } } VariantList& operator=(VariantList& that) { if (this != &that) { destroy_content(); copy_content(that); } return *this; } virtual VariantList* Clone() { return new VariantList(*this); } private: void destroy_content() { T *tmp=static_cast< T *> (cvptr); if (tmp) { tmp->clear(); delete tmp; cvptr=NULL; } } void copy_content(VariantList& var) { T *tmp=static_cast< T *> (var.cvptr); if (tmp) { cvptr=new T(); typename T::const_iterator cit=tmp->begin(); while(cit != tmp->end()) { (static_cast< T * >(cvptr))->push_back(sql::SQLString(*cit)); ++cit; } } } }; class CPPCONN_PUBLIC_FUNC Variant { public: Variant(const int &i=0) : variant(new VariantImpl< int >(i)) {} Variant(const double &i) : variant(new VariantImpl< double >(i)) {} Variant(const bool &i) : variant(new VariantImpl< bool >(i)) {} Variant(const std::string &i) : variant(new VariantImpl< std::string >(i)) {} Variant(const sql::SQLString &i) : variant(new VariantImpl< sql::SQLString >(i)) {} Variant(const std::list< std::string > &i) : variant(new VariantList< std::list < std::string > >(i)) {} Variant(const std::list< sql::SQLString > &i) : variant(new VariantList< std::list < sql::SQLString > >(i)) {} Variant(const std::map< std::string, std::string > &i) : variant(new VariantMap< std::map< std::string, std::string > >(i)) {} Variant(const std::map< sql::SQLString, sql::SQLString > &i) : variant(new VariantMap< std::map< sql::SQLString, sql::SQLString > >(i)) {} ~Variant() { if (variant) { delete variant; variant=0; } } Variant(const Variant& that) { if (this != &that) { variant=that.variant->Clone(); } } Variant& operator=(const Variant& that) { if (this != &that) { delete variant; variant=that.variant->Clone(); } return *this; } template T* get() const { return variant->get(); } private: BaseVariantImpl *variant; }; } /* namespace sql */ #endif /* _SQL_VARIANT_H_ */ mysql-connector-c++-1.1.7/cppconn/version_info.h.cmake000644 015771 000012 00000003203 12645244436 023351 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* @EDIT_WARNING_MESSAGE@ */ #define MYCPPCONN_DM_MAJOR_VERSION @CONNECTOR_MAJOR@ #define MYCPPCONN_DM_MINOR_VERSION @CONNECTOR_MINOR@ #define MYCPPCONN_DM_PATCH_VERSION @CONNECTOR_PATCH@ #define MYCPPCONN_DM_VERSION "@CONNECTOR_MAJOR@.@CONNECTOR_MINOR_PADDED@.@CONNECTOR_PATCH_PADDED@" #define MYCPPCONN_DM_VERSION_ID @CONNECTOR_MAJOR@@CONNECTOR_MINOR_PADDED@@CONNECTOR_PATCH_PADDED@ /* Driver version info */ #define MYCPPCONN_STATIC_MYSQL_VERSION "@MYSQL_VERSION@" #define MYCPPCONN_STATIC_MYSQL_VERSION_ID @MYSQL_NUM_VERSION@ #define MYCPPCONN_BOOST_VERSION @Boost_VERSION@ mysql-connector-c++-1.1.7/cppconn/warning.h000644 015771 000012 00000003555 12645244436 021251 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SQL_WARNING_H_ #define _SQL_WARNING_H_ #include #include #include #include "sqlstring.h" namespace sql { #ifdef _WIN32 #pragma warning (disable : 4290) //warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif class SQLWarning { public: SQLWarning(){} virtual const sql::SQLString & getMessage() const = 0; virtual const sql::SQLString & getSQLState() const = 0; virtual int getErrorCode() const = 0; virtual const SQLWarning * getNextWarning() const = 0; virtual void setNextWarning(const SQLWarning * _next) = 0; protected: virtual ~SQLWarning(){}; SQLWarning(const SQLWarning& e){}; private: const SQLWarning & operator = (const SQLWarning & rhs); }; } /* namespace sql */ #endif /* _SQL_WARNING_H_ */ mysql-connector-c++-1.1.7/driver/CMakeLists.txt000755 015771 000012 00000030545 12645244436 022030 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # There is a generated "version_info.h" in "cppconn/" as well, # specify that we want the one built from this directory INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) LINK_DIRECTORIES(${MYSQLCPPCONN_BOOST_LIBRARY_DIRS}) SET(MYSQLCPPCONN_TRACE_ENABLE 0 CACHE BOOL "trace-enabled") IF(MYSQLCPPCONN_TRACE_ENABLE) MESSAGE(STATUS "Building with tracing functionality") # Visual Studio 8 and up understand Variadic macros IF(WIN32) IF(CMAKE_GENERATOR MATCHES "Visual Studio 8" OR CMAKE_GENERATOR MATCHES "Visual Studio 9" OR CMAKE_GENERATOR MATCHES "NMake Makefiles") ADD_DEFINITIONS("-DCPPCONN_TRACE_ENABLED") ELSE(CMAKE_GENERATOR MATCHES "Visual Studio 8" OR CMAKE_GENERATOR MATCHES "Visual Studio 9" OR CMAKE_GENERATOR MATCHES "NMake Makefiles") MESSAGE(STATUS "Tracing will not be available in this build. VC8 or VC9 is needed.") ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8" OR CMAKE_GENERATOR MATCHES "Visual Studio 9" OR CMAKE_GENERATOR MATCHES "NMake Makefiles") ELSE(WIN32) ADD_DEFINITIONS("-DCPPCONN_TRACE_ENABLED") ENDIF(WIN32) ENDIF(MYSQLCPPCONN_TRACE_ENABLE) SET(MYSQLCLIENT_STATIC_BINDING 1 CACHE BOOL "enable static binding") IF(MYSQLCLIENT_STATIC_BINDING) MESSAGE(STATUS "Using static libmysql binding") ELSE(MYSQLCLIENT_STATIC_BINDING) MESSAGE(STATUS "Using dynamic libmysql binding") ENDIF(MYSQLCLIENT_STATIC_BINDING) IF(NOT MYSQLCLIENT_STATIC_BINDING) IF(NOT WIN32) CHECK_INCLUDE_FILES(dlfcn.h HAVE_DLFCN_H) # We are not on windows and don't have dlfcn.h - so we need static binding IF(NOT HAVE_DLFCN_H) MESSAGE(FATAL_ERROR "Dynamic binding has been requested but we cannot find dlfcn.h!") SET(MYSQLCLIENT_STATIC_BINDING 1) ENDIF(NOT HAVE_DLFCN_H) ENDIF(NOT WIN32) ENDIF(NOT MYSQLCLIENT_STATIC_BINDING) #----------------- # CPPFLAGS, CXXFLAGS and LDFLAGS from the environment SET(MYSQLCPPCONN_DT_RPATH "" CACHE STRING "For dynamic libmysql binding: DT_RPATH to set (default: unset)") IF(MYSQLCPPCONN_DT_RPATH) SET(CMAKE_SKIP_BUILD_RPATH TRUE) SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) SET(CMAKE_INSTALL_RPATH ${MYSQLCPPCONN_DT_RPATH}) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) MESSAGE(STATUS "DT_RPATH set to ${CMAKE_INSTALL_RPATH}") ELSE(MYSQLCPPCONN_DT_RPATH) SET(CMAKE_SKIP_RPATH TRUE) MESSAGE(STATUS "DT_RPATH will not be set") ENDIF(MYSQLCPPCONN_DT_RPATH) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/nativeapi/binding_config.h.cm ${CMAKE_CURRENT_BINARY_DIR}/nativeapi/binding_config.h) SET(MYSQLCPPCONN_SOURCES mysql_art_resultset.cpp mysql_art_rset_metadata.cpp mysql_connection.cpp mysql_debug.cpp mysql_driver.cpp mysql_metadata.cpp mysql_parameter_metadata.cpp mysql_prepared_statement.cpp mysql_ps_resultset.cpp mysql_ps_resultset_metadata.cpp mysql_resultbind.cpp mysql_resultset.cpp mysql_resultset_metadata.cpp mysql_statement.cpp mysql_util.cpp mysql_warning.cpp mysql_uri.cpp nativeapi/mysql_client_api.cpp nativeapi/library_loader.cpp nativeapi/mysql_native_driver_wrapper.cpp nativeapi/mysql_native_connection_wrapper.cpp nativeapi/mysql_native_statement_wrapper.cpp nativeapi/mysql_native_resultset_wrapper.cpp ) IF(WIN32) # adding headers to sources, so they will be included to VS projects SET(MYSQLCPPCONN_SOURCES ${MYSQLCPPCONN_SOURCES} mysql_art_resultset.h mysql_art_rset_metadata.h mysql_connection.h mysql_connection_options.h mysql_debug.h mysql_driver.h mysql_error.h mysql_metadata.h mysql_parameter_metadata.h mysql_prepared_statement.h mysql_ps_resultset.h mysql_ps_resultset_metadata.h mysql_resultbind.h mysql_resultset.h mysql_resultset_metadata.h mysql_statement.h mysql_util.h mysql_warning.h mysql_uri.h ${CMAKE_CURRENT_BINARY_DIR}/version_info.h nativeapi/mysql_client_api.h nativeapi/mysql_native_driver_wrapper.h nativeapi/native_driver_wrapper.h nativeapi/mysql_native_connection_wrapper.h nativeapi/native_connection_wrapper.h nativeapi/mysql_native_statement_wrapper.h nativeapi/native_statement_wrapper.h nativeapi/mysql_native_resultset_wrapper.h nativeapi/native_resultset_wrapper.h ../cppconn/warning.h ../cppconn/statement.h ../cppconn/sqlstring.h ../cppconn/resultset_metadata.h ../cppconn/resultset.h ../cppconn/prepared_statement.h ../cppconn/parameter_metadata.h ../cppconn/metadata.h ../cppconn/exception.h ../cppconn/driver.h ../cppconn/datatype.h ../cppconn/variant.h ../cppconn/connection.h ../cppconn/config.h ../cppconn/build_config.h ) IF(NOT MYSQLCLIENT_STATIC_BINDING) SET(MYSQLCPPCONN_SOURCES ${MYSQLCPPCONN_SOURCES} nativeapi/library_loader.h) ENDIF(NOT MYSQLCLIENT_STATIC_BINDING) # Used to create source filter in projects in VS SOURCE_GROUP(NativeApi nativeapi/.+) SOURCE_GROUP(API ../cppconn/.+) ENDIF(WIN32) ADD_LIBRARY(mysqlcppconn SHARED ${MYSQLCPPCONN_SOURCES}) ADD_LIBRARY(mysqlcppconn-static STATIC ${MYSQLCPPCONN_SOURCES}) SET(MYSQL_LIB_OBJECTS "${MYSQL_LIBRARIES}") IF(WIN32) INCLUDE_DIRECTORIES(${MYSQL_DIR}/include) IF(CMAKE_BUILD_TYPE STREQUAL "Debug") LINK_DIRECTORIES(${MYSQL_DIR}/lib/debug) ELSEIF(CMAKE_BUILD_TYPE STREQUAL "") LINK_DIRECTORIES(${MYSQL_DIR}/lib/opt) ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(MYSQLCPPCONN_SOURCES ${MYSQLCPPCONN_SOURCES} mysqlcppconn.def) ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") #Disables bunch of pretty useless warnings on win ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") ADD_LIBRARY(mysqlclient STATIC IMPORTED) SET_TARGET_PROPERTIES(mysqlclient PROPERTIES IMPORTED_LOCATION "${MYSQL_LIB}" ) IF(MYSQLCLIENT_STATIC_BINDING) SET(MY_TARGET_LINK_LIBRARIES_DYNAMIC mysqlclient ws2_32) ELSE(MYSQLCLIENT_STATIC_BINDING) SET(MY_TARGET_LINK_LIBRARIES_DYNAMIC ws2_32) ENDIF(MYSQLCLIENT_STATIC_BINDING) ELSEIF(NOT WIN32) IF(MYSQLCLIENT_STATIC_BINDING) SET(MY_TARGET_LINK_LIBRARIES_DYNAMIC ${MYSQL_LIBRARIES} ${MYSQL_LINK_FLAGS}) SET(MY_TARGET_LINK_LIBRARIES_STATIC ${MYSQL_LIBRARIES} ${MYSQL_LINK_FLAGS}) ELSE(MYSQLCLIENT_STATIC_BINDING) FOREACH(_lib ${MYSQL_LIBRARIES}) IF(NOT _lib MATCHES "libmysqlclient.*" AND NOT _lib MATCHES "mysqlclient.*") SET(MY_TARGET_LINK_LIBRARIES_DYNAMIC ${MY_TARGET_LINK_LIBRARIES_DYNAMIC} ${_lib}) SET(MY_TARGET_LINK_LIBRARIES_STATIC ${MY_TARGET_LINK_LIBRARIES_STATIC} ${_lib}) ENDIF(NOT _lib MATCHES "libmysqlclient.*" AND NOT _lib MATCHES "mysqlclient.*") ENDFOREACH(_lib ${MYSQL_LIBRARIES}) SET(MY_TARGET_LINK_LIBRARIES_DYNAMIC ${MY_TARGET_LINK_LIBRARIES_DYNAMIC} ${MYSQL_LINK_FLAGS} ${CMAKE_DL_LIBS}) SET(MY_TARGET_LINK_LIBRARIES_STATIC ${MY_TARGET_LINK_LIBRARIES_STATIC} ${MYSQL_LINK_FLAGS} ${CMAKE_DL_LIBS}) ENDIF(MYSQLCLIENT_STATIC_BINDING) IF(MYSQLCLIENT_STATIC_LINKING) SET(MYSQL_TEMP_STATIC_DIR ${CMAKE_CURRENT_BINARY_DIR}/.MYSQL_ARCHIVES) MAKE_DIRECTORY(${MYSQL_TEMP_STATIC_DIR}) EXECUTE_PROCESS( COMMAND ${CMAKE_AR} -x ${MYSQL_LIB} WORKING_DIRECTORY ${MYSQL_TEMP_STATIC_DIR} ) FILE(GLOB_RECURSE MYSQL_STATIC_OBJECTS "${MYSQL_TEMP_STATIC_DIR}/*.o") GET_FILENAME_COMPONENT(MYSQL_STATIC_ABS_TEMP_DIR ${MYSQL_TEMP_STATIC_DIR} ABSOLUTE) FOREACH(OBJ ${MYSQL_STATIC_OBJECTS}) FILE(RELATIVE_PATH OBJ ${CMAKE_CURRENT_BINARY_DIR} ${OBJ}) FILE(TO_NATIVE_PATH ${OBJ} OBJ) SET(MYSQL_STATIC_LIB_OBJECTS "${MYSQL_STATIC_LIB_OBJECTS} ${OBJ}") ENDFOREACH(OBJ ${MYSQL_STATIC_OBJECTS}) ENDIF(MYSQLCLIENT_STATIC_LINKING) SET(MYSQL_LIB_OBJECTS "${MYSQL_STATIC_LIB_OBJECTS}") ENDIF(WIN32) IF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(MY_GCOV_LINK_LIBRARIES gcov) ENDIF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) TARGET_LINK_LIBRARIES(mysqlcppconn ${MY_TARGET_LINK_LIBRARIES_DYNAMIC} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_EXTRA_LIBRARIES} ${MYSQLCPPCONN_ICU_LIBRARY}) # Need to find way it's defined for mysqlcppconn-static only #IF(WIN32) # ADD_DEFINITIONS("-DCPPCONN_PUBLIC_FUNC=\"\"") #ENDIF(WIN32) TARGET_LINK_LIBRARIES(mysqlcppconn-static ${MY_TARGET_LINK_LIBRARIES_STATIC} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_EXTRA_LIBRARIES} ${MYSQLCPPCONN_ICU_LIBRARY}) IF(CMAKE_SYSTEM_NAME MATCHES "SunOS") # We pass objects from our C client library in the # STATIC_LIBRARY_FLAGS property to create a # "libmysqlcppconn-static.a" with both the C client library and # Connector/C++ objects. # # In CMake 2.8.5 "SunPro-CXX.cmake" will define the creation of AR # archives to use "CC -xar ..." but leave out LINK_FLAGS where # the objects passed to STATIC_LIBRARY_FLAGS will end up. So no # C client library objects will be in the resulting library. # # We set it the archive creation line to the default "ar cr ..." SET(CMAKE_CXX_CREATE_STATIC_LIBRARY " cr ") ENDIF() SET_TARGET_PROPERTIES(mysqlcppconn-static PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}" COMPILE_DEFINITIONS CPPCONN_LIB_BUILD="" STATIC_LIBRARY_FLAGS "${MYSQL_LIB_OBJECTS}") SET_TARGET_PROPERTIES(mysqlcppconn PROPERTIES SOVERSION "${MYSQLCPPCONN_SOVERSION}" VERSION "${MYSQLCPPCONN_SOVERSION}.${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}" COMPILE_DEFINITIONS CPPCONN_SO_BUILD="" LINK_INTERFACE_LIBRARIES "") IF(WIN32) # SET_TARGET_PROPERTIES(mysqlcppconn PROPERTIES # LINK_FLAGS_DEBUG "/NODEFAULTLIB:LIBCMTD /NODEFAULTLIB:LIBCMT" # LINK_FLAGS_RELWITHDEBINFO "/NODEFAULTLIB:LIBCMT" # LINK_FLAGS_RELEASE "/NODEFAULTLIB:LIBCMT") # # SET_TARGET_PROPERTIES(mysqlcppconn-static PROPERTIES # STATIC_LIBRARY_FLAGS_DEBUG "/NODEFAULTLIB:LIBCMTD" # STATIC_LIBRARY_FLAGS_RELWITHDEBINFO "/NODEFAULTLIB:LIBCMT" # STATIC_LIBRARY_FLAGS_RELEASE "/NODEFAULTLIB:LIBCMT") # Changing CRT from dynamic to static IF(MYSQLCLIENT_STATIC_BINDING) INCLUDE(${CMAKE_SOURCE_DIR}/changeCrt.cmake) CHANGE_CRT("/MT") ENDIF() INSTALL(TARGETS mysqlcppconn mysqlcppconn-static RUNTIME DESTINATION lib ARCHIVE DESTINATION lib ) ELSE(WIN32) IF(ENABLE_BUILD_DYNAMIC OR ENABLE_BUILD_STATIC) IF(ENABLE_BUILD_DYNAMIC) INSTALL(TARGETS mysqlcppconn LIBRARY DESTINATION ${INSTALL_LIBDIR} ARCHIVE DESTINATION ${INSTALL_LIBDIR} ) ENDIF(ENABLE_BUILD_DYNAMIC) IF(ENABLE_BUILD_STATIC) INSTALL(TARGETS mysqlcppconn-static LIBRARY DESTINATION ${INSTALL_LIBDIR} ARCHIVE DESTINATION ${INSTALL_LIBDIR} ) ENDIF(ENABLE_BUILD_STATIC) ELSE(ENABLE_BUILD_DYNAMIC OR ENABLE_BUILD_STATIC) INSTALL(TARGETS mysqlcppconn mysqlcppconn-static LIBRARY DESTINATION ${INSTALL_LIBDIR} ARCHIVE DESTINATION ${INSTALL_LIBDIR} ) ENDIF(ENABLE_BUILD_DYNAMIC OR ENABLE_BUILD_STATIC) ENDIF(WIN32) # Install some MySQL specific headers SET(MYSQLCPPCONN_SPECIFIC_INSTALL_HEADERS mysql_connection.h mysql_driver.h mysql_error.h) INSTALL(FILES ${MYSQLCPPCONN_SPECIFIC_INSTALL_HEADERS} DESTINATION include) MESSAGE(STATUS "Configuring driver") mysql-connector-c++-1.1.7/driver/class_stats.php000644 015771 000012 00000004423 12645244436 022315 0ustar00pb2userwheel000000 000000 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ $prev_method = ""; $impl=$not_impl = 0; foreach(file("php://stdin") as $v) { if (!preg_match("#(.*?cpp):/\* +{{{ (.*?)::(.*?) +\-(I|U)\-#", $v, $matches)) { continue; } $class = $matches[2]; $method = $matches[3]; $implemented = ($matches[4] == "I"); if ($prev_method != $method) { $method_inc = 1; $prev_method = $method; } else { $method_inc++; } if (!isset($stats[$class][$method])) { $stats[$class][$method] = $implemented; } else { $stats[$class][$method."_".$method_inc] = $implemented; } } ksort($stats); foreach ($stats as $class => $methods) { printf("-----------\n"); ksort($methods); $local_impl=$local_notimpl=0; foreach ($methods as $method => $status) { if (1) { printf(" %s::%-55s %-30s\n", $class,$method, $status? "Implemented":"Not implemented"); } if ($status) { $impl++; $local_impl++; } else { $not_impl++; $local_notimpl++; } } printf("-----------\n%-30s Total=%-3d Implemented=%-3d Not Implemented=%-3d Impl=%-3d%%\n", $class,$local_impl+$local_notimpl, $local_impl, $local_notimpl, 100*$local_impl/($local_impl+$local_notimpl)); } printf("Total=%3d Implemented=%3d Not implemented=%3d\n", $not_impl+$impl, $impl, $not_impl); ?> mysql-connector-c++-1.1.7/driver/mysql_art_resultset.cpp000644 015771 000012 00000056456 12645244436 024127 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "mysql_util.h" #include "mysql_art_resultset.h" #include "mysql_art_rset_metadata.h" #include "mysql_debug.h" #include namespace sql { namespace mysql { /* {{{ MyVal::MyVal() -I- */ MyVal::MyVal(const sql::SQLString & s) : val_type(typeString) { val.str = new sql::SQLString(s); } /* }}} */ /* {{{ MyVal::MyVal() -I- */ MyVal::MyVal(const char * const s) : val_type(typeString) { // Init it clearly val.str = new sql::SQLString(s); } /* }}} */ /* {{{ MyVal::getString() -I- */ sql::SQLString MyVal::getString() { switch (val_type) { case typeString: return *val.str; case typeDouble: { char buf[31]; size_t len = snprintf(buf, sizeof(buf) - 1, "%14.14Lf", val.dval); return sql::SQLString(buf, len); } case typeInt: { char buf[20]; size_t len = snprintf(buf, sizeof(buf) - 1, "%lld", (long long int)val.lval); return sql::SQLString(buf, len); } case typeUInt: { char buf[20]; size_t len = snprintf(buf, sizeof(buf) - 1, "%llu", (long long unsigned int)val.ulval); return sql::SQLString(buf, len); } case typeBool: { char buf[3]; size_t len = snprintf(buf, sizeof(buf) - 1, "%d", val.bval); return sql::SQLString(buf, len); } case typePtr: return ""; } throw std::runtime_error("impossible"); } /* }}} */ /* {{{ MyVal::getDouble() -I- */ long double MyVal::getDouble() { switch (val_type) { case typeString: return sql::mysql::util::strtold(val.str->c_str(), NULL); case typePtr: return .0; case typeDouble: return val.dval; case typeInt: return static_cast(val.lval); case typeUInt: return static_cast(val.ulval); case typeBool: return val.bval ? 1.0 : 0.0; } throw std::runtime_error("impossible"); } /* }}} */ /* {{{ MyVal::getInt64() -I- */ int64_t MyVal::getInt64() { switch (val_type) { case typeString: return strtoll(val.str->c_str(), NULL, 10); case typePtr: return 0; case typeDouble: return static_cast(val.dval); case typeBool: return val.bval ? 1LL : 0LL; case typeInt: case typeUInt: return val.lval; } throw std::runtime_error("impossible"); } /* }}} */ /* {{{ MyVal::getUInt64() -I- */ uint64_t MyVal::getUInt64() { switch (val_type) { case typeString: return strtoull(val.str->c_str(), NULL, 10); case typePtr: return 0; case typeDouble: return static_cast(val.dval); case typeBool: return val.bval ? UL64(1) : UL64(0); case typeInt: case typeUInt: return val.ulval; } throw std::runtime_error("impossible"); } /* }}} */ /* {{{ MyVal::getBool() -I- */ bool MyVal::getBool() { static const double delta= 0.000001; switch (val_type) { case typeString: return getInt64() != 0; case typeDouble: return !(val.dval < delta && val.dval > -delta); case typeInt: case typeUInt: return val.lval != 0; case typeBool: return val.bval; case typePtr: return val.pval != NULL; } throw std::runtime_error("impossible"); } /* }}} */ /* {{{ MySQL_ArtResultSet::MySQL_ArtResultSet() -I- */ MySQL_ArtResultSet::MySQL_ArtResultSet(const StringList& fn, boost::shared_ptr< rset_t > &rs, boost::shared_ptr< MySQL_DebugLogger > & l) : num_fields(static_cast(fn.size())), rset(rs), current_record(rset->begin()), started(false), field_index_to_name_map(new sql::SQLString[num_fields]), num_rows(rset->size()), row_position(0), is_closed(false), logger(l) { CPP_ENTER("MySQL_ArtResultSet::MySQL_ArtResultSet"); CPP_INFO_FMT("metadata.size=%d resultset.size=%d", fn.size(), rset->size()); // field_index_to_name_map = new sql::SQLString[num_fields]; unsigned int idx = 0; for (StringList::const_iterator it = fn.begin(), e = fn.end(); it != e; ++it, ++idx) { boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(it->c_str(), 0)); field_name_to_index_map[sql::SQLString(upstring.get())] = idx; field_index_to_name_map[idx] = upstring.get(); } meta.reset(new MySQL_ArtResultSetMetaData(this, logger)); } /* }}} */ /* {{{ MySQL_ArtResultSet::~MySQL_ArtResultSet() -I- */ MySQL_ArtResultSet::~MySQL_ArtResultSet() { CPP_ENTER("MySQL_ArtResultSet::~MySQL_ArtResultSet"); if (!isClosed()) { close(); } } /* }}} */ /* {{{ MySQL_ArtResultSet::seek() -I- */ void MySQL_ArtResultSet::seek() { CPP_ENTER("MySQL_ArtResultSet::seek"); current_record = rset->begin(); /* i should be signed, or when row_position is 0 `i` will overflow */ for (long long i = row_position - 1; i > 0; --i) { ++current_record; } } /* }}} */ /* {{{ MySQL_ArtResultSet::isBeforeFirstOrAfterLast() -I- */ bool MySQL_ArtResultSet::isBeforeFirstOrAfterLast() const { CPP_ENTER("MySQL_ArtResultSet::isBeforeFirstOrAfterLast"); checkValid(); return (row_position == 0) || (row_position == num_rows + 1); } /* }}} */ /* {{{ MySQL_ArtResultSet::absolute() -I- */ bool MySQL_ArtResultSet::absolute(const int row) { CPP_ENTER("MySQL_ArtResultSet::absolute"); checkValid(); if (row > 0) { if (row > (int) num_rows) { afterLast(); } else { row_position = row; seek(); return true; } } else if (row < 0) { if ((-row) > (int) num_rows) { beforeFirst(); } else { row_position = num_rows - (-row) + 1; seek(); return true; } } else { /* According to the JDBC book, absolute(0) means before the result set */ beforeFirst(); } return (row_position > 0 && row_position < (num_rows + 1)); } /* }}} */ /* {{{ MySQL_ArtResultSet::afterLast() -I- */ void MySQL_ArtResultSet::afterLast() { CPP_ENTER("MySQL_ArtResultSet::afterLast"); checkValid(); row_position = num_rows + 1; seek(); } /* }}} */ /* {{{ MySQL_ArtResultSet::beforeFirst() -I- */ void MySQL_ArtResultSet::beforeFirst() { CPP_ENTER("MySQL_ArtResultSet::beforeFirst"); checkValid(); row_position = 0; seek(); } /* }}} */ /* {{{ MySQL_ArtResultSet::cancelRowUpdates() -U- */ void MySQL_ArtResultSet::cancelRowUpdates() { CPP_ENTER("MySQL_ArtResultSet::cancelRowUpdates"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::cancelRowUpdates()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::checkValid() -I- */ void MySQL_ArtResultSet::checkValid() const { CPP_ENTER("MySQL_ArtResultSet::checkValid"); CPP_INFO_FMT("this=%p", this); if (isClosed()) { throw sql::InvalidInstanceException("ResultSet has been closed"); } } /* }}} */ /* {{{ MySQL_ArtResultSet::clearWarnings() -U- */ void MySQL_ArtResultSet::clearWarnings() { CPP_ENTER("MySQL_ArtResultSet::clearWarnings"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::clearWarnings()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::close() -I- */ void MySQL_ArtResultSet::close() { CPP_ENTER("MySQL_ArtResultSet::close"); checkValid(); // delete [] field_index_to_name_map; is_closed = true; } /* }}} */ /* {{{ MySQL_ArtResultSet::findColumn() -I- */ uint32_t MySQL_ArtResultSet::findColumn(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::columnLabel"); checkValid(); boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(columnLabel.c_str(), 0)); FieldNameIndexMap::const_iterator iter = field_name_to_index_map.find(upstring.get()); if (iter == field_name_to_index_map.end()) { return 0; } /* findColumn returns 1-based indexes */ return iter->second + 1; } /* }}} */ /* {{{ MySQL_ArtResultSet::first() -I- */ bool MySQL_ArtResultSet::first() { CPP_ENTER("MySQL_ArtResultSet::first"); checkValid(); if (num_rows) { row_position = 1; seek(); } return num_rows != 0; } /* }}} */ /* {{{ MySQL_ArtResultSet::getBlob() -I- */ std::istream * MySQL_ArtResultSet::getBlob(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getBlob(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getString: can't fetch because not on result set"); } return new std::istringstream(getString(columnIndex)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getBlob() -I- */ std::istream * MySQL_ArtResultSet::getBlob(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getBlob(string)"); return new std::istringstream(getString(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getBoolean() -I- */ bool MySQL_ArtResultSet::getBoolean(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getBoolean(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getString: can't fetch because not on result set"); } return getInt(columnIndex) != 0; } /* }}} */ /* {{{ MySQL_ArtResultSet::getBoolean() -I- */ bool MySQL_ArtResultSet::getBoolean(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getBoolean(string)"); return getInt(columnLabel) != 0; } /* }}} */ /* {{{ MySQL_ArtResultSet::getConcurrency() -U- */ int MySQL_ArtResultSet::getConcurrency() { CPP_ENTER("MySQL_ArtResultSet::getConcurrency"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getConcurrency()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getCursorName() -U- */ SQLString MySQL_ArtResultSet::getCursorName() { CPP_ENTER("MySQL_ArtResultSet::getCursorName"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getCursorName()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getDouble() -I- */ long double MySQL_ArtResultSet::getDouble(uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getDouble(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getDouble: can't fetch because not on result set"); } if (columnIndex > num_fields || columnIndex == 0) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getDouble: invalid value of 'columnIndex'"); } return (*current_record)[columnIndex - 1].getDouble(); } /* }}} */ /* {{{ MySQL_ArtResultSet::getDouble() -I- */ long double MySQL_ArtResultSet::getDouble(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getDouble(string)"); return getDouble(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getFetchDirection() -U- */ int MySQL_ArtResultSet::getFetchDirection() { CPP_ENTER("MySQL_ArtResultSet::getFetchDirection"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getFetchDirection()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getFetchSize() -U- */ size_t MySQL_ArtResultSet::getFetchSize() { CPP_ENTER("MySQL_ArtResultSet::getFetchSize"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getFetchSize()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getHoldability() -U- */ int MySQL_ArtResultSet::getHoldability() { CPP_ENTER("MySQL_ArtResultSet::getHoldability"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getHoldability()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getInt() -I- */ int32_t MySQL_ArtResultSet::getInt(uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getInt(int)"); return static_cast(getInt64(columnIndex)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getInt() -I- */ int32_t MySQL_ArtResultSet::getInt(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getInt(string)"); return getInt(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getUInt() -I- */ uint32_t MySQL_ArtResultSet::getUInt(uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getUInt(int)"); return static_cast(getUInt64(columnIndex)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getUInt() -I- */ uint32_t MySQL_ArtResultSet::getUInt(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getUInt(string)"); return getUInt(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getInt64() -I- */ int64_t MySQL_ArtResultSet::getInt64(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getInt64(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getInt64: can't fetch because not on result set"); } if (columnIndex > num_fields || columnIndex == 0) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getInt64: invalid value of 'columnIndex'"); } return (*current_record)[columnIndex - 1].getInt64(); } /* }}} */ /* {{{ MySQL_ArtResultSet::getInt64() -I- */ int64_t MySQL_ArtResultSet::getInt64(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getInt64(string)"); return getInt64(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getUInt64() -I- */ uint64_t MySQL_ArtResultSet::getUInt64(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getUInt64(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getUInt64: can't fetch because not on result set"); } if (columnIndex > num_fields || columnIndex == 0) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getUInt64: invalid value of 'columnIndex'"); } return (*current_record)[columnIndex - 1].getUInt64(); } /* }}} */ /* {{{ MySQL_ArtResultSet::getUInt64() -I- */ uint64_t MySQL_ArtResultSet::getUInt64(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getUInt64(string)"); return getUInt64(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getMetaData() -I- */ sql::ResultSetMetaData * MySQL_ArtResultSet::getMetaData() const { CPP_ENTER("MySQL_ArtResultSet::getMetaData"); checkValid(); return meta.get(); } /* }}} */ /* {{{ MySQL_ArtResultSet::getRow() -I- */ size_t MySQL_ArtResultSet::getRow() const { CPP_ENTER("MySQL_ArtResultSet::getRow"); checkValid(); /* row_position is 0 based */ return static_cast (row_position); } /* }}} */ /* {{{ MySQL_ArtResultSet::getRowId() -U- */ sql::RowID * MySQL_ArtResultSet::getRowId(uint32_t) { CPP_ENTER("MySQL_ArtResultSet::getRowId"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getRowId()"); return NULL; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getRowId() -U- */ sql::RowID * MySQL_ArtResultSet::getRowId(const sql::SQLString &) { CPP_ENTER("MySQL_ArtResultSet::getRowId"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getRowId()"); return NULL; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::getStatement() -I- */ const Statement * MySQL_ArtResultSet::getStatement() const { CPP_ENTER("MySQL_ArtResultSet::getStatement"); checkValid(); return NULL; /* This is a constructed result set - no statement -> NULL */ } /* }}} */ /* {{{ MySQL_ArtResultSet::getString() -I- */ SQLString MySQL_ArtResultSet::getString(uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::getString(int)"); CPP_INFO_FMT("this=%p column=%u", this, columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getString: can't fetch because not on result set"); } if (columnIndex > num_fields || columnIndex == 0) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getString: invalid value of 'columnIndex'"); } return (*current_record)[columnIndex - 1].getString(); } /* }}} */ /* {{{ MySQL_ArtResultSet::getString() -I- */ SQLString MySQL_ArtResultSet::getString(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::getString(string)"); return getString(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::getType() -I- */ sql::ResultSet::enum_type MySQL_ArtResultSet::getType() const { CPP_ENTER("MySQL_ArtResultSet::getType"); checkValid(); return sql::ResultSet::TYPE_SCROLL_INSENSITIVE; } /* }}} */ /* {{{ MySQL_ArtResultSet::getWarnings() -U- */ void MySQL_ArtResultSet::getWarnings() { CPP_ENTER("MySQL_ArtResultSet::getWarnings"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::getWarnings()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::insertRow() -U- */ void MySQL_ArtResultSet::insertRow() { CPP_ENTER("MySQL_ArtResultSet::insertRow"); checkValid(); /* TODO - We don't support inserting anyway */ throw sql::MethodNotImplementedException("MySQL_ArtResultSet::insertRow()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::isAfterLast() -I- */ bool MySQL_ArtResultSet::isAfterLast() const { CPP_ENTER("MySQL_ArtResultSet::isAfterLast"); checkValid(); return (row_position == num_rows + 1); } /* }}} */ /* {{{ MySQL_ArtResultSet::isBeforeFirst() -I- */ bool MySQL_ArtResultSet::isBeforeFirst() const { CPP_ENTER("MySQL_ArtResultSet::isBeforeFirst"); checkValid(); return (row_position == 0); } /* }}} */ /* {{{ MySQL_ArtResultSet::isClosed() -I- */ bool MySQL_ArtResultSet::isClosed() const { CPP_ENTER("MySQL_ArtResultSet::isClosed"); return is_closed; } /* }}} */ /* {{{ MySQL_ArtResultSet::isFirst() -I- */ bool MySQL_ArtResultSet::isFirst() const { CPP_ENTER("MySQL_ArtResultSet::isFirst"); checkValid(); /* OR current_record == rs.begin() */ return (row_position == 1); } /* }}} */ /* {{{ MySQL_ArtResultSet::isLast() -I- */ bool MySQL_ArtResultSet::isLast() const { CPP_ENTER("MySQL_ArtResultSet::isLast"); checkValid(); /* OR current_record == rs.end() */ return (row_position == num_rows); } /* }}} */ /* {{{ MySQL_ArtResultSet::isNull() -I- */ bool MySQL_ArtResultSet::isNull(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ArtResultSet::isNull(int)"); checkValid(); if (columnIndex > num_fields || columnIndex == 0) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::isNull: invalid value of 'columnIndex'"); } /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ArtResultSet::getString: can't fetch because not on result set"); } return false; } /* }}} */ /* {{{ MySQL_ArtResultSet::isNull() -I- */ bool MySQL_ArtResultSet::isNull(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ArtResultSet::isNull(string)"); return isNull(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ArtResultSet::last() -I- */ bool MySQL_ArtResultSet::last() { CPP_ENTER("MySQL_ArtResultSet::last"); checkValid(); if (num_rows) { row_position = num_rows; seek(); } return num_rows != 0; } /* }}} */ /* {{{ MySQL_ArtResultSet::moveToCurrentRow() -U- */ void MySQL_ArtResultSet::moveToCurrentRow() { CPP_ENTER("MySQL_ArtResultSet::moveToCurrentRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::moveToCurrentRow()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::moveToInsertRow() -U- */ void MySQL_ArtResultSet::moveToInsertRow() { CPP_ENTER("MySQL_ArtResultSet::moveToInsertRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::moveToInsertRow()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::next() -I- */ bool MySQL_ArtResultSet::next() { CPP_ENTER("MySQL_ArtResultSet::next"); checkValid(); bool ret = false; if (isLast()) { afterLast(); } else if (row_position == 0) { first(); ret = true; } else if (row_position > 0 && row_position < num_rows) { ++current_record; ++row_position; ret = true; } CPP_INFO_FMT("row_position=%llu num_rows=%llu", row_position, num_rows); return ret; } /* }}} */ /* {{{ MySQL_ArtResultSet::previous() -I- */ bool MySQL_ArtResultSet::previous() { CPP_ENTER("MySQL_ArtResultSet::previous"); /* isBeforeFirst checks for validity */ if (isBeforeFirst()) { return false; } else if (isFirst()) { beforeFirst(); return false; } else if (row_position > 1) { --row_position; --current_record; return true; } throw sql::SQLException("Impossible"); } /* }}} */ /* {{{ MySQL_ArtResultSet::refreshRow() -U- */ void MySQL_ArtResultSet::refreshRow() { CPP_ENTER("MySQL_ArtResultSet::refreshRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::refreshRow()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::relative() -I- */ bool MySQL_ArtResultSet::relative(const int rows) { CPP_ENTER("MySQL_ArtResultSet::relative"); checkValid(); if (rows != 0) { if ((row_position + rows) > num_rows || (row_position + rows) < 1) { rows > 0? afterLast(): beforeFirst(); /* after last or before first */ } else { row_position += rows; seek(); } } return (row_position > 0 && row_position <= num_rows); } /* }}} */ /* {{{ MySQL_ArtResultSet::rowDeleted() -U- */ bool MySQL_ArtResultSet::rowDeleted() { CPP_ENTER("MySQL_ArtResultSet::rowDeleted"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::rowDeleted()"); return false; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::rowInserted() -U- */ bool MySQL_ArtResultSet::rowInserted() { CPP_ENTER("MySQL_ArtResultSet::rowInserted"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::rowInserted()"); return false; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::rowUpdated() -U- */ bool MySQL_ArtResultSet::rowUpdated() { CPP_ENTER("MySQL_ArtResultSet::rowUpdated"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ArtResultSet::rowUpdated()"); return false; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSet::rowsCount() -I- */ size_t MySQL_ArtResultSet::rowsCount() const { CPP_ENTER("MySQL_ArtResultSet::rowsCount"); checkValid(); return static_cast( num_rows ); } /* }}} */ /* {{{ MySQL_ArtResultSet::setFetchSize() -U- */ void MySQL_ArtResultSet::setFetchSize(size_t /* rows */) { CPP_ENTER("MySQL_ArtResultSet::setFetchSize"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::rowDeleted()"); } /* }}} */ /* {{{ MySQL_ArtResultSet::wasNull() -I- */ bool MySQL_ArtResultSet::wasNull() const { CPP_ENTER("MySQL_ArtResultSet::wasNull"); checkValid(); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::wasNull: can't fetch because not on result set"); } return false; } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_art_resultset.h000644 015771 000012 00000014061 12645244436 023556 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_ART_RESULTSET_H_ #define _MYSQL_ART_RESULTSET_H_ #include #include #include #include #include #include #include #include #include namespace sql { namespace mysql { class MySQL_DebugLogger; class MyVal { union { sql::SQLString * str; long double dval; int64_t lval; uint64_t ulval; bool bval; const void * pval; } val; enum { typeString, typeDouble, typeInt, typeUInt, typeBool, typePtr } val_type; void copy_obj(const MyVal & rhs) { val_type = rhs.val_type; if (val_type != typeString) { val = rhs.val; } else { val.str = new sql::SQLString(*rhs.val.str); } } public: MyVal(const sql::SQLString & s); MyVal(const char * const s); MyVal(long double d) : val_type(typeDouble) { val.dval = d; } MyVal(double d) : val_type(typeDouble) { val.dval = d; } MyVal(int64_t l) : val_type(typeInt) { val.lval = l; } MyVal(uint64_t ul) : val_type(typeUInt) { val.ulval = ul; } MyVal(bool b) : val_type(typeBool) { val.bval = b; } MyVal(void * p) : val_type(typePtr) { val.pval = p; } MyVal(const MyVal & rhs) { copy_obj(rhs); } const MyVal & operator=(const MyVal & rhs) { copy_obj(rhs); return *this; } ~MyVal() { if (val_type == typeString) { delete val.str; } } sql::SQLString getString(); long double getDouble(); int64_t getInt64(); uint64_t getUInt64(); bool getBool(); }; class MySQL_ArtResultSetMetaData; class MySQL_ArtResultSet : public sql::ResultSet { public: typedef std::list StringList; typedef std::vector< MyVal > row_t; typedef std::list< row_t > rset_t; MySQL_ArtResultSet(const StringList& fn, boost::shared_ptr< rset_t > &rset, boost::shared_ptr< MySQL_DebugLogger > & l); virtual ~MySQL_ArtResultSet(); bool absolute(int row); void afterLast(); void beforeFirst(); void cancelRowUpdates(); void clearWarnings(); void close(); uint32_t findColumn(const sql::SQLString& columnLabel) const; bool first(); std::istream * getBlob(uint32_t columnIndex) const; std::istream * getBlob(const sql::SQLString& columnLabel) const; bool getBoolean(uint32_t columnIndex) const; bool getBoolean(const sql::SQLString& columnLabel) const; int getConcurrency(); SQLString getCursorName(); // Get the given column as double long double getDouble(uint32_t columnIndex) const; long double getDouble(const sql::SQLString& columnLabel) const; int getFetchDirection(); size_t getFetchSize(); int getHoldability(); int32_t getInt(uint32_t columnIndex) const; int32_t getInt(const sql::SQLString& columnLabel) const; uint32_t getUInt(uint32_t columnIndex) const; uint32_t getUInt(const sql::SQLString& columnLabel) const; int64_t getInt64(uint32_t columnIndex) const; int64_t getInt64(const sql::SQLString& columnLabel) const; uint64_t getUInt64(uint32_t columnIndex) const; uint64_t getUInt64(const sql::SQLString& columnLabel) const; sql::ResultSetMetaData * getMetaData() const; size_t getRow() const; sql::RowID * getRowId(uint32_t columnIndex); sql::RowID * getRowId(const sql::SQLString & columnLabel); const sql::Statement * getStatement() const; // Get the given column as string SQLString getString(uint32_t columnIndex) const; SQLString getString(const sql::SQLString& columnLabel) const; sql::ResultSet::enum_type getType() const; void getWarnings(); void insertRow(); bool isAfterLast() const; bool isBeforeFirst() const; bool isClosed() const; bool isFirst() const; // Retrieves whether the cursor is on the last row of this sql::ResultSet object. bool isLast() const; bool isNull(uint32_t columnIndex) const; bool isNull(const sql::SQLString& columnLabel) const; bool last(); void moveToCurrentRow(); void moveToInsertRow(); bool next(); bool previous(); void refreshRow(); bool relative(int rows); bool rowDeleted(); bool rowInserted(); bool rowUpdated(); size_t rowsCount() const; void setFetchSize(size_t rows); bool wasNull() const; protected: void checkValid() const; bool isBeforeFirstOrAfterLast() const; void seek(); public: unsigned int num_fields; boost::shared_ptr< MySQL_ArtResultSet::rset_t > rset; rset_t::iterator current_record; bool started; typedef std::map< sql::SQLString, int > FieldNameIndexMap; FieldNameIndexMap field_name_to_index_map; boost::scoped_array< sql::SQLString > field_index_to_name_map; uint64_t num_rows; uint64_t row_position; /* 0 = before first row, 1 - first row, 'num_rows + 1' - after last row */ bool is_closed; boost::scoped_ptr< MySQL_ArtResultSetMetaData > meta; protected: boost::shared_ptr< MySQL_DebugLogger > logger; private: /* Prevent use of these */ MySQL_ArtResultSet(const MySQL_ArtResultSet &); void operator=(MySQL_ArtResultSet &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_ART_RESULTSET_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_art_rset_metadata.cpp000644 015771 000012 00000023132 12645244436 024673 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "mysql_util.h" /* mysql_art_rset_metadata.h must be included after mysql_art_resultset.h */ #include "mysql_art_resultset.h" #include "mysql_art_rset_metadata.h" #include "mysql_debug.h" #include #include namespace sql { namespace mysql { /* {{{ MySQL_ArtResultSetMetaData::MySQL_ArtResultSetMetaData() -I- */ MySQL_ArtResultSetMetaData::MySQL_ArtResultSetMetaData(const MySQL_ArtResultSet * p, boost::shared_ptr< MySQL_DebugLogger > & l) : parent(p), logger(l), num_fields(parent->num_fields) { } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::~MySQL_ArtResultSetMetaData() -I- */ MySQL_ArtResultSetMetaData::~MySQL_ArtResultSetMetaData() { CPP_ENTER("MySQL_ArtResultSetMetaData::~MySQL_ArtResultSetMetaData"); CPP_INFO_FMT("this=%p", this); } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::checkColumnIndex -I- */ void MySQL_ArtResultSetMetaData::checkColumnIndex(unsigned int columnIndex) const { if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("Invalid value for columnIndex"); } } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getCatalogName() -I- */ SQLString MySQL_ArtResultSetMetaData::getCatalogName(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getCatalogName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return ""; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnCount() -I- */ unsigned int MySQL_ArtResultSetMetaData::getColumnCount() { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnCount"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("column_count=%d", num_fields); return num_fields; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnDisplaySize() -U- */ unsigned int MySQL_ArtResultSetMetaData::getColumnDisplaySize(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnDisplaySize"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); throw sql::MethodNotImplementedException("MySQL_ArtResultSetMetaData::getColumnDisplaySize()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnLabel() -I- */ SQLString MySQL_ArtResultSetMetaData::getColumnLabel(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnLabel"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return parent->field_index_to_name_map[columnIndex - 1]; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnName() -I- */ SQLString MySQL_ArtResultSetMetaData::getColumnName(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return parent->field_index_to_name_map[columnIndex - 1]; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnType() -I- */ int MySQL_ArtResultSetMetaData::getColumnType(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnType"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return sql::DataType::VARCHAR; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnTypeName() -I- */ SQLString MySQL_ArtResultSetMetaData::getColumnTypeName(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnTypeName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return "VARCHAR"; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnCharset() -I- */ SQLString MySQL_ArtResultSetMetaData::getColumnCharset(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnCharset"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return ""; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getColumnCollation() -I- */ SQLString MySQL_ArtResultSetMetaData::getColumnCollation(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getColumnCollation"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return ""; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getPrecision() -U- */ unsigned int MySQL_ArtResultSetMetaData::getPrecision(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getPrecision"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); throw sql::MethodNotImplementedException("MySQL_ArtResultSetMetaData::getPrecision()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getScale() -U- */ unsigned int MySQL_ArtResultSetMetaData::getScale(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getScale"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); throw sql::MethodNotImplementedException("MySQL_ArtResultSetMetaData::getScale()"); return 0; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getSchemaName() -I- */ SQLString MySQL_ArtResultSetMetaData::getSchemaName(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getSchemaName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return ""; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::getTableName() -I- */ SQLString MySQL_ArtResultSetMetaData::getTableName(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::getTableName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return ""; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isAutoIncrement() -I- */ bool MySQL_ArtResultSetMetaData::isAutoIncrement(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isAutoIncrement"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isCaseSensitive() -I- */ bool MySQL_ArtResultSetMetaData::isCaseSensitive(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isCaseSensitive"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return "true"; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isCurrency() -I- */ bool MySQL_ArtResultSetMetaData::isCurrency(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isCurrency"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isDefinitelyWritable() -I- */ bool MySQL_ArtResultSetMetaData::isDefinitelyWritable(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isDefinitelyWritable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return isWritable(columnIndex); } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isNullable() -I- */ int MySQL_ArtResultSetMetaData::isNullable(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isNullable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isNumeric() -I- */ bool MySQL_ArtResultSetMetaData::isNumeric(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isNumeric"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isReadOnly() -I- */ bool MySQL_ArtResultSetMetaData::isReadOnly(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isReadOnly"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); /* We consider we connect to >= 40100 - else, we can't say */ return true; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isSearchable() -I- */ bool MySQL_ArtResultSetMetaData::isSearchable(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isSearchable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return true; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isSigned() -I- */ bool MySQL_ArtResultSetMetaData::isSigned(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isSigned"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isWritable() -I- */ bool MySQL_ArtResultSetMetaData::isWritable(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isWritable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return !isReadOnly(columnIndex); } /* }}} */ /* {{{ MySQL_ArtResultSetMetaData::isZerofill() -I- */ bool MySQL_ArtResultSetMetaData::isZerofill(unsigned int columnIndex) { CPP_ENTER("MySQL_ArtResultSetMetaData::isZerofill"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_art_rset_metadata.h000644 015771 000012 00000006324 12645244436 024344 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_ART_RSET_METADATA_H_ #define _MYSQL_ART_RSET_METADATA_H_ #include #include #include namespace sql { namespace mysql { class MySQL_DebugLogger; class MySQL_ArtResultSetMetaData : public sql::ResultSetMetaData { const MySQL_ArtResultSet * parent; boost::shared_ptr< MySQL_DebugLogger > logger; unsigned int num_fields; public: MySQL_ArtResultSetMetaData(const MySQL_ArtResultSet * p, boost::shared_ptr< MySQL_DebugLogger > & l); virtual ~MySQL_ArtResultSetMetaData(); SQLString getCatalogName(unsigned int columnIndex); unsigned int getColumnCount(); unsigned int getColumnDisplaySize(unsigned int columnIndex); SQLString getColumnLabel(unsigned int columnIndex); SQLString getColumnName(unsigned int columnIndex); int getColumnType(unsigned int columnIndex); SQLString getColumnTypeName(unsigned int columnIndex); SQLString getColumnCharset(unsigned int columnIndex); SQLString getColumnCollation(unsigned int columnIndex); unsigned int getPrecision(unsigned int columnIndex); unsigned int getScale(unsigned int columnIndex); SQLString getSchemaName(unsigned int columnIndex); SQLString getTableName(unsigned int columnIndex); bool isAutoIncrement(unsigned int columnIndex); bool isCaseSensitive(unsigned int columnIndex); bool isCurrency(unsigned int columnIndex); bool isDefinitelyWritable(unsigned int columnIndex); int isNullable(unsigned int columnIndex); bool isNumeric(unsigned int columnIndex); bool isReadOnly(unsigned int columnIndex); bool isSearchable(unsigned int columnIndex); bool isSigned(unsigned int columnIndex); bool isWritable(unsigned int columnIndex); bool isZerofill(unsigned int columnIndex); protected: void checkColumnIndex(unsigned int columnIndex) const; private: /* Prevent use of these */ MySQL_ArtResultSetMetaData(const MySQL_ArtResultSetMetaData &); void operator=(MySQL_ArtResultSetMetaData &); }; } /* namespace mysql */ } /* namespace sql */ #endif /* _MYSQL_ART_RSET_METADATA_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_connection.cpp000644 015771 000012 00000147321 12645244436 023356 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include "nativeapi/native_connection_wrapper.h" #include "nativeapi/native_statement_wrapper.h" #include "mysql_connection_options.h" #include "mysql_util.h" #include "mysql_uri.h" #include "mysql_error.h" /* * _WIN32 is defined by 64bit compiler too * (see http://msdn.microsoft.com/en-us/library/aa489554.aspx) * So no need to check for _WIN64 too */ #ifdef _WIN32 /* MySQL 5.1 might have defined it before in include/config-win.h */ #ifdef strncasecmp #undef strncasecmp #endif #define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n) #else #include #endif #include "mysql_connection.h" #include "mysql_connection_data.h" #include "mysql_prepared_statement.h" #include "mysql_statement.h" #include "mysql_metadata.h" #include "mysql_resultset.h" #include "mysql_warning.h" #include "mysql_debug.h" #ifndef ER_MUST_CHANGE_PASSWORD_LOGIN # define ER_MUST_CHANGE_PASSWORD_LOGIN 1820 #endif namespace sql { namespace mysql { /* {{{ MySQL_Savepoint::MySQL_Savepoint() -I- */ MySQL_Savepoint::MySQL_Savepoint(const sql::SQLString &savepoint): name(savepoint) { } /* }}} */ /* {{{ MySQL_Savepoint::getSavepointId() -I- */ int MySQL_Savepoint::getSavepointId() { throw sql::InvalidArgumentException("Only named savepoints are supported."); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Savepoint::getSavepointName() -I- */ sql::SQLString MySQL_Savepoint::getSavepointName() { return name; } /* }}} */ /* {{{ MySQL_Connection::createServiceStmt() */ MySQL_Statement * MySQL_Connection::createServiceStmt() { /* We need to have it storing results, not using */ return new MySQL_Statement(this, proxy, sql::ResultSet::TYPE_SCROLL_INSENSITIVE, intern->logger); } /* {{{ MySQL_Connection::MySQL_Connection() -I- */ MySQL_Connection::MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper& _proxy, const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) : driver (_driver), proxy (&_proxy), intern (NULL) { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"] = hostName; connection_properties["userName"] = userName; connection_properties["password"] = password; boost::shared_ptr< MySQL_DebugLogger > tmp_logger(new MySQL_DebugLogger()); intern.reset(new MySQL_ConnectionData(tmp_logger)); service.reset(createServiceStmt()); init(connection_properties); } /* }}} */ /* {{{ MySQL_Connection::MySQL_Connection() -I- */ MySQL_Connection::MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper& _proxy, sql::ConnectOptionsMap & properties) : driver(_driver), proxy(&_proxy), intern(NULL) { boost::shared_ptr tmp_logger(new MySQL_DebugLogger()); intern.reset(new MySQL_ConnectionData(tmp_logger)); service.reset(createServiceStmt()); init(properties); } /* }}} */ /* {{{ MySQL_Connection::~MySQL_Connection() -I- */ MySQL_Connection::~MySQL_Connection() { /* We need this outter block, because the on-stack object created by CPP_ENTER references `intern->logger`. And if there is no block the on-stack object will be destructed after `delete intern->logger` leading to a faulty memory access. */ { CPP_ENTER_WL(intern->logger, "MySQL_Connection::~MySQL_Connection"); } } /* }}} */ /* A struct to keep const reference data for mapping string value to int */ struct String2IntMap { const char * key; int value; bool skip_list; }; static const String2IntMap flagsOptions[]= { {"CLIENT_COMPRESS", CLIENT_COMPRESS, false}, {"CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, false}, {"CLIENT_IGNORE_SIGPIPE", CLIENT_IGNORE_SIGPIPE, false}, {"CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, false}, {"CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, false}, {"CLIENT_LOCAL_FILES", CLIENT_LOCAL_FILES, false}, {"CLIENT_MULTI_STATEMENTS", CLIENT_MULTI_STATEMENTS, false}, {"CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, false} }; /* {{{ readFlag(::sql::SQLString, int= 0) -I- */ /** Check if connection option pointed by map iterator defines a connection flag */ static bool read_connection_flag(ConnectOptionsMap::const_iterator &cit, int &flags) { const bool * value; for (size_t i = 0; i < sizeof(flagsOptions)/sizeof(String2IntMap); ++i) { if (!cit->first.compare(flagsOptions[i].key)) { try { value = (cit->second).get< bool >(); } catch (sql::InvalidArgumentException& e) { std::ostringstream msg; msg << "Wrong type passed for " << flagsOptions[i].key << " expected bool"; throw sql::InvalidArgumentException(msg.str()); } if (!value) { sql::SQLString err("No bool value passed for "); err.append(flagsOptions[i].key); throw sql::InvalidArgumentException(err); } if (*value) { flags |= flagsOptions[i].value; } return true; } } return false; } /* }}} */ /* Array for mapping of boolean connection options to mysql_options call */ static const String2IntMap booleanOptions[]= { {"OPT_REPORT_DATA_TRUNCATION", MYSQL_REPORT_DATA_TRUNCATION, false}, {"OPT_ENABLE_CLEARTEXT_PLUGIN", MYSQL_ENABLE_CLEARTEXT_PLUGIN, false}, {"sslVerify", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, false}, {"OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, true}, {"OPT_CONNECT_ATTR_RESET", MYSQL_OPT_CONNECT_ATTR_RESET, true}, {"OPT_RECONNECT", MYSQL_OPT_RECONNECT, true}, {"sslEnforce", MYSQL_OPT_SSL_ENFORCE, false} }; /* Array for mapping of integer connection options to mysql_options call */ static const String2IntMap intOptions[]= { {"OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, false}, {"OPT_READ_TIMEOUT", MYSQL_OPT_READ_TIMEOUT, false}, {"OPT_WRITE_TIMEOUT", MYSQL_OPT_WRITE_TIMEOUT, false}, {"OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, false} }; /* Array for mapping of string connection options to mysql_options call */ static const String2IntMap stringOptions[]= { {"preInit", MYSQL_INIT_COMMAND, false}, {"sslKey", MYSQL_OPT_SSL_KEY, true}, {"sslCert", MYSQL_OPT_SSL_CERT, true}, {"sslCA", MYSQL_OPT_SSL_CA, true}, {"sslCAPath", MYSQL_OPT_SSL_CAPATH, true}, {"sslCipher", MYSQL_OPT_SSL_CIPHER, true}, {"sslCRL", MYSQL_OPT_SSL_CRL, false}, {"sslCRLPath", MYSQL_OPT_SSL_CRLPATH, false}, {"rsaKey", MYSQL_SERVER_PUBLIC_KEY, false}, {"charsetDir", MYSQL_SET_CHARSET_DIR, false}, {"pluginDir", MYSQL_PLUGIN_DIR, false}, {"defaultAuth", MYSQL_DEFAULT_AUTH, false}, {"OPT_CONNECT_ATTR_DELETE", MYSQL_OPT_CONNECT_ATTR_DELETE, false}, {"readDefaultGroup", MYSQL_READ_DEFAULT_GROUP, false}, {"readDefaultFile", MYSQL_READ_DEFAULT_FILE, false}, {"OPT_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, true} }; template bool process_connection_option(ConnectOptionsMap::const_iterator &option, const String2IntMap options_map[], size_t map_size, boost::shared_ptr< NativeAPI::NativeConnectionWrapper > &proxy) { const T * value; for (size_t i = 0; i < map_size; ++i) { if (!option->first.compare(options_map[i].key) && !options_map[i].skip_list) { try { value = (option->second).get(); } catch (sql::InvalidArgumentException& e) { std::ostringstream msg; msg << "Wrong type passed for " << options_map[i].key << " expected " << typeid(value).name(); throw sql::InvalidArgumentException(msg.str()); } if (!value) { sql::SQLString err("Option "); err.append(option->first).append(" is not of expected type"); throw sql::InvalidArgumentException(err); } try { proxy->options(static_cast(options_map[i].value), *value); } catch (sql::InvalidArgumentException& e) { std::string errorOption(options_map[i].key); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } return true; } } return false; } bool get_connection_option(const sql::SQLString optionName, void *optionValue, const String2IntMap options_map[], size_t map_size, boost::shared_ptr< NativeAPI::NativeConnectionWrapper > &proxy) { for (size_t i = 0; i < map_size; ++i) { if (!optionName.compare(options_map[i].key)) { try { proxy->get_option(static_cast(options_map[i].value), optionValue); } catch (sql::InvalidArgumentException& e) { std::string errorOption(options_map[i].key); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } return true; } } return false; } /* We support : - hostName - userName - password - port - socket - pipe - characterSetResults - schema - sslKey - sslCert - sslCA - sslCAPath - sslCipher - sslEnforce - sslVerify - sslCRL - sslCRLPath - useLegacyAuth - defaultStatementResultType - defaultPreparedStatementResultType - CLIENT_COMPRESS - CLIENT_FOUND_ROWS - CLIENT_IGNORE_SIGPIPE - CLIENT_IGNORE_SPACE - CLIENT_INTERACTIVE - CLIENT_LOCAL_FILES - CLIENT_MULTI_RESULTS - CLIENT_MULTI_STATEMENTS - CLIENT_NO_SCHEMA - CLIENT_COMPRESS - OPT_CONNECT_TIMEOUT - OPT_NAMED_PIPE - OPT_READ_TIMEOUT - OPT_WRITE_TIMEOUT - OPT_RECONNECT - OPT_CHARSET_NAME - OPT_REPORT_DATA_TRUNCATION - OPT_CAN_HANDLE_EXPIRED_PASSWORDS - OPT_ENABLE_CLEARTEXT_PLUGIN - OPT_LOCAL_INFILE - OPT_CONNECT_ATTR_ADD - OPT_CONNECT_ATTR_DELETE - OPT_CONNECT_ATTR_RESET - preInit - postInit - rsaKey - charsetDir - pluginDir - defaultAuth - readDefaultGroup - readDefaultFile To add new connection option that maps to a myql_options call, only add its mapping to sql::mysql::MySQL_Connection_Options value to one of arrays above - booleanOptions, intOptions, stringOptions. You might need to add new member to the sql::mysql::MySQL_Connection_Options enum */ /* {{{ MySQL_Connection::init() -I- */ void MySQL_Connection::init(ConnectOptionsMap & properties) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::init"); intern->is_valid = true; MySQL_Uri uri; sql::SQLString userName; sql::SQLString password; sql::SQLString defaultCharset("utf8"); sql::SQLString characterSetResults("utf8"); sql::SQLString sslKey, sslCert, sslCA, sslCAPath, sslCipher, postInit; bool ssl_used = false; int flags = CLIENT_MULTI_RESULTS; const int * p_i; const bool * p_b; const sql::SQLString * p_s; bool opt_reconnect = false; int client_exp_pwd = false; bool secure_auth= true; /* Values set in properties individually should have priority over those we restore from Uri */ sql::ConnectOptionsMap::const_iterator it = properties.find("hostName"); if (it != properties.end()) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for userName expected sql::SQLString"); } if (p_s) { /* Parsing uri prior to processing all parameters, so indivudually specified parameters precede over those in the uri */ parseUri(*p_s, uri); } else { throw sql::InvalidArgumentException("No string value passed for hostName"); } } #define PROCESS_CONN_OPTION(option_type, options_map) process_connection_option< option_type >(it, options_map, sizeof(options_map)/sizeof(String2IntMap), proxy) for (it = properties.begin(); it != properties.end(); ++it) { if (!it->first.compare("userName")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for userName expected sql::SQLString"); } if (p_s) { userName = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for userName"); } } else if (!it->first.compare("password")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for password expected sql::SQLString"); } if (p_s) { password = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for password"); } } else if (!it->first.compare("port")) { try { p_i = (it->second).get< int >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for port expected int"); } if (p_i) { uri.setPort(static_cast(*p_i)); } else { throw sql::InvalidArgumentException("No long long value passed for port"); } } else if (!it->first.compare("socket")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for socket expected sql::SQLString"); } if (p_s) { uri.setSocket(*p_s); } else { throw sql::InvalidArgumentException("No string value passed for socket"); } } else if (!it->first.compare("pipe")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for pipe expected sql::SQLString"); } if (p_s) { uri.setPipe(*p_s); } else { throw sql::InvalidArgumentException("No string value passed for pipe"); } } else if (!it->first.compare("schema")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for schema expected sql::SQLString"); } if (p_s) { uri.setSchema(*p_s); } else { throw sql::InvalidArgumentException("No string value passed for schema"); } } else if (!it->first.compare("characterSetResults")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for characterSetResults expected sql::SQLString"); } if (p_s) { characterSetResults = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for characterSetResults"); } } else if (!it->first.compare("sslKey")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for sslKey expected sql::SQLString"); } if (p_s) { sslKey = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for sslKey"); } ssl_used = true; } else if (!it->first.compare("sslCert")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for sslCert expected sql::SQLString"); } if (p_s) { sslCert = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for sslCert"); } ssl_used = true; } else if (!it->first.compare("sslCA")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for sslCA expected sql::SQLString"); } if (p_s) { sslCA = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for sslCA"); } ssl_used = true; } else if (!it->first.compare("sslCAPath")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for sslCAPath expected sql::SQLString"); } if (p_s) { sslCAPath = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for sslCAPath"); } ssl_used = true; } else if (!it->first.compare("sslCipher")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for sslCipher expected sql::SQLString"); } if (p_s) { sslCipher = *p_s; } else { throw sql::InvalidArgumentException("No string value passed for sslCipher"); } ssl_used = true; } else if (!it->first.compare("defaultStatementResultType")) { try { p_i = (it->second).get< int >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for defaultStatementResultType expected sql::SQLString"); } if (!p_i) { throw sql::InvalidArgumentException("No long long value passed for defaultStatementResultType"); } do { if (static_cast< int >(sql::ResultSet::TYPE_FORWARD_ONLY) == *p_i) break; if (static_cast< int >(sql::ResultSet::TYPE_SCROLL_INSENSITIVE) == *p_i) break; if (static_cast< int >(sql::ResultSet::TYPE_SCROLL_SENSITIVE) == *p_i) { std::ostringstream msg; msg << "Invalid value " << *p_i << " for option defaultStatementResultType. TYPE_SCROLL_SENSITIVE is not supported"; throw sql::InvalidArgumentException(msg.str()); } std::ostringstream msg; msg << "Invalid value (" << *p_i << " for option defaultStatementResultType"; throw sql::InvalidArgumentException(msg.str()); } while (0); intern->defaultStatementResultType = static_cast< sql::ResultSet::enum_type >(*p_i); /* The connector is not ready for unbuffered as we need to refetch */ } else if (!it->first.compare("defaultPreparedStatementResultType")) { #if WE_SUPPORT_USE_RESULT_WITH_PS try { p_i = (it->second).get< int >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for defaultPreparedStatementResultType expected sql::SQLString"); } if (!(p_i)) { throw sql::InvalidArgumentException("No long long value passed for defaultPreparedStatementResultType"); } do { if (static_cast< int >(sql::ResultSet::TYPE_FORWARD_ONLY) == *p_i) break; if (static_cast< int >(sql::ResultSet::TYPE_SCROLL_INSENSITIVE) == *p_i) break; if (static_cast< int >(sql::ResultSet::TYPE_SCROLL_SENSITIVE) == *p_i) { std::ostringstream msg; msg << "Invalid value " << *p_i << " for option defaultPreparedStatementResultType. TYPE_SCROLL_SENSITIVE is not supported"; throw sql::InvalidArgumentException(msg.str()); } std::ostringstream msg; msg << "Invalid value (" << *p_i << " for option defaultPreparedStatementResultType"; throw sql::InvalidArgumentException(msg.str()); } while (0); intern->defaultPreparedStatementResultType = static_cast< sql::ResultSet::enum_type >(*p_i); #else throw SQLException("defaultPreparedStatementResultType parameter still not implemented"); #endif } else if (!it->first.compare("metadataUseInfoSchema")) { try { p_b = (it->second).get(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for metadataUseInfoSchema expected bool"); } if (p_b) { intern->metadata_use_info_schema = *p_b; } else { throw sql::InvalidArgumentException("No bool value passed for metadataUseInfoSchema"); } } else if (!it->first.compare("OPT_RECONNECT")) { try { p_b = (it->second).get(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for OPT_RECONNECT expected bool"); } if (!(p_b)) { throw sql::InvalidArgumentException("No bool value passed for OPT_RECONNECT"); } opt_reconnect = true; intern->reconnect= *p_b; } else if (!it->first.compare("OPT_CHARSET_NAME")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for OPT_CHARSET_NAME expected sql::SQLString"); } if (!p_s) { throw sql::InvalidArgumentException("No SQLString value passed for OPT_CHARSET_NAME"); } defaultCharset = *p_s; } else if (!it->first.compare("OPT_NAMED_PIPE")) { /* Not sure it is really needed */ uri.setProtocol(NativeAPI::PROTOCOL_PIPE); } else if (!it->first.compare("OPT_CAN_HANDLE_EXPIRED_PASSWORDS")) { try { p_b = (it->second).get(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for OPT_CAN_HANDLE_EXPIRED_PASSWORDS expected bool"); } if (!(p_b)) { throw sql::InvalidArgumentException("No bool value passed for " "OPT_CAN_HANDLE_EXPIRED_PASSWORDS"); } try { client_exp_pwd= proxy->options(MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, (const char*)p_b); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } } else if (!it->first.compare("postInit")) { try { p_s = (it->second).get< sql::SQLString >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for postInit expected sql::SQLString"); } if (p_s) { postInit= *p_s; } else { throw sql::InvalidArgumentException("No string value passed for postInit"); } } else if (!it->first.compare("useLegacyAuth")) { try { p_b = (it->second).get< bool >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for useLegacyAuth expected sql::SQLString"); } if (p_b) { secure_auth= !*p_b; } else { throw sql::InvalidArgumentException("No bool value passed for useLegacyAuth"); } } else if (!it->first.compare("OPT_CONNECT_ATTR_ADD")) { const std::map< sql::SQLString, sql::SQLString > *conVal; try { conVal= (it->second).get< std::map< sql::SQLString, sql::SQLString > >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for OPT_CONNECT_ATTR_ADD expected std::map< sql::SQLString, sql::SQLString >"); } std::map< sql::SQLString, sql::SQLString >::const_iterator conn_attr_it; for (conn_attr_it = conVal->begin(); conn_attr_it != conVal->end(); conn_attr_it++) { try { proxy->options(MYSQL_OPT_CONNECT_ATTR_ADD, conn_attr_it->first, conn_attr_it->second); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_CONNECT_ATTR_ADD"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } } } else if (!it->first.compare("OPT_CONNECT_ATTR_DELETE")) { const std::list< sql::SQLString > *conVal; try { conVal= (it->second).get< std::list< sql::SQLString > >(); } catch (sql::InvalidArgumentException& e) { throw sql::InvalidArgumentException("Wrong type passed for OPT_CONNECT_ATTR_DELETE expected std::list< sql::SQLString >"); } std::list< sql::SQLString >::const_iterator conn_attr_it; for (conn_attr_it = conVal->begin(); conn_attr_it != conVal->end(); conn_attr_it++) { try { proxy->options(MYSQL_OPT_CONNECT_ATTR_DELETE, *conn_attr_it); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_CONNECT_ATTR_DELETE"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } } } else if (!it->first.compare("OPT_CONNECT_ATTR_RESET")) { proxy->options(MYSQL_OPT_CONNECT_ATTR_RESET, 0); /* If you need to add new integer connection option that should result in calling mysql_optiong - add its mapping to the intOptions array */ } else if (PROCESS_CONN_OPTION(int, intOptions)) { // Nothing to do here /* For boolean coonection option - add mapping to booleanOptions array */ } else if (PROCESS_CONN_OPTION(bool, booleanOptions)) { // Nothing to do here /* For string coonection option - add mapping to stringOptions array */ } else if (PROCESS_CONN_OPTION(sql::SQLString, stringOptions)) { // Nothing to do here } else if (read_connection_flag(it, flags)) { // Nothing to do here } else { // TODO: Shouldn't we really create a warning here? as soon as we are able to // create a warning } } /* End of cycle on connection options map */ #undef PROCESS_CONNSTR_OPTION /* libmysql shouldn't think it is too smart */ if (tcpProtocol(uri) && !uri.Host().compare(util::LOCALHOST)) { uri.setHost("127.0.0.1"); } // Throwing in case of wrong protocol #ifdef _WIN32 if (uri.Protocol() == NativeAPI::PROTOCOL_SOCKET) { throw sql::InvalidArgumentException("Invalid for this platform protocol requested(MYSQL_PROTOCOL_SOCKET)"); } #else if (uri.Protocol() == NativeAPI::PROTOCOL_PIPE) { throw sql::InvalidArgumentException("Invalid for this platform protocol requested(MYSQL_PROTOCOL_PIPE)"); } #endif proxy->use_protocol(uri.Protocol()); try { proxy->options(MYSQL_SECURE_AUTH, &secure_auth); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_SECURE_AUTH"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } try { proxy->options(MYSQL_SET_CHARSET_NAME, defaultCharset.c_str()); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_SET_CHARSET_NAME"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } if (ssl_used) { /* According to the docs, always returns 0 */ proxy->ssl_set(sslKey.c_str(), sslCert.c_str(), sslCA.c_str(), sslCAPath.c_str(), sslCipher.c_str()); } CPP_INFO_FMT("hostName=%s", uri.Host().c_str()); CPP_INFO_FMT("user=%s", userName.c_str()); CPP_INFO_FMT("port=%d", uri.Port()); CPP_INFO_FMT("schema=%s", uri.Schema().c_str()); CPP_INFO_FMT("socket/pipe=%s", uri.SocketOrPipe().c_str()); if (!proxy->connect(uri.Host(), userName, password, uri.Schema() /* schema */, uri.Port(), uri.SocketOrPipe() /*socket or named pipe */, flags)) { CPP_ERR_FMT("Couldn't connect : %d", proxy->errNo()); CPP_ERR_FMT("Couldn't connect : (%s)", proxy->sqlstate().c_str()); CPP_ERR_FMT("Couldn't connect : %s", proxy->error().c_str()); CPP_ERR_FMT("Couldn't connect : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); /* If error is "Password has expired" and application supports it while mysql client lib does not */ std::string error_message; int native_error= proxy->errNo(); if (native_error == ER_MUST_CHANGE_PASSWORD_LOGIN && client_exp_pwd) { native_error= deCL_CANT_HANDLE_EXP_PWD; error_message= "Your password has expired, but your instance of" " Connector/C++ is not linked against mysql client library that" " allows to reset it. To resolve this you either need to change" " the password with mysql client that is capable to do that," " or rebuild your instance of Connector/C++ against mysql client" " library that supports resetting of an expired password."; } else { error_message= proxy->error(); } sql::SQLException e(error_message, proxy->sqlstate(), native_error); proxy.reset(); throw e; } if (opt_reconnect) { try { proxy->options(MYSQL_OPT_RECONNECT, (const char *) &intern->reconnect); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_RECONNECT"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } } setAutoCommit(true); setTransactionIsolation(sql::TRANSACTION_REPEATABLE_READ); // Different Values means we have to set different result set encoding if (characterSetResults.compare(defaultCharset)) { setSessionVariable("character_set_results", characterSetResults.length() ? characterSetResults:"NULL"); } intern->meta.reset(new MySQL_ConnectionMetaData(service.get(), proxy, intern->logger)); if (postInit.length() > 0) { service->executeUpdate(postInit); } } /* }}} */ /* {{{ MySQL_Connection::clearWarnings() -I- */ void MySQL_Connection::clearWarnings() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::clearWarnings"); intern->warnings.reset(); } /* }}} */ /* {{{ MySQL_Connection::checkClosed() -I- */ void MySQL_Connection::checkClosed() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::checkClosed"); if (!intern->is_valid) { throw sql::SQLException("Connection has been closed"); } } /* }}} */ /* {{{ MySQL_Connection::close() -I- */ void MySQL_Connection::close() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::close"); checkClosed(); proxy.reset(); clearWarnings(); intern->is_valid = false; } /* }}} */ /* {{{ MySQL_Connection::commit() -I- */ void MySQL_Connection::commit() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::commit"); checkClosed(); proxy->commit(); } /* }}} */ /* {{{ MySQL_Connection::createStatement() -I- */ sql::Statement * MySQL_Connection::createStatement() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::createStatement"); checkClosed(); return new MySQL_Statement(this, proxy, intern->defaultStatementResultType, intern->logger); } /* }}} */ /* {{{ MySQL_Connection::escapeString() -I- */ sql::SQLString MySQL_Connection::escapeString(const sql::SQLString & s) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::escapeString"); checkClosed(); return proxy->escapeString(s); } /* }}} */ /* {{{ MySQL_Connection::getAutoCommit() -I- */ bool MySQL_Connection::getAutoCommit() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getAutoCommit"); checkClosed(); return intern->autocommit; } /* }}} */ /* {{{ MySQL_Connection::getCatalog() -I- */ sql::SQLString MySQL_Connection::getCatalog() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getCatalog"); checkClosed(); return proxy->get_server_version() > 60006 ? "def" : ""; } /* }}} */ /* {{{ MySQL_Connection::getDriver() -I- */ Driver * MySQL_Connection::getDriver() { return driver; } /* }}} */ /** Added for consistency. Not present in jdbc interface. Is still subject for discussion. */ /* {{{ MySQL_Connection::getSchema() -I- */ sql::SQLString MySQL_Connection::getSchema() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getSchema"); checkClosed(); boost::scoped_ptr< sql::Statement > stmt(createStatement()); boost::scoped_ptr< sql::ResultSet > rset(stmt->executeQuery("SELECT DATABASE()")); //SELECT SCHEMA() rset->next(); return rset->getString(1); } /* }}} */ /* {{{ MySQL_Connection::getClientInfo() -I- */ sql::SQLString MySQL_Connection::getClientInfo() { const sql::SQLString clientInfo("cppconn"); CPP_ENTER_WL(intern->logger, "MySQL_Connection::getClientInfo"); return clientInfo; } /* }}} */ #define GET_CONN_OPTION(option_type, option_value, options_map) \ get_connection_option(option_type, option_value, options_map, sizeof(options_map)/sizeof(String2IntMap), proxy) /* {{{ MySQL_Connection::getClientOption() -I- */ void MySQL_Connection::getClientOption(const sql::SQLString & optionName, void * optionValue) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getClientOption"); if (!optionName.compare("metadataUseInfoSchema")) { *(static_cast(optionValue)) = intern->metadata_use_info_schema; } else if (!optionName.compare("defaultStatementResultType")) { *(static_cast(optionValue)) = intern->defaultStatementResultType; } else if (!optionName.compare("defaultPreparedStatementResultType")) { *(static_cast(optionValue)) = intern->defaultPreparedStatementResultType; } else if (!optionName.compare("multiByteMinLength")) { MY_CHARSET_INFO cs; proxy->get_character_set_info(&cs); *(static_cast(optionValue)) = cs.mbminlen; } else if (!optionName.compare("multiByteMaxLength")) { MY_CHARSET_INFO cs; proxy->get_character_set_info(&cs); *(static_cast(optionValue)) = cs.mbmaxlen; /* mysql_get_option() was added in mysql 5.7.3 version */ } else if ( proxy->get_server_version() >= 50703 ) { try { if (GET_CONN_OPTION(optionName, optionValue, intOptions)) { return; } else if (GET_CONN_OPTION(optionName, optionValue, booleanOptions)) { return; } else if (GET_CONN_OPTION(optionName, optionValue, stringOptions)) { return; } } catch (sql::SQLUnsupportedOptionException& e) { CPP_ERR_FMT("Unsupported option : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); throw e; } } } /* }}} */ /* {{{ MySQL_Connection::getClientOption() -I- */ sql::SQLString MySQL_Connection::getClientOption(const sql::SQLString & optionName) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getClientOption"); if (!optionName.compare("characterSetResults")) { return sql::SQLString(getSessionVariable("character_set_results")); } else if (!optionName.compare("characterSetDirectory")) { MY_CHARSET_INFO cs; proxy->get_character_set_info(&cs); return cs.dir ? sql::SQLString(cs.dir) : ""; } else if ( proxy->get_server_version() >= 50703 ) { const char* optionValue= NULL; if (GET_CONN_OPTION(optionName, &optionValue, stringOptions)) { return optionValue ? sql::SQLString(optionValue) : ""; } } return ""; } /* }}} */ /* {{{ MySQL_Connection::getMetaData() -I- */ DatabaseMetaData * MySQL_Connection::getMetaData() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getMetaData"); checkClosed(); return intern->meta.get(); } /* }}} */ /* {{{ MySQL_Connection::getTransactionIsolation() -I- */ enum_transaction_isolation MySQL_Connection::getTransactionIsolation() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getTransactionIsolation"); checkClosed(); return intern->txIsolationLevel; } /* }}} */ /* {{{ MySQL_Connection::getWarnings() -I- */ const SQLWarning * MySQL_Connection::getWarnings() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getWarnings"); checkClosed(); clearWarnings(); intern->warnings.reset(loadMysqlWarnings(this)); return intern->warnings.get(); } /* }}} */ /* {{{ MySQL_Connection::isClosed() -I- */ bool MySQL_Connection::isClosed() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::isClosed"); if (intern->is_valid) { return false; } return true; } /* }}} */ /* {{{ MySQL_Connection::isReadOnly() -U- */ bool MySQL_Connection::isReadOnly() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::isReadOnly"); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Connection::isReadOnly"); return false; // fool compiler } /* }}} */ /* {{{ MySQL_Connection::nativeSQL() -I- */ sql::SQLString MySQL_Connection::nativeSQL(const sql::SQLString& sql) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::nativeSQL"); checkClosed(); return sql::SQLString(sql.c_str()); } /* }}} */ /* {{{ MySQL_Connection::prepareStatement() -I- */ sql::PreparedStatement * MySQL_Connection::prepareStatement(const sql::SQLString& sql) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement"); CPP_INFO_FMT("query=%s", sql.c_str()); checkClosed(); boost::shared_ptr< NativeAPI::NativeStatementWrapper > stmt; //TODO change - probably no need to catch and throw here. Logging can be done inside proxy try { stmt.reset(&proxy->stmt_init()); } catch (sql::SQLException& e) { CPP_ERR_FMT("No statement : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); throw e; } if (stmt->prepare(sql)) { CPP_ERR_FMT("Cannot prepare %d:(%s) %s", stmt->errNo(), stmt->sqlstate().c_str(), stmt->error().c_str()); sql::SQLException e(stmt->error(), stmt->sqlstate(), stmt->errNo()); stmt.reset(); throw e; } return new MySQL_Prepared_Statement(stmt, this, intern->defaultPreparedStatementResultType, intern->logger); } /* }}} */ /* {{{ MySQL_Connection::prepareStatement() -U- */ sql::PreparedStatement * MySQL_Connection::prepareStatement(const sql::SQLString& /* sql */, int /* autoGeneratedKeys */) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement"); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Connection::prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys)"); return NULL; // fool compiler } /* }}} */ /* {{{ MySQL_Connection::prepareStatement() -U- */ sql::PreparedStatement * MySQL_Connection::prepareStatement(const sql::SQLString& /* sql */, int /* columnIndexes */ []) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement"); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Connection::prepareStatement(const sql::SQLString& sql, int* columnIndexes)"); return NULL; // fool compiler } /* }}} */ /* {{{ MySQL_Connection::prepareStatement() -U- */ sql::PreparedStatement * MySQL_Connection::prepareStatement(const sql::SQLString& /* sql */, int /* resultSetType */, int /* resultSetConcurrency */) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement"); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Connection::prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency)"); return NULL; // fool compiler } /* }}} */ /* {{{ MySQL_Connection::prepareStatement() -U- */ sql::PreparedStatement * MySQL_Connection::prepareStatement(const sql::SQLString& /* sql */, int /* resultSetType */, int /* resultSetConcurrency */, int /* resultSetHoldability */) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement"); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Connection::prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)"); return NULL; // fool compiler } /* }}} */ /* {{{ MySQL_Connection::prepareStatement() -U- */ sql::PreparedStatement * MySQL_Connection::prepareStatement(const sql::SQLString& /* sql */, sql::SQLString /* columnNames*/ []) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::prepareStatement"); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Connection::prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[])"); return NULL; // fool compiler } /* }}} */ /* {{{ MySQL_Connection::releaseSavepoint() -I- */ void MySQL_Connection::releaseSavepoint(Savepoint * savepoint) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::releaseSavepoint"); checkClosed(); if (proxy->get_server_version() < 50001) { throw sql::MethodNotImplementedException("releaseSavepoint not available in this server version"); } if (getAutoCommit()) { throw sql::InvalidArgumentException("The connection is in autoCommit mode"); } sql::SQLString sql("RELEASE SAVEPOINT "); sql.append(savepoint->getSavepointName()); boost::scoped_ptr stmt(createStatement()); stmt->execute(sql); } /* }}} */ /* {{{ MySQL_Connection::rollback() -I- */ void MySQL_Connection::rollback() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::rollback"); checkClosed(); proxy->rollback(); } /* }}} */ /* {{{ MySQL_Connection::rollback() -I- */ void MySQL_Connection::rollback(Savepoint * savepoint) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::rollback"); checkClosed(); if (getAutoCommit()) { throw sql::InvalidArgumentException("The connection is in autoCommit mode"); } sql::SQLString sql("ROLLBACK TO SAVEPOINT "); sql.append(savepoint->getSavepointName()); boost::scoped_ptr< sql::Statement > stmt(createStatement()); stmt->execute(sql); } /* }}} */ /* {{{ MySQL_Connection::setCatalog() -I- */ void MySQL_Connection::setCatalog(const sql::SQLString&) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setCatalog"); checkClosed(); } /* }}} */ /* {{{ MySQL_Connection::setSchema() -I- (not part of JDBC) */ void MySQL_Connection::setSchema(const sql::SQLString& catalog) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setCatalog"); checkClosed(); sql::SQLString sql("USE `"); sql.append(catalog).append("`"); boost::scoped_ptr< sql::Statement > stmt(createStatement()); stmt->execute(sql); } /* }}} */ /* {{{ MySQL_Connection::setClientOption() -I- */ sql::Connection * MySQL_Connection::setClientOption(const sql::SQLString & optionName, const void * optionValue) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setClientOption"); if (!optionName.compare("libmysql_debug")) { proxy->debug(static_cast(optionValue)); } else if (!optionName.compare("clientTrace")) { if (*(static_cast(optionValue))) { intern->logger->enableTracing(); CPP_INFO("Tracing enabled"); } else { intern->logger->disableTracing(); CPP_INFO("Tracing disabled"); } } else if (!optionName.compare("metadataUseInfoSchema")) { intern->metadata_use_info_schema = *(static_cast(optionValue)); } else if (!optionName.compare("defaultStatementResultType")) { int int_value = *static_cast(optionValue); do { if (static_cast< int >(sql::ResultSet::TYPE_FORWARD_ONLY) == int_value) break; if (static_cast< int >(sql::ResultSet::TYPE_SCROLL_INSENSITIVE) == int_value) break; if (static_cast< int >(sql::ResultSet::TYPE_SCROLL_SENSITIVE) == int_value) { std::ostringstream msg; msg << "Invalid value " << int_value << " for option defaultStatementResultType. TYPE_SCROLL_SENSITIVE is not supported"; throw sql::InvalidArgumentException(msg.str()); } std::ostringstream msg; msg << "Invalid value (" << int_value << " for option defaultStatementResultType"; throw sql::InvalidArgumentException(msg.str()); } while (0); intern->defaultStatementResultType = static_cast< sql::ResultSet::enum_type >(int_value); } else if (!optionName.compare("defaultPreparedStatementResultType")) { #if WE_SUPPORT_USE_RESULT_WITH_PS /* The connector is not ready for unbuffered as we need to refetch */ intern->defaultPreparedStatementResultType = *(static_cast(optionValue)); #else throw MethodNotImplementedException("MySQL_Prepared_Statement::setResultSetType"); #endif } return this; } /* }}} */ /* {{{ MySQL_Connection::setClientOption() -I- */ sql::Connection * MySQL_Connection::setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setClientOption"); if (!optionName.compare("characterSetResults")) { setSessionVariable("character_set_results", optionValue); } return this; } /* }}} */ /* {{{ MySQL_Connection::setHoldability() -U- */ void MySQL_Connection::setHoldability(int /* holdability */) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setHoldability"); throw sql::MethodNotImplementedException("MySQL_Connection::setHoldability()"); } /* }}} */ /* {{{ MySQL_Connection::setReadOnly() -U- */ void MySQL_Connection::setReadOnly(bool /* readOnly */) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setReadOnly"); throw sql::MethodNotImplementedException("MySQL_Connection::setReadOnly()"); } /* }}} */ /* {{{ MySQL_Connection::setSavepoint() -U- */ Savepoint * MySQL_Connection::setSavepoint() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setSavepoint"); checkClosed(); throw sql::MethodNotImplementedException("Please use MySQL_Connection::setSavepoint(const sql::SQLString& name)"); return NULL; } /* }}} */ /* {{{ MySQL_Connection::setSavepoint() -I- */ sql::Savepoint * MySQL_Connection::setSavepoint(const sql::SQLString& name) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setSavepoint"); checkClosed(); if (getAutoCommit()) { throw sql::InvalidArgumentException("The connection is in autoCommit mode"); } if (!name.length()) { throw sql::InvalidArgumentException("Savepoint name cannot be empty string"); } sql::SQLString sql("SAVEPOINT "); sql.append(name); boost::scoped_ptr< sql::Statement > stmt(createStatement()); stmt->execute(sql); return new MySQL_Savepoint(name); } /* }}} */ /* {{{ MySQL_Connection::setAutoCommit() -I- */ void MySQL_Connection::setAutoCommit(bool autoCommit) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setAutoCommit"); checkClosed(); proxy->autocommit(autoCommit); intern->autocommit = autoCommit; } /* }}} */ /* {{{ MySQL_Connection::setTransactionIsolation() -I- */ void MySQL_Connection::setTransactionIsolation(enum_transaction_isolation level) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setTransactionIsolation"); checkClosed(); const char * q; switch (level) { case TRANSACTION_SERIALIZABLE: q = "SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE"; break; case TRANSACTION_REPEATABLE_READ: q = "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"; break; case TRANSACTION_READ_COMMITTED: q = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"; break; case TRANSACTION_READ_UNCOMMITTED: q = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"; break; default: throw sql::InvalidArgumentException("MySQL_Connection::setTransactionIsolation()"); } intern->txIsolationLevel = level; service->executeUpdate(q); } /* }}} */ /* {{{ MySQL_Connection::getLastStatementInfo() -I- */ sql::SQLString MySQL_Connection::getLastStatementInfo() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getLastStatementInfo"); checkClosed(); return proxy->info(); } /* }}} */ /* {{{ MySQL_Connection::getSessionVariable() -I- */ sql::SQLString MySQL_Connection::getSessionVariable(const sql::SQLString & varname) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::getSessionVariable"); checkClosed(); if (intern->cache_sql_mode && intern->sql_mode_set == true && !varname.compare("sql_mode")) { CPP_INFO_FMT("sql_mode=%s", intern->sql_mode.c_str()); return intern->sql_mode; } sql::SQLString q("SHOW SESSION VARIABLES LIKE '"); q.append(varname).append("'"); boost::scoped_ptr< sql::ResultSet > rset(service->executeQuery(q)); if (rset->next()) { if (intern->cache_sql_mode && intern->sql_mode_set == false && !varname.compare("sql_mode")) { intern->sql_mode = rset->getString(2); intern->sql_mode_set = true; } return rset->getString(2); } return ""; } /* }}} */ /* {{{ MySQL_Connection::setSessionVariable() -I- */ void MySQL_Connection::setSessionVariable(const sql::SQLString & varname, const sql::SQLString & value) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setSessionVariable"); checkClosed(); sql::SQLString query("SET SESSION "); query.append(varname).append("="); if (!value.compare("NULL")) { query.append("NULL"); } else { query.append("'").append(value).append("'"); } service->executeUpdate(query); if (intern->cache_sql_mode && !strncasecmp(varname.c_str(), "sql_mode", sizeof("sql_mode") - 1)) { intern->sql_mode= value; } } /* }}} */ /* {{{ MySQL_Connection::setSessionVariable() -I- */ void MySQL_Connection::setSessionVariable(const sql::SQLString & varname, unsigned int value) { CPP_ENTER_WL(intern->logger, "MySQL_Connection::setSessionVariable"); checkClosed(); sql::SQLString query("SET SESSION "); query.append(varname).append("="); if (!value) { query.append("0"); } else { std::ostringstream qstr; qstr << value; query.append(qstr.str()); } service->executeUpdate(query); } /* }}} */ /* {{{ MySQL_Connection::isValid() -I- */ bool MySQL_Connection::isValid() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::isValid"); bool is_active= false; if (intern->is_valid) { if (intern->reconnect) { bool opt_reconnect_value= false; try { proxy->options(MYSQL_OPT_RECONNECT, (const char *) &opt_reconnect_value); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_RECONNECT"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } is_active= proxy->ping(); opt_reconnect_value= true; try { proxy->options(MYSQL_OPT_RECONNECT, (const char *) &opt_reconnect_value); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_RECONNECT"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } if (is_active == 0) { return true; } } else { if (!proxy->ping()) { return true; } } } return false; } /* }}} */ /* {{{ MySQL_Connection::reconnect() -I- */ bool MySQL_Connection::reconnect() { CPP_ENTER_WL(intern->logger, "MySQL_Connection::reconnect"); bool is_active= false; if (intern->is_valid) { if (intern->reconnect) { if (!proxy->ping()) { return true; } } else { bool opt_reconnect_value= true; try { proxy->options(MYSQL_OPT_RECONNECT, (const char *) &opt_reconnect_value); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_RECONNECT"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } is_active= proxy->ping(); opt_reconnect_value= false; try { proxy->options(MYSQL_OPT_RECONNECT, (const char *) &opt_reconnect_value); } catch (sql::InvalidArgumentException& e) { std::string errorOption("MYSQL_OPT_RECONNECT"); throw ::sql::SQLUnsupportedOptionException(e.what(), errorOption); } if (is_active == 0) { return true; } } } return false; } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_connection.h000644 015771 000012 00000012524 12645244436 023017 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_CONNECTION_H_ #define _MYSQL_CONNECTION_H_ #include #include #include namespace sql { namespace mysql { class MySQL_Savepoint : public sql::Savepoint { sql::SQLString name; public: MySQL_Savepoint(const sql::SQLString &savepoint); virtual ~MySQL_Savepoint() {} int getSavepointId(); sql::SQLString getSavepointName(); private: /* Prevent use of these */ MySQL_Savepoint(const MySQL_Savepoint &); void operator=(MySQL_Savepoint &); }; class MySQL_DebugLogger; struct MySQL_ConnectionData; /* PIMPL */ class MySQL_Statement; namespace NativeAPI { class NativeConnectionWrapper; } class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection { MySQL_Statement * createServiceStmt(); public: MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password); MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, std::map< sql::SQLString, sql::ConnectPropertyVal > & options); virtual ~MySQL_Connection(); void clearWarnings(); void close(); void commit(); sql::Statement * createStatement(); sql::SQLString escapeString(const sql::SQLString &); bool getAutoCommit(); sql::SQLString getCatalog(); Driver *getDriver(); sql::SQLString getSchema(); sql::SQLString getClientInfo(); void getClientOption(const sql::SQLString & optionName, void * optionValue); sql::SQLString getClientOption(const sql::SQLString & optionName); sql::DatabaseMetaData * getMetaData(); enum_transaction_isolation getTransactionIsolation(); const SQLWarning * getWarnings(); bool isClosed(); bool isReadOnly(); bool isValid(); bool reconnect(); sql::SQLString nativeSQL(const sql::SQLString& sql); sql::PreparedStatement * prepareStatement(const sql::SQLString& sql); sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys); sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int columnIndexes[]); sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency); sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability); sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]); void releaseSavepoint(Savepoint * savepoint) ; void rollback(); void rollback(Savepoint * savepoint); void setAutoCommit(bool autoCommit); void setCatalog(const sql::SQLString& catalog); void setSchema(const sql::SQLString& catalog); sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue); sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue); void setHoldability(int holdability); void setReadOnly(bool readOnly); sql::Savepoint * setSavepoint(); sql::Savepoint * setSavepoint(const sql::SQLString& name); void setTransactionIsolation(enum_transaction_isolation level); virtual sql::SQLString getSessionVariable(const sql::SQLString & varname); virtual void setSessionVariable(const sql::SQLString & varname, const sql::SQLString & value); virtual void setSessionVariable(const sql::SQLString & varname, unsigned int value); virtual sql::SQLString getLastStatementInfo(); private: /* We do not really think this class has to be subclassed*/ void checkClosed(); void init(std::map< sql::SQLString, sql::ConnectPropertyVal > & properties); Driver * driver; boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy; /* statement handle to execute queries initiated by driver. Perhaps it is a good idea to move it to a separate helper class */ boost::scoped_ptr< ::sql::mysql::MySQL_Statement > service; boost::scoped_ptr< ::sql::mysql::MySQL_ConnectionData > intern; /* pimpl */ /* Prevent use of these */ MySQL_Connection(const MySQL_Connection &); void operator=(MySQL_Connection &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_CONNECTION_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_connection_data.h000644 015771 000012 00000005130 12645244436 024003 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_CONNECTION_DATA_H_ #define _MYSQL_CONNECTION_DATA_H_ #include #include #include #include #include "mysql_util.h" #include "mysql_metadata.h" #include "mysql_warning.h" namespace sql { namespace mysql { class MySQL_DebugLogger; class MySQL_ConnectionMetaData; struct MySQL_ConnectionData { MySQL_ConnectionData(boost::shared_ptr< MySQL_DebugLogger > & l) : closed(false), autocommit(false), txIsolationLevel(TRANSACTION_READ_COMMITTED), is_valid(false), sql_mode_set(false), cache_sql_mode(false), metadata_use_info_schema(true), reconnect(false), defaultStatementResultType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE), defaultPreparedStatementResultType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE), logger(l), meta(NULL) {} ~MySQL_ConnectionData() { } bool closed; bool autocommit; enum_transaction_isolation txIsolationLevel; boost::scoped_ptr warnings; bool is_valid; sql::SQLString sql_mode; bool sql_mode_set; bool cache_sql_mode; bool metadata_use_info_schema; bool reconnect; sql::ResultSet::enum_type defaultStatementResultType; sql::ResultSet::enum_type defaultPreparedStatementResultType; boost::shared_ptr< MySQL_DebugLogger > logger; boost::scoped_ptr< MySQL_ConnectionMetaData > meta; }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_CONNECTION_DATA_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_connection_options.h000644 015771 000012 00000004262 12645244436 024572 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_CONNECTION_OPTIONS_H_ #define _MYSQL_CONNECTION_OPTIONS_H_ namespace sql { namespace mysql { enum MySQL_Connection_Options { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT, MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, MYSQL_OPT_BIND, MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH, MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD, MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_SERVER_PUBLIC_KEY, MYSQL_ENABLE_CLEARTEXT_PLUGIN, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, MYSQL_OPT_SSL_ENFORCE }; } } #endif mysql-connector-c++-1.1.7/driver/mysql_debug.cpp000644 015771 000012 00000010316 12645244436 022276 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "mysql_debug.h" #define NON_WANTED_FUNCTIONS !strstr(func, "Closed") \ && !strstr(func, "Valid") \ && !strstr(func, "getMySQLHandle") \ && !strstr(func, "isBeforeFirstOrAfterLast") namespace sql { namespace mysql { /* {{{ MySQL_DebugEnterEvent::MySQL_DebugEnterEvent() -I- */ MySQL_DebugEnterEvent::MySQL_DebugEnterEvent(unsigned int l, const char * const f, const char * const func_name, const boost::shared_ptr< MySQL_DebugLogger > & logger_object) : line(l), file(f), func(func_name), logger(logger_object) { if (logger) { if (NON_WANTED_FUNCTIONS) { logger->enter(this); } } } /* }}} */ /* {{{ MySQL_DebugEnterEvent::MySQL_DebugEnterEvent() -I- */ MySQL_DebugEnterEvent::~MySQL_DebugEnterEvent() { if (logger) { if (NON_WANTED_FUNCTIONS) { logger->leave(this); } } } /* }}} */ /* {{{ MySQL_DebugLogger::MySQL_DebugLogger() -I- */ MySQL_DebugLogger::MySQL_DebugLogger() : tracing(NO_TRACE) { // ToDo: On Win getenv() is not thread-safe ! if (getenv("MYSQLCPPCONN_TRACE_ENABLED")) { tracing = NORMAL_TRACE; } } /* }}} */ /* {{{ MySQL_DebugLogger::~MySQL_DebugLogger() -I- */ MySQL_DebugLogger::~MySQL_DebugLogger() { callStack.empty(); } /* }}} */ /* {{{ MySQL_DebugLogger::disableTracing() -I- */ void MySQL_DebugLogger::disableTracing() { tracing = NO_TRACE; } /* }}} */ /* {{{ MySQL_DebugLogger::enableTracing() -I- */ void MySQL_DebugLogger::enableTracing() { tracing = NORMAL_TRACE; } /* }}} */ /* {{{ MySQL_DebugLogger::enter() -I- */ void MySQL_DebugLogger::enter(const MySQL_DebugEnterEvent * event) { if (tracing != NO_TRACE) { printf("#\t"); for (unsigned int i = 0; i < callStack.size(); ++i) { printf("| "); } printf(">%s\n", event->func); } callStack.push(event); } /* }}} */ /* {{{ MySQL_DebugLogger::isTracing() -I- */ bool MySQL_DebugLogger::isTracing() { return (tracing != NO_TRACE); } /* }}} */ /* {{{ MySQL_DebugLogger::leave() -I- */ void MySQL_DebugLogger::leave(const MySQL_DebugEnterEvent * event) { callStack.pop(); if (tracing != NO_TRACE) { printf("#\t"); for (unsigned int i = 0; i < callStack.size(); ++i) { printf("| "); } printf("<%s\n", event->func); } } /* }}} */ /* {{{ MySQL_DebugLogger::log() -I- */ void MySQL_DebugLogger::log(const char * const type, const char * const message) { if (tracing == NO_TRACE) { return; } printf("#\t"); for (unsigned int i = 0; i < callStack.size(); ++i) { printf("| "); } printf("%s: ", type); printf("%s\n", message); } /* }}} */ /* {{{ MySQL_DebugLogger::log_va() -I- */ void MySQL_DebugLogger::log_va(const char * const type, const char * const format, ...) { if (tracing == NO_TRACE) { return; } va_list args; printf("#\t"); for (unsigned int i = 0; i < callStack.size(); ++i) { printf("| "); } printf("%s: ", type); va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_debug.h000644 015771 000012 00000007011 12645244436 021741 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_DEBUG_H_ #define _MYSQL_DEBUG_H_ #include /* _MSC_VER VC6.0=1200, VC7.0=1300, VC7.1=1310, VC8.0=1400 */ #if defined(_MSC_VER) #if _MSC_VER >=1400 #define WE_HAVE_VARARGS_MACRO_SUPPORT #endif #else #define WE_HAVE_VARARGS_MACRO_SUPPORT #endif #if defined(WE_HAVE_VARARGS_MACRO_SUPPORT) && (CPPCONN_TRACE_ENABLED || defined(SAL_DLLPRIVATE)) #define CPP_ENTER(msg) const boost::shared_ptr< MySQL_DebugLogger > __l = this->logger;(void)__l;\ MySQL_DebugEnterEvent __this_func(__LINE__, __FILE__, msg, this->logger) #define CPP_ENTER_WL(l, msg) const boost::shared_ptr< MySQL_DebugLogger > __l = (l);(void)__l;\ MySQL_DebugEnterEvent __this_func(__LINE__, __FILE__, msg, (l)) #define CPP_INFO(msg) {if (__l) __l->log("INF", msg); } #define CPP_INFO_FMT(...) {if (__l) __l->log_va("INF", __VA_ARGS__); } #define CPP_ERR(msg) {if (__l) __l->log("ERR", msg); } #define CPP_ERR_FMT(...) {if (__l) __l->log_va("ERR", __VA_ARGS__); } #else #define CPP_ENTER(msg) #define CPP_ENTER_WL(l, msg) #define CPP_INFO(msg) #define CPP_ERR(msg) #define CPP_ENTER_WL(l, msg) static inline void CPP_INFO_FMT(...) {} static inline void CPP_ERR_FMT(...) {} #endif #include #include "mysql_util.h" namespace sql { namespace mysql { class MySQL_DebugEnterEvent; class MySQL_DebugLogger { std::stack< const MySQL_DebugEnterEvent * > callStack; int tracing; enum { NO_TRACE, NORMAL_TRACE }; public: MySQL_DebugLogger(); virtual ~MySQL_DebugLogger(); void disableTracing(); void enableTracing(); void enter(const MySQL_DebugEnterEvent * obj); bool isTracing(); void leave(const MySQL_DebugEnterEvent * obj); void log(const char * const type, const char * const message); void log_va(const char * const type, const char * const format, ...); private: /* Prevent use of these */ MySQL_DebugLogger(const MySQL_DebugLogger &); void operator=(MySQL_DebugLogger &); }; class MySQL_DebugEnterEvent { public: unsigned int line; const char * const file; const char * const func; const boost::shared_ptr< MySQL_DebugLogger > logger; MySQL_DebugEnterEvent(unsigned int l, const char * const f, const char * const func_name, const boost::shared_ptr< MySQL_DebugLogger > & logger_object); ~MySQL_DebugEnterEvent(); }; } /* namespace mysql */ } /* namespace sql */ #endif /* _MYSQL_DEBUG_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_driver.cpp000644 015771 000012 00000010107 12645244436 022501 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_connection.h" #include "version_info.h" #include // Looks like this one should go after private_iface #include "mysql_driver.h" #include "nativeapi/native_driver_wrapper.h" extern "C" { CPPCONN_PUBLIC_FUNC void * sql_mysql_get_driver_instance() { void * ret = sql::mysql::get_driver_instance(); return ret; } /* these are the functions without namespace - from cppconn/driver.h */ CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib) { return sql::mysql::get_driver_instance_by_name(clientlib); } CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance() { return sql::mysql::get_driver_instance(); } } /* extern "C" */ namespace sql { namespace mysql { static const ::sql::SQLString emptyStr(""); /* Mapping by client name is probably not enough here */ static std::map< sql::SQLString, boost::shared_ptr > driver; CPPCONN_PUBLIC_FUNC sql::mysql::MySQL_Driver * get_driver_instance() { return get_driver_instance_by_name(""); } CPPCONN_PUBLIC_FUNC sql::mysql::MySQL_Driver * get_driver_instance_by_name(const char * const clientlib) { ::sql::SQLString dummy(clientlib); std::map< sql::SQLString, boost::shared_ptr< MySQL_Driver > >::const_iterator cit; if ((cit = driver.find(dummy)) != driver.end()) { return cit->second.get(); } else { boost::shared_ptr< MySQL_Driver > newDriver; newDriver.reset(new MySQL_Driver(dummy)); driver[dummy] = newDriver; return newDriver.get(); } } MySQL_Driver::MySQL_Driver() { try { proxy.reset(::sql::mysql::NativeAPI::createNativeDriverWrapper(emptyStr)); } catch(std::runtime_error & e) { throw sql::InvalidArgumentException(e.what()); } } MySQL_Driver::MySQL_Driver(const ::sql::SQLString & clientLib) { try { proxy.reset(::sql::mysql::NativeAPI::createNativeDriverWrapper(clientLib)); } catch(std::runtime_error & e) { throw sql::InvalidArgumentException(e.what()); } } MySQL_Driver::~MySQL_Driver() { } sql::Connection * MySQL_Driver::connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) { return new MySQL_Connection(this, proxy->conn_init(),hostName, userName, password); } sql::Connection * MySQL_Driver::connect(sql::ConnectOptionsMap & properties) { return new MySQL_Connection(this, proxy->conn_init(),properties); } //TODO: That has to be defined in cmake files int MySQL_Driver::getMajorVersion() { return MYCPPCONN_MAJOR_VERSION; } int MySQL_Driver::getMinorVersion() { return MYCPPCONN_MINOR_VERSION; } int MySQL_Driver::getPatchVersion() { return MYCPPCONN_PATCH_VERSION; } const sql::SQLString & MySQL_Driver::getName() { static const sql::SQLString name("MySQL Connector C++ (libmysql)"); return name; } void MySQL_Driver::threadInit() { proxy->thread_init(); } void MySQL_Driver::threadEnd() { proxy->thread_end(); } } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_driver.h000644 015771 000012 00000005411 12645244436 022150 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_DRIVER_H_ #define _MYSQL_DRIVER_H_ #include #include extern "C" { CPPCONN_PUBLIC_FUNC void * sql_mysql_get_driver_instance(); } namespace sql { namespace mysql { namespace NativeAPI { class NativeDriverWrapper; } //class sql::mysql::NativeAPI::NativeDriverWrapper; class CPPCONN_PUBLIC_FUNC MySQL_Driver : public sql::Driver { boost::scoped_ptr< ::sql::mysql::NativeAPI::NativeDriverWrapper > proxy; public: MySQL_Driver(); MySQL_Driver(const ::sql::SQLString & clientLib); virtual ~MySQL_Driver(); sql::Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password); sql::Connection * connect(sql::ConnectOptionsMap & options); int getMajorVersion(); int getMinorVersion(); int getPatchVersion(); const sql::SQLString & getName(); void threadInit(); void threadEnd(); private: /* Prevent use of these */ MySQL_Driver(const MySQL_Driver &); void operator=(MySQL_Driver &); }; /** We do not hide the function if MYSQLCLIENT_STATIC_BINDING(or anything else) not defined because the counterpart C function is declared in the cppconn and is always visible. If dynamic loading is not enabled then its result is just like of get_driver_instance() */ CPPCONN_PUBLIC_FUNC MySQL_Driver * get_driver_instance_by_name(const char * const clientlib); CPPCONN_PUBLIC_FUNC MySQL_Driver * get_driver_instance(); static inline MySQL_Driver * get_mysql_driver_instance() { return get_driver_instance(); } } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_DRIVER_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_error.h000644 015771 000012 00000003032 12645244436 022003 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_ERROR_H_ #define _MYSQL_ERROR_H_ namespace sql { namespace mysql { /* Driver specific errors */ enum DRIVER_ERROR { /* Underlying client library(cl) can't deal with expired password. Raised when password actually expires */ deCL_CANT_HANDLE_EXP_PWD= 820 }; } /* namespace mysql */ } /* namespace sql */ #endif /* _MYSQL_ERROR_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_metadata.cpp000644 015771 000012 00000543744 12645244436 023010 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include "mysql_util.h" #include "mysql_connection.h" #include "mysql_metadata.h" #include "mysql_art_resultset.h" #include "mysql_statement.h" #include "mysql_prepared_statement.h" #include "mysql_debug.h" #include "version_info.h" #include "nativeapi/native_connection_wrapper.h" // For snprintf #include namespace sql { namespace mysql { struct TypeInfoDef { const char * const typeName; int dataType; unsigned long long precision; const char * const literalPrefix; const char * const literalSuffix; const char * const createParams; short nullable; bool caseSensitive; short searchable; bool isUnsigned; bool fixedPrecScale; bool autoIncrement; const char * localTypeName; int minScale; int maxScale; int sqlDataType; int sqlDateTimeSub; int numPrecRadix; }; static const TypeInfoDef mysqlc_types[] = { // ------------- MySQL-Type: BIT. DBC-Type: BIT ------------- { "BIT", // Typename sql::DataType::BIT, // dbc-type 1, // Precision "", // Literal prefix "", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "BIT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, #ifdef ENABLE_ONCE_THE_SERVER_HAS_REAL_BOOL // ------------ MySQL-Type: BOOL. DBC-Type: BIT ------------- { "BOOL", // Typename sql::DataType::TINYINT, // dbc-type 1, // Precision "", // Literal prefix "", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "BOOL", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, #endif // --------- MySQL-Type: TINYINT DBC-Type: TINYINT ---------- { "TINYINT", // Typename sql::DataType::TINYINT, // dbc-type 3, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "TINYINT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "TINYINT UNSIGNED", // Typename sql::DataType::TINYINT, // dbc-type 3, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [UNSIGNED] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "TINYINT UNSIGNED", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "TINYINT UNSIGNED ZEROFILL", // Typename sql::DataType::TINYINT, // dbc-type 3, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [UNSIGNED]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "TINYINT UNSIGNED ZEROFILL", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: BIGINT DBC-Type: BIGINT ---------- { "BIGINT", // Typename sql::DataType::BIGINT, // dbc-type 19, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "BIGINT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "BIGINT UNSIGNED", // Typename sql::DataType::BIGINT, // dbc-type 19, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "BIGINT UNSIGNED", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "BIGINT UNSIGNED ZEROFILL", // Typename sql::DataType::BIGINT, // dbc-type 19, // Precision "", // Literal prefix "", // Literal suffix "[(M)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "BIGINT UNSIGNED ZEROFILL", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: LONG VARBINARY DBC-Type: LONGVARBINARY ---------- { "LONG VARBINARY", // Typename sql::DataType::LONGVARBINARY, // dbc-type 16777215, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "LONG VARBINARY", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: MEDIUMBLOB DBC-Type: LONGVARBINARY ---------- { "MEDIUMBLOB", // Typename sql::DataType::LONGVARBINARY, // dbc-type 16777215, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "MEDIUMBLOB", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: LONGBLOB DBC-Type: LONGVARBINARY ---------- { "LONGBLOB", // Typename sql::DataType::LONGVARBINARY, // dbc-type 0xFFFFFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "LONGBLOB", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: BLOB DBC-Type: LONGVARBINARY ---------- { "BLOB", // Typename sql::DataType::LONGVARBINARY, // dbc-type 0xFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "BLOB", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: TINYBLOB DBC-Type: LONGVARBINARY ---------- { "TINYBLOB", // Typename sql::DataType::LONGVARBINARY, // dbc-type 0xFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "TINYBLOB", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: VARBINARY DBC-Type: VARBINARY ---------- { "VARBINARY", // Typename sql::DataType::VARBINARY, // dbc-type 0xFF, // Precision "'", // Literal prefix "'", // Literal suffix "(M)", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "VARBINARY", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: BINARY DBC-Type: BINARY ---------- { "BINARY", // Typename sql::DataType::BINARY, // dbc-type 0xFF, // Precision "'", // Literal prefix "'", // Literal suffix "(M)", // Create params DatabaseMetaData::typeNullable, // nullable true, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "BINARY", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: LONG VARCHAR DBC-Type: LONG VARCHAR ---------- { "LONG VARCHAR", // Typename sql::DataType::LONGVARCHAR, // dbc-type 0xFFFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "LONG VARCHAR", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: MEDIUMTEXT DBC-Type: LONG VARCHAR ---------- { "MEDIUMTEXT", // Typename sql::DataType::LONGVARCHAR, // dbc-type 0xFFFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "MEDIUMTEXT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: LONGTEXT DBC-Type: LONG VARCHAR ---------- { "LONGTEXT", // Typename sql::DataType::LONGVARCHAR, // dbc-type 0xFFFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "LONGTEXT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: TEXT DBC-Type: LONG VARCHAR ---------- { "TEXT", // Typename sql::DataType::LONGVARCHAR, // dbc-type 0xFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "TEXT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: TINYTEXT DBC-Type: LONG VARCHAR ---------- { "TINYTEXT", // Typename sql::DataType::LONGVARCHAR, // dbc-type 0xFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "TINYTEXT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: CHAR DBC-Type: CHAR ---------- { "CHAR", // Typename sql::DataType::CHAR, // dbc-type 0xFF, // Precision "'", // Literal prefix "'", // Literal suffix "(M)", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "CHAR", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ToDo : The maximum number of digits for DECIMAL or NUMERIC is 65 (64 from MySQL 5.0.3 to 5.0.5). // ----------- MySQL-Type: NUMERIC (silently conv. to DECIMAL) DBC-Type: NUMERIC ---------- { "NUMERIC", // Typename sql::DataType::NUMERIC, // dbc-type 64, // Precision "", // Literal prefix "", // Literal suffix "[(M[,D])] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "NUMERIC", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: DECIMAL DBC-Type: DECIMAL ---------- { "DECIMAL", // Typename sql::DataType::DECIMAL, // dbc-type 64, // Precision "", // Literal prefix "", // Literal suffix "[(M[,D])] [ZEROFILL] [UNSIGNED]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "DECIMAL", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "DECIMAL UNSIGNED", // Typename sql::DataType::DECIMAL, // dbc-type 64, // Precision "", // Literal prefix "", // Literal suffix "[(M[,D])] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "DECIMAL UNSIGNED", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "DECIMAL UNSIGNED ZEROFILL", // Typename sql::DataType::DECIMAL, // dbc-type 64, // Precision "", // Literal prefix "", // Literal suffix "[(M[,D])]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "DECIMAL UNSIGNED ZEROFILL", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, #ifdef LETS_HAVE_JUST_ONLY_ONE_INT_TYPE // ----------- MySQL-Type: INTEGER DBC-Type: INTEGER ---------- { "INTEGER", // Typename sql::DataType::INTEGER, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [UNSIGNED] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "INTEGER", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "INTEGER UNSIGNED", // Typename sql::DataType::INTEGER, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "INTEGER UNSIGNED", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, #endif // ----------- MySQL-Type: INT DBC-Type: INTEGER ---------- { "INT", // Typename sql::DataType::INTEGER, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [UNSIGNED] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "INT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "INT UNSIGNED", // Typename sql::DataType::INTEGER, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "INT UNSIGNED", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "INT UNSIGNED ZEROFILL", // Typename sql::DataType::INTEGER, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "INT UNSIGNED ZEROFILL", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: MEDIUMINT DBC-Type: MEDIUMINT ---------- { "MEDIUMINT", // Typename sql::DataType::MEDIUMINT, // dbc-type 7, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [UNSIGNED] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "MEDIUMINT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "MEDIUMINT UNSIGNED", // Typename sql::DataType::MEDIUMINT, // dbc-type 7, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "MEDIUMINT UNSIGNED", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "MEDIUMINT UNSIGNED ZEROFILL", // Typename sql::DataType::MEDIUMINT, // dbc-type 7, // Precision "", // Literal prefix "", // Literal suffix "[(M)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "MEDIUMINT UNSIGNED ZEROFILL", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: SMALLINT DBC-Type: SMALLINT ---------- { "SMALLINT", // Typename sql::DataType::SMALLINT, // dbc-type 5, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [UNSIGNED] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "SMALLINT", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "SMALLINT UNSIGNED", // Typename sql::DataType::SMALLINT, // dbc-type 5, // Precision "", // Literal prefix "", // Literal suffix "[(M)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "SMALLINT UNSIGNED", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "SMALLINT UNSIGNED ZEROFILL", // Typename sql::DataType::SMALLINT, // dbc-type 5, // Precision "", // Literal prefix "", // Literal suffix "[(M)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "SMALLINT UNSIGNED ZEROFILL", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, /* * MySQL Type: FLOAT JDBC Type: REAL (this is the SINGLE PERCISION * floating point type) */ // ----------- MySQL-Type: FLOAT DBC-Type: REAL ---------- { "FLOAT", // Typename sql::DataType::REAL, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)] [ZEROFILL] [UNSIGNED]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "FLOAT", // local type name -38, // minimum scale 38, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "FLOAT UNSIGNED", // Typename sql::DataType::REAL, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "FLOAT UNSIGNED", // local type name -38, // minimum scale 38, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "FLOAT UNSIGNED ZEROFILL", // Typename sql::DataType::REAL, // dbc-type 10, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "FLOAT UNSIGNED ZEROFILL", // local type name -38, // minimum scale 38, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: DOUBLE DBC-Type: DOUBLE ---------- { "DOUBLE", // Typename sql::DataType::DOUBLE, // dbc-type 17, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)] [ZEROFILL] [UNSIGNED]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "DOUBLE", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "DOUBLE UNSIGNED", // Typename sql::DataType::DOUBLE, // dbc-type 17, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "DOUBLE UNSIGNED", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "DOUBLE UNSIGNED ZEROFILL", // Typename sql::DataType::DOUBLE, // dbc-type 17, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "DOUBLE UNSIGNED ZEROFILL", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, /* * MySQL Type: REAL (does not map to Types.REAL) JDBC Type: DOUBLE */ // ----------- MySQL-Type: REAL DBC-Type: DOUBLE ---------- { "REAL", // Typename sql::DataType::DOUBLE, // dbc-type 17, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)] [ZEROFILL] [UNSIGNED]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "REAL", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, { "REAL UNSIGNED", // Typename sql::DataType::DOUBLE, // dbc-type 17, // Precision "", // Literal prefix "", // Literal suffix "[(M,D)] [ZEROFILL]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable true, // unsigned_attribute false, // fixed_prec_scale true, // auto_increment "REAL UNSIGNED", // local type name -308, // minimum scale 308, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: VARCHAR DBC-Type: VARCHAR ---------- { "VARCHAR", // Typename sql::DataType::VARCHAR, // dbc-type 255, // Precision "'", // Literal prefix "'", // Literal suffix "(M)", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "VARCHAR", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: ENUM DBC-Type: VARCHAR ---------- { "ENUM", // Typename sql::DataType::ENUM, // dbc-type 0xFFFF, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "ENUM", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: SET DBC-Type: VARCHAR ---------- { "SET", // Typename sql::DataType::SET, // dbc-type 64, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "SET", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: DATE DBC-Type: DATE ---------- { "DATE", // Typename sql::DataType::DATE, // dbc-type 0, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "DATE", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: TIME DBC-Type: TIME ---------- { "TIME", // Typename sql::DataType::TIME, // dbc-type 0, // Precision "", // Literal prefix "", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "TIME", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: DATETIME DBC-Type: TIMESTAMP ---------- { "DATETIME", // Typename sql::DataType::TIMESTAMP, // dbc-type 0, // Precision "", // Literal prefix "", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "DATETIME", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: TIMESTAMP DBC-Type: TIMESTAMP ---------- { "TIMESTAMP", // Typename sql::DataType::TIMESTAMP, // dbc-type 0, // Precision "'", // Literal prefix "'", // Literal suffix "[(M)]", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "TIMESTAMP", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: DATE DBC-Type: DATE ---------- { "YEAR", // Typename sql::DataType::YEAR, // dbc-type 0, // Precision "'", // Literal prefix "'", // Literal suffix "", // Create params DatabaseMetaData::typeNullable, // nullable false, // case sensitive DatabaseMetaData::typeSearchable, // searchable false, // unsigned_attribute false, // fixed_prec_scale false, // auto_increment "YEAR", // local type name 0, // minimum scale 0, // maximum scale 0, // sql data type (unused) 0, // sql datetime sub (unused) 10 // num prec radix }, // ----------- MySQL-Type: TIMESTAMP DBC-Type: TIMESTAMP ---------- { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; /* {{{ my_i_to_a() -I- */ static inline const char * my_i_to_a(char * buf, size_t buf_size, int a) { snprintf(buf, buf_size, "%d", a); return buf; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::MySQL_ConnectionMetaData() -I- */ MySQL_ConnectionMetaData::MySQL_ConnectionMetaData(sql::Statement * const service, boost::shared_ptr _proxy, boost::shared_ptr< MySQL_DebugLogger > & l) : stmt(service), connection(dynamic_cast< MySQL_Connection * >(service->getConnection())), logger(l), proxy(_proxy), use_info_schema(true) { CPP_ENTER("MySQL_ConnectionMetaData::MySQL_ConnectionMetaData"); server_version = proxy->get_server_version(); lower_case_table_names = connection->getSessionVariable("lower_case_table_names"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::~MySQL_ConnectionMetaData() -I- */ MySQL_ConnectionMetaData::~MySQL_ConnectionMetaData() { CPP_ENTER("MySQL_ConnectionMetaData::~MySQL_ConnectionMetaData"); CPP_INFO_FMT("this=%p", this); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemata() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSchemata(const sql::SQLString& /*catalogName*/) { CPP_ENTER("MySQL_ConnectionMetaData::getSchemata"); return stmt->executeQuery("SHOW DATABASES"); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemaObjects() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSchemaObjects(const sql::SQLString& /* catalogName */, const sql::SQLString& schemaName, const sql::SQLString& objectType, bool includingDdl, const sql::SQLString& objectName, const sql::SQLString& contextTableName) { CPP_ENTER("MySQL_ConnectionMetaData::getSchemaObjects"); // for now catalog name is ignored sql::SQLString query; sql::SQLString escapedSchemaName = connection->escapeString(schemaName); sql::SQLString escapedObjectName = connection->escapeString(objectName); sql::SQLString escapedContextTableName = connection->escapeString(contextTableName); sql::SQLString schemata_where_clause; sql::SQLString tables_where_clause; sql::SQLString views_where_clause; sql::SQLString routines_where_clause; sql::SQLString triggers_where_clause; const sql::SQLString schemata_select_items("'schema' AS 'OBJECT_TYPE', CATALOG_NAME as 'CATALOG', SCHEMA_NAME as 'SCHEMA', SCHEMA_NAME as 'NAME'"); const sql::SQLString tables_select_items("'table' AS 'OBJECT_TYPE', TABLE_CATALOG as 'CATALOG', TABLE_SCHEMA as 'SCHEMA', TABLE_NAME as 'NAME'"); const sql::SQLString views_select_items("'view' AS 'OBJECT_TYPE', TABLE_CATALOG as 'CATALOG', TABLE_SCHEMA as 'SCHEMA', TABLE_NAME as 'NAME'"); const sql::SQLString routines_select_items("ROUTINE_TYPE AS 'OBJECT_TYPE', ROUTINE_CATALOG as 'CATALOG', ROUTINE_SCHEMA as 'SCHEMA', ROUTINE_NAME as 'NAME'"); const sql::SQLString triggers_select_items("'trigger' AS 'OBJECT_TYPE', TRIGGER_CATALOG as 'CATALOG', TRIGGER_SCHEMA as 'SCHEMA', TRIGGER_NAME as 'NAME'"); const sql::SQLString schema_ddl_column("Create Database"); const sql::SQLString table_ddl_column("Create Table"); const sql::SQLString view_ddl_column("Create View"); const sql::SQLString procedure_ddl_column("Create Procedure"); const sql::SQLString function_ddl_column("Create Function"); const sql::SQLString trigger_ddl_column("SQL Original Statement"); if (escapedSchemaName.length() > 0) { schemata_where_clause.append(" WHERE schema_name = '").append(escapedSchemaName).append("' "); tables_where_clause.append(" WHERE table_type<>'VIEW' AND table_schema = '").append(escapedSchemaName).append("' "); views_where_clause.append(" WHERE table_schema = '").append(escapedSchemaName).append("' "); routines_where_clause.append(" WHERE routine_schema = '").append(escapedSchemaName).append("' "); triggers_where_clause.append(" WHERE trigger_schema = '").append(escapedSchemaName).append("' "); } if (escapedObjectName.length() > 0) { std::string predicate_mediator= (escapedSchemaName.length() > 0) ? " AND " : " WHERE "; predicate_mediator += "'" + escapedObjectName + "'="; schemata_where_clause += predicate_mediator + "SCHEMA_NAME"; tables_where_clause += predicate_mediator + "TABLE_NAME"; views_where_clause += predicate_mediator + "TABLE_NAME"; routines_where_clause += predicate_mediator + "ROUTINE_NAME"; triggers_where_clause += predicate_mediator + "TRIGGER_NAME"; } if (escapedContextTableName.length() > 0) { std::string predicate_mediator= ((escapedSchemaName.length() > 0) || (escapedObjectName.length() > 0)) ? " AND " : " WHERE "; predicate_mediator += "'" + escapedContextTableName + "'="; triggers_where_clause += predicate_mediator + "EVENT_OBJECT_TABLE"; } if (objectType.length() == 0) { query.append("SELECT ").append(tables_select_items) .append(" FROM information_schema.tables ").append(tables_where_clause) .append("UNION SELECT ").append(views_select_items) .append(" FROM information_schema.views ").append(views_where_clause) .append("UNION SELECT ").append(routines_select_items) .append(" FROM information_schema.routines ").append(routines_where_clause) .append("UNION SELECT ").append(triggers_select_items) .append(" FROM information_schema.triggers ").append(triggers_where_clause) ; } else { if (objectType.compare("schema") == 0) { query.append("SELECT ") .append(schemata_select_items) .append(" FROM information_schema.schemata") .append(schemata_where_clause); } else if (objectType.compare("table") == 0) { query.append("SELECT ") .append(tables_select_items) .append(" FROM information_schema.tables") .append(tables_where_clause); } else if (objectType.compare("view") == 0) { query.append("SELECT ") .append(views_select_items) .append(" FROM information_schema.views") .append(views_where_clause); } else if (objectType.compare("routine") == 0) { query.append("SELECT ") .append(routines_select_items) .append(" FROM information_schema.routines") .append(routines_where_clause); } else if (objectType.compare("trigger") == 0) { query.append("SELECT ") .append(triggers_select_items) .append(" FROM information_schema.triggers") .append(triggers_where_clause); } else { throw sql::InvalidArgumentException("MySQLMetadata::getSchemaObjects: invalid 'objectType'"); } } boost::scoped_ptr< sql::ResultSet > native_rs(stmt->executeQuery(query)); int objtype_field_index = native_rs->findColumn("OBJECT_TYPE"); int catalog_field_index = native_rs->findColumn("CATALOG"); int schema_field_index = native_rs->findColumn("SCHEMA"); int name_field_index = native_rs->findColumn("NAME"); std::map< sql::SQLString, sql::SQLString > trigger_name_map; std::map< sql::SQLString, sql::SQLString > trigger_ddl_map; // if we fetch triggers, then build DDL for them if ((objectType.compare("trigger") == 0) || !objectType.length()) { sql::SQLString trigger_ddl_query("SELECT "); trigger_ddl_query .append(triggers_select_items) .append(", EVENT_MANIPULATION, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, ACTION_ORDER, " " ACTION_CONDITION, ACTION_STATEMENT, ACTION_ORIENTATION, ACTION_TIMING, DEFINER" " FROM information_schema.triggers ") .append(triggers_where_clause); boost::scoped_ptr< sql::ResultSet > trigger_ddl_rs(stmt->executeQuery(trigger_ddl_query)); // trigger specific fields: exclusion from the rule - 'show create trigger' is not supported by versions below 5.1.21 // reproducing ddl based on metadata int event_manipulation_index = trigger_ddl_rs->findColumn("EVENT_MANIPULATION"); int event_object_schema_index = trigger_ddl_rs->findColumn("EVENT_OBJECT_SCHEMA"); int event_object_table_index = trigger_ddl_rs->findColumn("EVENT_OBJECT_TABLE"); int action_statement_index = trigger_ddl_rs->findColumn("ACTION_STATEMENT"); int action_timing_index = trigger_ddl_rs->findColumn("ACTION_TIMING"); int definer_index = trigger_ddl_rs->findColumn("DEFINER"); while (trigger_ddl_rs->next()) { sql::SQLString trigger_ddl; // quote definer, which is stored as unquoted string std::string quoted_definer; { quoted_definer = trigger_ddl_rs->getString(definer_index); const char * quot_sym = "`\0"; size_t i = quoted_definer.find('@'); if (std::string::npos != i) { quoted_definer.reserve(quoted_definer.length()+4); quoted_definer.insert(i+1, quot_sym); quoted_definer.insert(i, quot_sym); } quoted_definer.insert(0, quot_sym); quoted_definer.push_back(quot_sym[0]); } sql::SQLString key; key.append("`").append(trigger_ddl_rs->getString("schema")) .append("`.`").append(trigger_ddl_rs->getString("name")).append("`"); { trigger_ddl .append("CREATE\nDEFINER=").append(quoted_definer) .append("\nTRIGGER ").append("`") .append(trigger_ddl_rs->getString("schema")).append("`.`").append(trigger_ddl_rs->getString("name")).append("`") .append("\n").append(trigger_ddl_rs->getString(action_timing_index)) .append(" ").append(trigger_ddl_rs->getString(event_manipulation_index)) .append(" ON `").append(trigger_ddl_rs->getString(event_object_schema_index)) .append("`.`").append(trigger_ddl_rs->getString(event_object_table_index)).append("`") .append("\nFOR EACH ROW\n") .append(trigger_ddl_rs->getString(action_statement_index)) .append("\n"); trigger_ddl_map[key] = trigger_ddl; } { sql::SQLString trigger_name; trigger_name .append(trigger_ddl_rs->getString(event_object_table_index)) .append(".") .append(trigger_ddl_rs->getString("name")); trigger_name_map[key] = trigger_name; } } } std::list< sql::SQLString > rs_field_data; rs_field_data.push_back("OBJECT_TYPE"); rs_field_data.push_back("CATALOG"); rs_field_data.push_back("SCHEMA"); rs_field_data.push_back("NAME"); rs_field_data.push_back("DDL"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); while (native_rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; sql::SQLString obj_type(native_rs->getString(objtype_field_index)); sql::SQLString schema(native_rs->getString(schema_field_index)); sql::SQLString name(native_rs->getString(name_field_index)); if ((obj_type.compare("PROCEDURE") == 0) || (obj_type.compare("FUNCTION") == 0)) { rs_data_row.push_back("routine"); } else { rs_data_row.push_back(obj_type); } rs_data_row.push_back(native_rs->getString(catalog_field_index)); rs_data_row.push_back(schema); if (obj_type.compare("trigger") == 0) { sql::SQLString key; key.append("`").append(schema).append("`.`").append(name).append("`"); rs_data_row.push_back(trigger_name_map[key]); } else { rs_data_row.push_back(name); } sql::SQLString ddl_query; sql::SQLString ddl_column; if (obj_type.compare("schema") == 0) { ddl_column = schema_ddl_column; ddl_query.append("SHOW CREATE SCHEMA `").append(name).append("`"); } else if (obj_type.compare("table") == 0) { ddl_column = table_ddl_column; ddl_query.append("SHOW CREATE TABLE `") .append(schema).append("`.`") .append(name).append("`"); } else if (obj_type.compare("view") == 0) { ddl_column = view_ddl_column; ddl_query.append("SHOW CREATE VIEW `") .append(schema).append("`.`") .append(name).append("`"); } else if (obj_type.compare("PROCEDURE") == 0) { ddl_column = procedure_ddl_column; ddl_query.append("SHOW CREATE PROCEDURE `") .append(schema).append("`.`") .append(name).append("`"); } else if (obj_type.compare("FUNCTION") == 0) { ddl_column = function_ddl_column; ddl_query.append("SHOW CREATE FUNCTION `") .append(schema).append("`.`") .append(name).append("`"); } else if (obj_type.compare("trigger") == 0) { /* ddl_column= trigger_ddl_column; ddl_query.append("SHOW CREATE TRIGGER `") .append(schema).append("`.`") .append(name).append("`"); */ } else { throw sql::InvalidArgumentException("MySQL_DatabaseMetaData::getSchemaObjects: invalid OBJECT_TYPE returned from query"); } if (includingDdl) { // due to bugs in server code some queries can fail. // here we want to gather as much info as possible try { sql::SQLString ddl; if (obj_type.compare("trigger") == 0) { //ddl // .append("CREATE\nDEFINER=").append(trigger_ddl_rs->getString(definer_index)) // .append("\nTRIGGER ").append("`") // .append(schema).append("`.`").append(name).append("`") // .append("\n").append(trigger_ddl_rs->getString(action_timing_index)) // .append(" ").append(trigger_ddl_rs->getString(event_manipulation_index)) // .append(" ON `").append(trigger_ddl_rs->getString(event_object_schema_index)) // .append("`.`").append(trigger_ddl_rs->getString(event_object_table_index)).append("`") // .append("\nFOR EACH ROW\n") // .append(trigger_ddl_rs->getString(action_statement_index)) // .append("\n"); sql::SQLString key; key.append("`").append(schema).append("`.`").append(name).append("`"); std::map< sql::SQLString, sql::SQLString >::const_iterator it = trigger_ddl_map.find(key); if (it != trigger_ddl_map.end()) { ddl.append(it->second); } } else { boost::scoped_ptr< sql::ResultSet > sql_rs(stmt->executeQuery(ddl_query)); sql_rs->next(); // this is a hack for views listed as tables int colIdx = sql_rs->findColumn(ddl_column); if ((colIdx == 0) && (obj_type.compare("table") == 0)) colIdx = sql_rs->findColumn(view_ddl_column); ddl = sql_rs->getString(colIdx); } rs_data_row.push_back(ddl); } catch (SQLException) { rs_data_row.push_back(""); } } else { rs_data_row.push_back(""); } rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemaObjectTypes() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSchemaObjectTypes() { CPP_ENTER("MySQL_ConnectionMetaData::getSchemaObjectTypes"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("OBJECT_TYPE"); { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("table"); rs_data->push_back(rs_data_row); } { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("view"); rs_data->push_back(rs_data_row); } { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("routine"); rs_data->push_back(rs_data_row); } { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("trigger"); rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::allProceduresAreCallable() -I- */ bool MySQL_ConnectionMetaData::allProceduresAreCallable() { CPP_ENTER("MySQL_ConnectionMetaData::allProceduresAreCallable"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::allTablesAreSelectable() -I- */ bool MySQL_ConnectionMetaData::allTablesAreSelectable() { CPP_ENTER("MySQL_ConnectionMetaData::allTablesAreSelectable"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::dataDefinitionCausesTransactionCommit() -I- */ bool MySQL_ConnectionMetaData::dataDefinitionCausesTransactionCommit() { CPP_ENTER("MySQL_ConnectionMetaData::dataDefinitionCausesTransactionCommit"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::dataDefinitionIgnoredInTransactions() -I- */ bool MySQL_ConnectionMetaData::dataDefinitionIgnoredInTransactions() { CPP_ENTER("MySQL_ConnectionMetaData::dataDefinitionIgnoredInTransactions"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::deletesAreDetected() -I- */ bool MySQL_ConnectionMetaData::deletesAreDetected(int /*type*/) { CPP_ENTER("MySQL_ConnectionMetaData::deletesAreDetected"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::doesMaxRowSizeIncludeBlobs() -I- */ bool MySQL_ConnectionMetaData::doesMaxRowSizeIncludeBlobs() { CPP_ENTER("MySQL_ConnectionMetaData::doesMaxRowSizeIncludeBlobs"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getAttributes() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getAttributes(const sql::SQLString& /*catalog*/, const sql::SQLString& /*schemaPattern*/, const sql::SQLString& /*typeNamePattern*/, const sql::SQLString& /*attributeNamePattern*/) { CPP_ENTER("MySQL_ConnectionMetaData::getAttributes"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TYPE_CAT"); rs_field_data.push_back("TYPE_SCHEM"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("ATTR_NAME"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("ATTR_TYPE_NAME"); rs_field_data.push_back("ATTR_SIZE"); rs_field_data.push_back("DECIMAL_DIGITS"); rs_field_data.push_back("NUM_PREC_RADIX"); rs_field_data.push_back("NULLABLE"); rs_field_data.push_back("REMARKS"); rs_field_data.push_back("ATTR_DEF"); rs_field_data.push_back("SQL_DATA_TYPE"); rs_field_data.push_back("SQL_DATETIME_SUB"); rs_field_data.push_back("CHAR_OCTET_LENGTH"); rs_field_data.push_back("ORDINAL_POSITION"); rs_field_data.push_back("IS_NULLABLE"); rs_field_data.push_back("SCOPE_CATALOG"); rs_field_data.push_back("SCOPE_SCHEMA"); rs_field_data.push_back("SCOPE_TABLE"); rs_field_data.push_back("SOURCE_DATA_TYPE"); MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getBestRowIdentifier() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int /* scope */, bool /* nullable */) { CPP_ENTER("MySQL_ConnectionMetaData::getBestRowIdentifier"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("SCOPE"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("COLUMN_SIZE"); rs_field_data.push_back("BUFFER_LENGTH"); rs_field_data.push_back("DECIMAL_DIGITS"); rs_field_data.push_back("PSEUDO_COLUMN"); boost::scoped_ptr< sql::ResultSet > rs(getPrimaryKeys(catalog, schema, table)); if (!rs->rowsCount()) rs.reset(getUniqueNonNullableKeys(catalog, schema, table)); while (rs->next()) { sql::SQLString columnNamePattern(rs->getString(4)); boost::scoped_ptr< sql::ResultSet > rsCols(getColumns(catalog, schema, table, columnNamePattern)); if (rsCols->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back((int64_t) DatabaseMetaData::bestRowSession); // SCOPE rs_data_row.push_back(rs->getString(4)); // COLUMN_NAME rs_data_row.push_back(rsCols->getString(5)); // DATA_TYPE rs_data_row.push_back(rsCols->getString(6)); // TYPE_NAME rs_data_row.push_back(rsCols->getString(7)); // COLUMN_SIZE rs_data_row.push_back(rsCols->getString(8)); // BUFFER_LENGTH rs_data_row.push_back(rsCols->getString(9)); // DECIMAL_DIGITS rs_data_row.push_back((int64_t) DatabaseMetaData::bestRowNotPseudo); // PSEUDO_COLUMN rs_data->push_back(rs_data_row); } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getCatalogs() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getCatalogs() { boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getCatalogSeparator() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getCatalogSeparator() { CPP_ENTER("MySQL_ConnectionMetaData::getCatalogSeparator"); static const sql::SQLString separator(""); return separator; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getCatalogTerm() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getCatalogTerm() { CPP_ENTER("MySQL_ConnectionMetaData::getCatalogTerm"); static const sql::SQLString term("n/a"); return term; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getColumnPrivileges() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getColumnPrivileges(const sql::SQLString& /*catalog*/, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) { CPP_ENTER("MySQL_ConnectionMetaData::getColumnPrivileges"); sql::SQLString escapedSchema = connection->escapeString(schema); sql::SQLString escapedTableName = connection->escapeString(table); sql::SQLString escapedColumnNamePattern = connection->escapeString(columnNamePattern); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("GRANTOR"); rs_field_data.push_back("GRANTEE"); rs_field_data.push_back("PRIVILEGE"); rs_field_data.push_back("IS_GRANTABLE"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); /* I_S seems currently (20080220) not to work */ if (use_info_schema && server_version > 69999) { #if A0 sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME," "COLUMN_NAME, NULL AS GRANTOR, GRANTEE, PRIVILEGE_TYPE AS PRIVILEGE, IS_GRANTABLE\n" "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES\n" "WHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME=? AND COLUMN_NAME LIKE ?\n" "ORDER BY COLUMN_NAME, PRIVILEGE_TYPE"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, escapedSchema); pStmt->setString(2, escapedTableName); pStmt->setString(3, escapedColumnNamePattern); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // COLUMN_NAME rs_data_row.push_back(rs->getString(5)); // KEY_SEQ rs_data_row.push_back(rs->getString(6)); // PK_NAME rs_data->push_back(rs_data_row); } #endif } else { size_t idx; sql::SQLString query("SHOW FULL COLUMNS FROM `"); query.append(schema).append("`.`").append(table).append("` LIKE '").append(escapedColumnNamePattern).append("'"); boost::scoped_ptr< sql::ResultSet > res(NULL); try { res.reset(stmt->executeQuery(query)); } catch (SQLException &) { // schema and/or table doesn't exist. return empty set // do nothing here } while (res.get() && res->next()) { size_t pos = 0; sql::SQLString privs = res->getString(8); do { MySQL_ArtResultSet::row_t rs_data_row; sql::SQLString privToken; while (privs[pos] == ' ') ++pos; // Eat the whitespace idx = privs.find(",", pos); if (idx != sql::SQLString::npos) { privToken = privs.substr(pos, idx - pos); pos = idx + 1; /* skip ',' */ } else { privToken = privs.substr(pos, privs.length() - pos); } rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(schema); // TABLE_SCHEM rs_data_row.push_back(table); // TABLE_NAME rs_data_row.push_back(res->getString(1)); // COLUMN_NAME rs_data_row.push_back(""); // GRANTOR rs_data_row.push_back(getUserName()); // GRANTEE rs_data_row.push_back(privToken); // PRIVILEGE rs_data_row.push_back(""); // IS_GRANTABLE rs_data->push_back(rs_data_row); } while (idx != sql::SQLString::npos); } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getColumns() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getColumns(const sql::SQLString& /*catalog*/, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) { CPP_ENTER("MySQL_ConnectionMetaData::getColumns"); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); sql::SQLString escapedTableNamePattern = connection->escapeString(tableNamePattern); sql::SQLString escapedColumnNamePattern = connection->escapeString(columnNamePattern); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("COLUMN_SIZE"); rs_field_data.push_back("BUFFER_LENGTH"); rs_field_data.push_back("DECIMAL_DIGITS"); rs_field_data.push_back("NUM_PREC_RADIX"); rs_field_data.push_back("NULLABLE"); rs_field_data.push_back("REMARKS"); rs_field_data.push_back("COLUMN_DEF"); rs_field_data.push_back("SQL_DATA_TYPE"); rs_field_data.push_back("SQL_DATETIME_SUB"); rs_field_data.push_back("CHAR_OCTET_LENGTH"); rs_field_data.push_back("ORDINAL_POSITION"); rs_field_data.push_back("IS_NULLABLE"); /* The following are not known by SDBC */ rs_field_data.push_back("SCOPE_CATALOG"); rs_field_data.push_back("SCOPE_SCHEMA"); rs_field_data.push_back("SCOPE_TABLE"); rs_field_data.push_back("SOURCE_DATA_TYPE"); rs_field_data.push_back("IS_AUTOINCREMENT"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); if (use_info_schema && server_version > 50020) { char buf[5]; sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE," "CASE " "WHEN LOCATE('unsigned', COLUMN_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN " " CASE" " WHEN LOCATE('zerofill', COLUMN_TYPE) != 0 AND LOCATE('zerofill', DATA_TYPE) = 0 THEN CONCAT(UCASE(DATA_TYPE), ' UNSIGNED ZEROFILL')" " ELSE CONCAT(UCASE(DATA_TYPE), ' UNSIGNED')" " END " // "ELSE" // " CASE" // " WHEN LCASE(DATA_TYPE)='set' THEN 'VARCHAR'" // " WHEN LCASE(DATA_TYPE)='enum' THEN 'VARCHAR'" // " WHEN LCASE(DATA_TYPE)='year' THEN 'YEAR'" " ELSE UCASE(DATA_TYPE)" // " END " "END AS TYPE_NAME," "CASE " "WHEN LCASE(DATA_TYPE)='year' THEN SUBSTRING(COLUMN_TYPE, 6, 1) -- 'year('=5\n" "WHEN LCASE(DATA_TYPE)='date' THEN 10 " "WHEN LCASE(DATA_TYPE)='time' THEN 8 " "WHEN LCASE(DATA_TYPE)='datetime' THEN 19 " "WHEN LCASE(DATA_TYPE)='timestamp' THEN 19 " "WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN NUMERIC_PRECISION " "ELSE CHARACTER_MAXIMUM_LENGTH END AS COLUMN_SIZE, " "'' AS BUFFER_LENGTH," "NUMERIC_SCALE AS DECIMAL_DIGITS," "10 AS NUM_PREC_RADIX," "CASE WHEN IS_NULLABLE='NO' THEN "); query.append(my_i_to_a(buf, sizeof(buf) - 1, columnNoNulls)); query.append(" ELSE CASE WHEN IS_NULLABLE='YES' THEN "); query.append(my_i_to_a(buf, sizeof(buf) - 1, columnNullable)); query.append(" ELSE "); query.append(my_i_to_a(buf, sizeof(buf) - 1, columnNullableUnknown)); query.append(" END END AS NULLABLE," "COLUMN_COMMENT AS REMARKS," "COLUMN_DEFAULT AS COLUMN_DEF," "0 AS SQL_DATA_TYPE," "0 AS SQL_DATETIME_SUB," "CHARACTER_OCTET_LENGTH," "ORDINAL_POSITION," "IS_NULLABLE," "NULL AS SCOPE_CATALOG," "NULL AS SCOPE_SCHEMA," "NULL AS SCOPE_TABLE," "NULL AS SOURCE_DATA_TYPE," "IF (EXTRA LIKE '%auto_increment%','YES','NO') AS IS_AUTOINCREMENT " "FROM INFORMATION_SCHEMA.COLUMNS WHERE "); if (schemaPattern.length()) { query.append(" TABLE_SCHEMA LIKE ? "); } else { query.append(" TABLE_SCHEMA = DATABASE() "); } query.append("AND TABLE_NAME LIKE ? AND COLUMN_NAME LIKE ? " "ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); if (schemaPattern.length()) { pStmt->setString(1, escapedSchemaPattern); pStmt->setString(2, escapedTableNamePattern); pStmt->setString(3, escapedColumnNamePattern); } else { pStmt->setString(1, escapedTableNamePattern); pStmt->setString(2, escapedColumnNamePattern); } boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // COLUMN_NAME rs_data_row.push_back((int64_t) sql::mysql::util::mysql_string_type_to_datatype(rs->getString(5))); // DATA_TYPE rs_data_row.push_back(rs->getString(6)); // TYPE_NAME rs_data_row.push_back(rs->getInt64(7)); // COLUMN_SIZE rs_data_row.push_back(rs->getInt64(8)); // BUFFER_LENGTH rs_data_row.push_back(rs->getInt64(9)); // DECIMAL_DIGITS rs_data_row.push_back(rs->getInt64(10)); // NUM_PREC_RADIX rs_data_row.push_back(rs->getString(11)); // NULLABLE rs_data_row.push_back(rs->getString(12)); // REMARKS rs_data_row.push_back(rs->getString(13)); // COLUMN_DEFAULT rs_data_row.push_back(rs->getString(14)); // SQL_DATA_TYPE rs_data_row.push_back(rs->getString(15)); // SQL_DATETIME_SUB rs_data_row.push_back(rs->getString(16)); // CHAR_OCTET_LENGTH rs_data_row.push_back(rs->getString(17)); // ORDINAL_POSITION rs_data_row.push_back(rs->getString(18)); // IS_NULLABLE /* The following are not currently used by C/OOO*/ rs_data_row.push_back(rs->getString(19)); // SCOPE_CATALOG rs_data_row.push_back(rs->getString(20)); // SCOPE_SCHEMA rs_data_row.push_back(rs->getString(21)); // SCOPE_TABLE rs_data_row.push_back(rs->getString(22)); // SOURCE_DATA_TYPE rs_data_row.push_back(rs->getString(23)); // IS_AUTOINCREMENT rs_data->push_back(rs_data_row); } } else { /* get schemata */ sql::SQLString query1("SHOW DATABASES LIKE '"); query1.append(escapedSchemaPattern).append("'"); boost::scoped_ptr< sql::ResultSet > rs1(stmt->executeQuery(query1)); while (rs1->next()) { sql::SQLString current_schema(rs1->getString(1)); sql::SQLString query2("SHOW TABLES FROM `"); query2.append(current_schema).append("` LIKE '").append(escapedTableNamePattern).append("'"); /* stmt is storing results. otherwise this won't work anyway */ boost::scoped_ptr< sql::ResultSet > rs2(stmt->executeQuery(query2)); while (rs2->next()) { sql::SQLString current_table(rs2->getString(1)); sql::SQLString query3("SELECT * FROM `"); query3.append(current_schema).append("`.`").append(current_table).append("` WHERE 0=1"); boost::scoped_ptr< sql::ResultSet > rs3(stmt->executeQuery(query3)); sql::ResultSetMetaData * rs3_meta = rs3->getMetaData(); sql::SQLString query4("SHOW FULL COLUMNS FROM `"); query4.append(current_schema).append("`.`").append(current_table).append("` LIKE '").append(escapedColumnNamePattern).append("'"); boost::scoped_ptr< sql::ResultSet > rs4(stmt->executeQuery(query4)); while (rs4->next()) { for (unsigned int i = 1; i <= rs3_meta->getColumnCount(); ++i) { /* `SELECT * FROM XYZ WHERE 0=1` will return metadata about all columns but `columnNamePattern` could be set. So, we can have different number of rows/columns in the result sets which doesn't correspond. */ if (rs3_meta->getColumnName(i) == rs4->getString(1)) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(current_schema); // TABLE_SCHEM rs_data_row.push_back(current_table); // TABLE_NAME rs_data_row.push_back(rs4->getString(1)); // COLUMN_NAME rs_data_row.push_back((int64_t) rs3_meta->getColumnType(i)); // DATA_TYPE rs_data_row.push_back(rs3_meta->getColumnTypeName(i)); // TYPE_NAME rs_data_row.push_back((int64_t) rs3_meta->getColumnDisplaySize(i)); // COLUMN_SIZE rs_data_row.push_back(""); // BUFFER_LENGTH rs_data_row.push_back((int64_t) rs3_meta->getScale(i)); // DECIMAL_DIGITS rs_data_row.push_back("10"); // NUM_PREC_RADIX rs_data_row.push_back((int64_t) rs3_meta->isNullable(i)); // Is_nullable rs_data_row.push_back(rs4->getString(9)); // REMARKS rs_data_row.push_back(rs4->getString(6)); // COLUMN_DEFAULT rs_data_row.push_back(""); // SQL_DATA_TYPE - unused rs_data_row.push_back(""); // SQL_DATETIME_SUB - unused rs_data_row.push_back((int64_t) rs3_meta->getColumnDisplaySize(i)); // CHAR_OCTET_LENGTH rs_data_row.push_back((int64_t) i); // ORDINAL_POSITION rs_data_row.push_back(rs3_meta->isNullable(i)? "YES":"NO"); // IS_NULLABLE rs_data_row.push_back(""); // SCOPE_CATALOG - unused rs_data_row.push_back(""); // SCOPE_SCHEMA - unused rs_data_row.push_back(""); // SCOPE_TABLE - unused rs_data_row.push_back(""); // SOURCE_DATA_TYPE - unused rs_data_row.push_back(""); // IS_AUTOINCREMENT - unused rs_data->push_back(rs_data_row); /* don't iterate any more, we have found our column */ break; } } } } } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getConnection() -I- */ Connection * MySQL_ConnectionMetaData::getConnection() { CPP_ENTER("MySQL_ConnectionMetaData::getConnection"); return this->connection; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getCrossReference() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog , const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) { CPP_ENTER("MySQL_ConnectionMetaData::getCrossReference"); CPP_INFO_FMT("p_catalog=%s f_catalog=%s p_schema=%s f_schema=%s p_table=%s f_table=%s", primaryCatalog.c_str(), foreignCatalog.c_str(), primarySchema.c_str(), foreignSchema.c_str(), primaryTable.c_str(), foreignTable.c_str()); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("PKTABLE_CAT"); rs_field_data.push_back("PKTABLE_SCHEM"); rs_field_data.push_back("PKTABLE_NAME"); rs_field_data.push_back("PKCOLUMN_NAME"); rs_field_data.push_back("FKTABLE_CAT"); rs_field_data.push_back("FKTABLE_SCHEM"); rs_field_data.push_back("FKTABLE_NAME"); rs_field_data.push_back("FKCOLUMN_NAME"); rs_field_data.push_back("KEY_SEQ"); rs_field_data.push_back("UPDATE_RULE"); rs_field_data.push_back("DELETE_RULE"); rs_field_data.push_back("FK_NAME"); rs_field_data.push_back("PK_NAME"); rs_field_data.push_back("DEFERRABILITY"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); /* Not sure which version, let it not be 5.1.0, just something above which is anyway not used anymore */ if (use_info_schema && server_version >= 50110) { /* This just doesn't work */ /* currently this doesn't work - we have to wait for implementation of REFERENTIAL_CONSTRAINTS */ char buf[10]; my_i_to_a(buf, sizeof(buf) - 1, importedKeyCascade); sql::SQLString importedKeyCascadeStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeySetNull); sql::SQLString importedKeySetNullStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeySetDefault); sql::SQLString importedKeySetDefaultStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyRestrict); sql::SQLString importedKeyRestrictStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyNoAction); sql::SQLString importedKeyNoActionStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyNotDeferrable); sql::SQLString importedKeyNotDeferrableStr(buf); sql::SQLString UpdateRuleClause; UpdateRuleClause.append("CASE WHEN R.UPDATE_RULE='CASCADE' THEN ").append(importedKeyCascadeStr). append(" WHEN R.UPDATE_RULE='SET NULL' THEN ").append(importedKeySetNullStr). append(" WHEN R.UPDATE_RULE='SET DEFAULT' THEN ").append(importedKeySetDefaultStr). append(" WHEN R.UPDATE_RULE='RESTRICT' THEN ").append(importedKeyRestrictStr). append(" WHEN R.UPDATE_RULE='NO ACTION' THEN ").append(importedKeyNoActionStr). append(" ELSE ").append(importedKeyNoActionStr).append(" END "); sql::SQLString DeleteRuleClause; DeleteRuleClause.append("CASE WHEN R.DELETE_RULE='CASCADE' THEN ").append(importedKeyCascadeStr). append(" WHEN R.DELETE_RULE='SET NULL' THEN ").append(importedKeySetNullStr). append(" WHEN R.DELETE_RULE='SET DEFAULT' THEN ").append(importedKeySetDefaultStr). append(" WHEN R.DELETE_RULE='RESTRICT' THEN ").append(importedKeyRestrictStr). append(" WHEN R.DELETE_RULE='NO ACTION' THEN ").append(importedKeyNoActionStr). append(" ELSE ").append(importedKeyNoActionStr).append(" END "); sql::SQLString OptionalRefConstraintJoinStr( "JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R ON " "(R.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND R.TABLE_NAME = B.TABLE_NAME AND R.CONSTRAINT_SCHEMA = B.TABLE_SCHEMA) "); sql::SQLString query("SELECT \n"); query.append("A.TABLE_CATALOG AS PKTABLE_CAT, A.REFERENCED_TABLE_SCHEMA AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME," "A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_CATALOG AS FKTABLE_CAT, A.TABLE_SCHEMA AS FKTABLE_SCHEM," "A.TABLE_NAME AS FKTABLE_NAME, A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ,"); query.append(UpdateRuleClause); query.append(" AS UPDATE_RULE,"); query.append(DeleteRuleClause); query.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME," "(SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = REFERENCED_TABLE_SCHEMA AND" " TABLE_NAME = A.REFERENCED_TABLE_NAME AND CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1) AS PK_NAME,"); query.append(importedKeyNotDeferrableStr); query.append(" AS DEFERRABILITY FROM\nINFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B\n" "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME)\n"); query.append(OptionalRefConstraintJoinStr); query.append("\nWHERE B.CONSTRAINT_TYPE = 'FOREIGN KEY' AND A.REFERENCED_TABLE_SCHEMA LIKE ? AND A.REFERENCED_TABLE_NAME=?\n" "AND A.TABLE_SCHEMA LIKE ? AND A.TABLE_NAME=?\nORDER BY A.TABLE_SCHEMA, A.TABLE_NAME, A.ORDINAL_POSITION"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, primarySchema); pStmt->setString(2, primaryTable); pStmt->setString(3, foreignSchema); pStmt->setString(4, foreignTable); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // PKTABLE_CAT rs_data_row.push_back(rs->getString(2)); // PKTABLE_SCHEMA rs_data_row.push_back(rs->getString(3)); // PKTABLE_NAME rs_data_row.push_back(rs->getString(4)); // PKCOLUMN_NAME rs_data_row.push_back(rs->getString(5)); // FKTABLE_CAT rs_data_row.push_back(rs->getString(6)); // FKTABLE_SCHEMA rs_data_row.push_back(rs->getString(7)); // FKTABLE_NAME rs_data_row.push_back(rs->getString(8)); // FKCOLUMN_NAME rs_data_row.push_back(rs->getString(9)); // KEY_SEQ rs_data_row.push_back(rs->getString(10)); // UPDATE_RULE rs_data_row.push_back(rs->getString(11)); // DELETE_RULE rs_data_row.push_back(rs->getString(12)); // FK_NAME rs_data_row.push_back(rs->getString(13)); // PK_NAME rs_data_row.push_back(rs->getString(14)); // DEFERRABILITY rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } else { throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::getCrossReference"); } return NULL; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDatabaseMajorVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getDatabaseMajorVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDatabaseMajorVersion"); return server_version / 10000; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDatabaseMinorVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getDatabaseMinorVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDatabaseMinorVersion"); return (server_version % 10000) / 100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDatabasePatchVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getDatabasePatchVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDatabasePatchVersion"); return server_version % 100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDatabaseProductName() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getDatabaseProductName() { CPP_ENTER("MySQL_ConnectionMetaData::getDatabaseProductName"); static const sql::SQLString product_name("MySQL"); return product_name; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDatabaseProductVersion() -I- */ SQLString MySQL_ConnectionMetaData::getDatabaseProductVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDatabaseProductVersion"); return proxy->get_server_info(); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDefaultTransactionIsolation() -I- */ int MySQL_ConnectionMetaData::getDefaultTransactionIsolation() { CPP_ENTER("MySQL_ConnectionMetaData::getDefaultTransactionIsolation"); if (server_version >= 32336) { return TRANSACTION_READ_COMMITTED; } return TRANSACTION_NONE; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDriverMajorVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getDriverMajorVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDriverMajorVersion"); return MYCPPCONN_MAJOR_VERSION; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDriverMinorVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getDriverMinorVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDriverMinorVersion"); return MYCPPCONN_MINOR_VERSION; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDriverPatchVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getDriverPatchVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDriverPatchVersion"); return MYCPPCONN_PATCH_VERSION; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDriverVersion() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getDriverVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getDriverVersion"); static const sql::SQLString version(MYCPPCONN_STRVERSION); return version; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getDriverName() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getDriverName() { CPP_ENTER("MySQL_ConnectionMetaData::getDriverName"); static const sql::SQLString product_version("MySQL Connector/C++"); return product_version; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getExportedKeys() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) { CPP_ENTER("MySQL_ConnectionMetaData::getExportedKeys"); CPP_INFO_FMT("catalog=%s schema=%s table=%s", catalog.c_str(), schema.c_str(), table.c_str()); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("PKTABLE_CAT"); rs_field_data.push_back("PKTABLE_SCHEM"); rs_field_data.push_back("PKTABLE_NAME"); rs_field_data.push_back("PKCOLUMN_NAME"); rs_field_data.push_back("FKTABLE_CAT"); rs_field_data.push_back("FKTABLE_SCHEM"); rs_field_data.push_back("FKTABLE_NAME"); rs_field_data.push_back("FKCOLUMN_NAME"); rs_field_data.push_back("KEY_SEQ"); rs_field_data.push_back("UPDATE_RULE"); rs_field_data.push_back("DELETE_RULE"); rs_field_data.push_back("FK_NAME"); rs_field_data.push_back("PK_NAME"); rs_field_data.push_back("DEFERRABILITY"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); /* Not sure which version, let it not be 5.1.0, just something above which is anyway not used anymore */ if (use_info_schema && server_version >= 50110) { /* This just doesn't work */ /* currently this doesn't work - we have to wait for implementation of REFERENTIAL_CONSTRAINTS */ char buf[10]; my_i_to_a(buf, sizeof(buf) - 1, importedKeyCascade); sql::SQLString importedKeyCascadeStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeySetNull); sql::SQLString importedKeySetNullStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeySetDefault); sql::SQLString importedKeySetDefaultStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyRestrict); sql::SQLString importedKeyRestrictStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyNoAction); sql::SQLString importedKeyNoActionStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyNotDeferrable); sql::SQLString importedKeyNotDeferrableStr(buf); sql::SQLString UpdateRuleClause; UpdateRuleClause.append("CASE WHEN R.UPDATE_RULE='CASCADE' THEN ").append(importedKeyCascadeStr). append(" WHEN R.UPDATE_RULE='SET NULL' THEN ").append(importedKeySetNullStr). append(" WHEN R.UPDATE_RULE='SET DEFAULT' THEN ").append(importedKeySetDefaultStr). append(" WHEN R.UPDATE_RULE='RESTRICT' THEN ").append(importedKeyRestrictStr). append(" WHEN R.UPDATE_RULE='NO ACTION' THEN ").append(importedKeyNoActionStr). append(" ELSE ").append(importedKeyNoActionStr).append(" END "); sql::SQLString DeleteRuleClause; DeleteRuleClause.append("CASE WHEN R.DELETE_RULE='CASCADE' THEN ").append(importedKeyCascadeStr). append(" WHEN R.DELETE_RULE='SET NULL' THEN ").append(importedKeySetNullStr). append(" WHEN R.DELETE_RULE='SET DEFAULT' THEN ").append(importedKeySetDefaultStr). append(" WHEN R.DELETE_RULE='RESTRICT' THEN ").append(importedKeyRestrictStr). append(" WHEN R.DELETE_RULE='NO ACTION' THEN ").append(importedKeyNoActionStr). append(" ELSE ").append(importedKeyNoActionStr).append(" END "); sql::SQLString OptionalRefConstraintJoinStr( "JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R ON " "(R.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND R.TABLE_NAME = B.TABLE_NAME AND R.CONSTRAINT_SCHEMA = B.TABLE_SCHEMA) "); sql::SQLString query("SELECT \n"); query.append("A.TABLE_CATALOG AS PKTABLE_CAT, A.REFERENCED_TABLE_SCHEMA AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME,\n" "A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_CATALOG AS FKTABLE_CAT, A.TABLE_SCHEMA AS FKTABLE_SCHEM,\n" "A.TABLE_NAME AS FKTABLE_NAME, A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ,"); query.append(UpdateRuleClause); query.append(" AS UPDATE_RULE,"); query.append(DeleteRuleClause); query.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME," "(SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = REFERENCED_TABLE_SCHEMA AND" " TABLE_NAME = A.REFERENCED_TABLE_NAME AND CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1) AS PK_NAME,"); query.append(importedKeyNotDeferrableStr); query.append(" AS DEFERRABILITY \n FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B\n" "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME)\n"); query.append(OptionalRefConstraintJoinStr); query.append("\nWHERE B.CONSTRAINT_TYPE = 'FOREIGN KEY' AND A.REFERENCED_TABLE_SCHEMA LIKE ? AND A.REFERENCED_TABLE_NAME=?\n" "ORDER BY A.TABLE_SCHEMA, A.TABLE_NAME, A.ORDINAL_POSITION"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, schema); pStmt->setString(2, table); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // PKTABLE_CAT rs_data_row.push_back(rs->getString(2)); // PKTABLE_SCHEMA rs_data_row.push_back(rs->getString(3)); // PKTABLE_NAME rs_data_row.push_back(rs->getString(4)); // PKCOLUMN_NAME rs_data_row.push_back(rs->getString(5)); // FKTABLE_CAT rs_data_row.push_back(rs->getString(6)); // FKTABLE_SCHEMA rs_data_row.push_back(rs->getString(7)); // FKTABLE_NAME rs_data_row.push_back(rs->getString(8)); // FKCOLUMN_NAME rs_data_row.push_back(rs->getString(9)); // KEY_SEQ rs_data_row.push_back(rs->getString(10)); // UPDATE_RULE rs_data_row.push_back(rs->getString(11)); // DELETE_RULE rs_data_row.push_back(rs->getString(12)); // FK_NAME rs_data_row.push_back(rs->getString(13)); // PK_NAME rs_data_row.push_back(rs->getString(14)); // DEFERRABILITY rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } else { throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::getExportedKeys"); } return NULL; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getExtraNameCharacters() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getExtraNameCharacters() { CPP_ENTER("MySQL_ConnectionMetaData::getExtraNameCharacters"); static const sql::SQLString extra("#@"); return extra; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getIdentifierQuoteString() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getIdentifierQuoteString() { CPP_ENTER("MySQL_ConnectionMetaData::getIdentifierQuoteString"); static const sql::SQLString empty(" "), tick("`"), quote("\""); if (server_version >= 32306) { /* Ask the server for sql_mode and decide for a tick or a quote */ sql::SQLString sql_mode(connection->getSessionVariable("SQL_MODE")); if (sql_mode.find("ANSI_QUOTES") != sql::SQLString::npos) { return quote; } else { return tick; } } return empty; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::parseImportedKeys() -I- */ bool MySQL_ConnectionMetaData::parseImportedKeys( const sql::SQLString& def, sql::SQLString & constraint_name, std::map< sql::SQLString, sql::SQLString > & keywords_names, std::map< sql::SQLString, std::list< sql::SQLString > > & referenced_fields, std::map< sql::SQLString, int > & update_cascade ) { CPP_ENTER("MySQL_ConnectionMetaData::parseImportedKeys"); size_t idx, pos; /* check if line contains 'CONSTRAINT' */ idx = def.find("CONSTRAINT"); if (idx == sql::SQLString::npos) { return false; } pos = idx + sizeof("CONSTRAINT") - 1; sql::SQLString cQuote(getIdentifierQuoteString()); { { size_t end_pos; if (cQuote.length()) { while (def[pos] != cQuote[0]) ++pos; end_pos = ++pos; while (def[end_pos] != cQuote[0] && def[end_pos - 1] != '\\') ++end_pos; } else { while (def[pos] == ' ') ++pos; end_pos = ++pos; while (def[end_pos] != ' ') ++end_pos; } constraint_name = def.substr(pos, end_pos - pos); pos = end_pos + 1; } std::list< sql::SQLString > keywords; keywords.push_back("FOREIGN KEY"); keywords.push_back("REFERENCES"); std::list< sql::SQLString >::const_iterator keywords_it = keywords.begin(); for (; keywords_it != keywords.end(); ++keywords_it) { idx = def.find(*keywords_it, pos); pos = idx + keywords_it->length(); while (def[pos] == ' ') ++pos; // Here comes optional constraint name if (def[pos] != '(') { if (cQuote.length()) { size_t end_pos = ++pos; while (def[end_pos] != cQuote[0] && def[end_pos - 1] != '\\') ++end_pos; keywords_names[*keywords_it] = def.substr(pos, end_pos - pos); pos = end_pos + 1; } else { size_t end_pos = pos; while (def[end_pos] != ' ' && def[end_pos] != '(') ++end_pos; keywords_names[*keywords_it] = def.substr(pos, end_pos - pos - 1); pos = end_pos + 1; // Now find the opening bracket } // skip to the open bracket while (def[pos] != '(') ++pos; } ++pos; // skip the bracket // Here come the referenced fields { size_t end_bracket; end_bracket = def.find(")", pos); size_t comma_pos; do { // Look within a range // , end_bracket - pos comma_pos = def.find("," , pos); // there is something in the implementation of find(",", pos, end_bracket - pos) - so I have to emulate it if (comma_pos >= end_bracket || comma_pos == sql::SQLString::npos) { referenced_fields[*keywords_it].push_back(def.substr(pos + cQuote.length(), end_bracket - pos - cQuote.length() * 2)); break; } else { referenced_fields[*keywords_it].push_back(def.substr(pos + cQuote.length(), comma_pos - pos - cQuote.length() * 2)); pos = comma_pos + 1; // skip the comma while (def[pos] == ' ') ++pos; // skip whitespace after the comma } } while (1); pos = end_bracket + 1; } } } // Check optional (UPDATE | DELETE) CASCADE { std::list< sql::SQLString > keywords; keywords.push_back("ON DELETE"); keywords.push_back("ON UPDATE"); std::list< sql::SQLString >::const_iterator keywords_it = keywords.begin(); for (; keywords_it != keywords.end(); ++keywords_it) { int action = importedKeyNoAction; idx = def.find(*keywords_it, pos); if (idx != sql::SQLString::npos) { pos = idx + keywords_it->length(); while (def[pos] == ' ') ++pos; if (def[pos] == 'R') { // RESTRICT action = importedKeyRestrict; pos += sizeof("RESTRICT"); } else if (def[pos] == 'C') { // CASCADE action = importedKeyCascade; pos += sizeof("CASCADE"); } else if (def[pos] == 'S') { // SET NULL action = importedKeySetNull; pos += sizeof("SET NULL"); } else if (def[pos] == 'N') { // NO ACTION action = importedKeyNoAction; pos += sizeof("NO ACTION"); } } update_cascade[*keywords_it] = action; } } return true; } /* }}} */ /* ORDER BY PKTABLE_SCHEM, PKTABLE_NAME, KEY_SEQ 1,2,8 */ bool compareImportedKeys(std::vector< MyVal > &first, std::vector< MyVal > &second) { return (first[1].getString().compare(second[1].getString()) < 0) || ((first[1].getString().compare(second[1].getString()) == 0) && (first[2].getString().compare(second[2].getString()) < 0)) || ((first[1].getString().compare(second[1].getString()) == 0) && (first[2].getString().compare(second[2].getString()) == 0) && (first[8].getString().caseCompare(second[8].getString()) < 0 )); } /* {{{ MySQL_ConnectionMetaData::getImportedKeys() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) { CPP_ENTER("MySQL_ConnectionMetaData::getImportedKeys"); CPP_INFO_FMT("catalog=%s schema=%s table=%s", catalog.c_str(), schema.c_str(), table.c_str()); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("PKTABLE_CAT"); rs_field_data.push_back("PKTABLE_SCHEM"); rs_field_data.push_back("PKTABLE_NAME"); rs_field_data.push_back("PKCOLUMN_NAME"); rs_field_data.push_back("FKTABLE_CAT"); rs_field_data.push_back("FKTABLE_SCHEM"); rs_field_data.push_back("FKTABLE_NAME"); rs_field_data.push_back("FKCOLUMN_NAME"); rs_field_data.push_back("KEY_SEQ"); rs_field_data.push_back("UPDATE_RULE"); rs_field_data.push_back("DELETE_RULE"); rs_field_data.push_back("FK_NAME"); rs_field_data.push_back("PK_NAME"); rs_field_data.push_back("DEFERRABILITY"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); if (use_info_schema && server_version >= 50116) { /* This just doesn't work */ /* currently this doesn't work - we have to wait for implementation of REFERENTIAL_CONSTRAINTS */ char buf[10]; my_i_to_a(buf, sizeof(buf) - 1, importedKeyCascade); sql::SQLString importedKeyCascadeStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeySetNull); sql::SQLString importedKeySetNullStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeySetDefault); sql::SQLString importedKeySetDefaultStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyRestrict); sql::SQLString importedKeyRestrictStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyNoAction); sql::SQLString importedKeyNoActionStr(buf); my_i_to_a(buf, sizeof(buf) - 1, importedKeyNotDeferrable); sql::SQLString importedKeyNotDeferrableStr(buf); sql::SQLString UpdateRuleClause; UpdateRuleClause.append("CASE WHEN R.UPDATE_RULE='CASCADE' THEN ").append(importedKeyCascadeStr). append(" WHEN R.UPDATE_RULE='SET NULL' THEN ").append(importedKeySetNullStr). append(" WHEN R.UPDATE_RULE='SET DEFAULT' THEN ").append(importedKeySetDefaultStr). append(" WHEN R.UPDATE_RULE='RESTRICT' THEN ").append(importedKeyRestrictStr). append(" WHEN R.UPDATE_RULE='NO ACTION' THEN ").append(importedKeyNoActionStr). append(" ELSE ").append(importedKeyNoActionStr).append(" END "); sql::SQLString DeleteRuleClause; DeleteRuleClause.append("CASE WHEN R.DELETE_RULE='CASCADE' THEN ").append(importedKeyCascadeStr). append(" WHEN R.DELETE_RULE='SET NULL' THEN ").append(importedKeySetNullStr). append(" WHEN R.DELETE_RULE='SET DEFAULT' THEN ").append(importedKeySetDefaultStr). append(" WHEN R.DELETE_RULE='RESTRICT' THEN ").append(importedKeyRestrictStr). append(" WHEN R.DELETE_RULE='NO ACTION' THEN ").append(importedKeyNoActionStr). append(" ELSE ").append(importedKeyNoActionStr).append(" END "); sql::SQLString OptionalRefConstraintJoinStr( "JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R ON " "(R.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND R.TABLE_NAME = B.TABLE_NAME AND R.CONSTRAINT_SCHEMA = B.TABLE_SCHEMA) "); sql::SQLString query("SELECT \n" "A.TABLE_CATALOG AS PKTABLE_CAT, A.REFERENCED_TABLE_SCHEMA AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME,\n" "A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_CATALOG AS FKTABLE_CAT, A.TABLE_SCHEMA AS FKTABLE_SCHEM,\n" "A.TABLE_NAME AS FKTABLE_NAME, A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ,\n"); query.append(UpdateRuleClause); query.append(" AS UPDATE_RULE,\n"); query.append(DeleteRuleClause); query.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME,\n" "(SELECT TC.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC\n" "WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND TABLE_NAME = A.REFERENCED_TABLE_NAME \n" "AND CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1) AS PK_NAME,\n"); query.append(importedKeyNotDeferrableStr); query.append(" AS DEFERRABILITY FROM " "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B \n" "USING(CONSTRAINT_NAME, TABLE_NAME) \n"); query.append(OptionalRefConstraintJoinStr); query.append("WHERE B.CONSTRAINT_TYPE = 'FOREIGN KEY' AND A.TABLE_SCHEMA LIKE ? AND A.TABLE_NAME=? AND A.REFERENCED_TABLE_SCHEMA \n" "IS NOT NULL\nORDER BY A.REFERENCED_TABLE_SCHEMA, A.REFERENCED_TABLE_NAME, A.ORDINAL_POSITION"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, schema); pStmt->setString(2, table); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // PKTABLE_CAT rs_data_row.push_back(rs->getString(2)); // PKTABLE_SCHEMA rs_data_row.push_back(rs->getString(3)); // PKTABLE_NAME rs_data_row.push_back(rs->getString(4)); // PKCOLUMN_NAME rs_data_row.push_back(rs->getString(5)); // FKTABLE_CAT rs_data_row.push_back(rs->getString(6)); // FKTABLE_SCHEMA rs_data_row.push_back(rs->getString(7)); // FKTABLE_NAME rs_data_row.push_back(rs->getString(8)); // FKCOLUMN_NAME rs_data_row.push_back(rs->getString(9)); // KEY_SEQ rs_data_row.push_back(rs->getString(10)); // UPDATE_RULE rs_data_row.push_back(rs->getString(11)); // DELETE_RULE rs_data_row.push_back(rs->getString(12)); // FK_NAME rs_data_row.push_back(rs->getString(13)); // PK_NAME rs_data_row.push_back(rs->getString(14)); // DEFERRABILITY rs_data->push_back(rs_data_row); } } else { sql::SQLString query("SHOW CREATE TABLE `"); query.append(schema).append("`.`").append(table).append("`"); boost::scoped_ptr< sql::ResultSet > rs(NULL); try { rs.reset(stmt->executeQuery(query)); } catch (SQLException &) { // schema and/or table don't exist, return empty set // just do nothing and the `if` will be skipped } if (rs.get() && rs->next()) { sql::SQLString create_query(rs->getString(2)); unsigned int kSequence = 0; sql::SQLString constraint_name; std::map< sql::SQLString, sql::SQLString > keywords_names; std::map< sql::SQLString, std::list< sql::SQLString > > referenced_fields; std::map< sql::SQLString, int > update_delete_action; if (parseImportedKeys(create_query, constraint_name, keywords_names, referenced_fields, update_delete_action)) { std::list< sql::SQLString >::const_iterator it_references = referenced_fields["REFERENCES"].begin(); std::list< sql::SQLString >::const_iterator it_references_end = referenced_fields["REFERENCES"].end(); std::list< sql::SQLString >::const_iterator it_foreignkey = referenced_fields["FOREIGN KEY"].begin(); std::list< sql::SQLString >::const_iterator it_foreignkey_end = referenced_fields["FOREIGN KEY"].end(); for ( ; it_references != it_references_end && it_foreignkey != it_foreignkey_end; ++it_references, ++it_foreignkey ) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // PK_TABLE_CAT rs_data_row.push_back(schema); // PKTABLE_SCHEM rs_data_row.push_back(keywords_names["REFERENCES"]);// PKTABLE_NAME // ToDo: Extracting just the first column rs_data_row.push_back(*it_references); // PK_COLUMN_NAME rs_data_row.push_back(""); // FKTABLE_CAT // ToDo: Is this correct? referencing the same schema. Maybe fully referenced name can appear, need to parse it too rs_data_row.push_back(schema); // FKTABLE_SCHEM rs_data_row.push_back(table); // FKTABLE_NAME // ToDo: Extracting just the first column rs_data_row.push_back(*it_foreignkey); // FKCOLUMN_NAME rs_data_row.push_back((int64_t) ++kSequence); // KEY_SEQ rs_data_row.push_back((int64_t) update_delete_action["ON UPDATE"]); // UPDATE_RULE rs_data_row.push_back((int64_t) update_delete_action["ON DELETE"]); // DELETE_RULE rs_data_row.push_back(constraint_name); // FK_NAME // ToDo: Should it really be PRIMARY? rs_data_row.push_back("PRIMARY"); // PK_NAME rs_data_row.push_back((int64_t) importedKeyNotDeferrable); // DEFERRABILITY rs_data->push_back(rs_data_row); } } } rs_data.get()->sort(compareImportedKeys); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION */ bool compareIndexInfo(std::vector< MyVal > &first, std::vector< MyVal > &second) { return (first[3].getBool() < second[3].getBool()) || ((first[3].getBool() == second[3].getBool()) && (first[6].getString().compare(second[6].getString()) < 0)) || ((first[3].getBool() == second[3].getBool()) && (first[6].getString().compare(second[6].getString()) == 0) && (first[5].getString().caseCompare(second[5].getString()) < 0 )) || ((first[3].getBool() == second[3].getBool()) && (first[6].getString().compare(second[6].getString()) == 0) && (first[5].getString().caseCompare(second[5].getString()) == 0 ) && (first[7].getString().caseCompare(second[7].getString()) < 0 )); } /* {{{ MySQL_ConnectionMetaData::getIndexInfo() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getIndexInfo(const sql::SQLString& /*catalog*/, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool /* approximate */) { CPP_ENTER("MySQL_ConnectionMetaData::getIndexInfo"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("NON_UNIQUE"); rs_field_data.push_back("INDEX_QUALIFIER"); rs_field_data.push_back("INDEX_NAME"); rs_field_data.push_back("TYPE"); rs_field_data.push_back("ORDINAL_POSITION"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("ASC_OR_DESC"); rs_field_data.push_back("CARDINALITY"); rs_field_data.push_back("PAGES"); rs_field_data.push_back("FILTER_CONDITION"); char indexOther[5]; char indexHash[5]; snprintf(indexOther, sizeof(indexOther), "%d", DatabaseMetaData::tableIndexOther); snprintf(indexHash, sizeof(indexHash), "%d", DatabaseMetaData::tableIndexHashed); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); if (use_info_schema && server_version > 50020) { sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, NON_UNIQUE, " "TABLE_SCHEMA AS INDEX_QUALIFIER, INDEX_NAME, CASE WHEN INDEX_TYPE='HASH' THEN "); query.append(indexHash).append(" ELSE ").append(indexOther); query.append(" END AS TYPE, SEQ_IN_INDEX AS ORDINAL_POSITION, COLUMN_NAME, COLLATION AS ASC_OR_DESC, CARDINALITY," "NULL AS PAGES, NULL AS FILTER_CONDITION " "FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ?\n"); if (unique) { query.append(" AND NON_UNIQUE=0"); } query.append(" ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, schema); pStmt->setString(2, table); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // NON_UNIQUE rs_data_row.push_back(rs->getString(5)); // INDEX_QUALIFIER rs_data_row.push_back(rs->getString(6)); // INDEX_NAME rs_data_row.push_back(rs->getString(7)); // TYPE rs_data_row.push_back(rs->getString(8)); // ORDINAL_POSITION rs_data_row.push_back(rs->getString(9)); // COLUMN_NAME rs_data_row.push_back(rs->getString(10)); // ASC_OR_DESC rs_data_row.push_back(rs->getString(11)); // CARDINALITY rs_data_row.push_back(rs->getString(12)); // PAGES rs_data_row.push_back(rs->getString(13)); // FILTER_CONDITION rs_data->push_back(rs_data_row); } } else { sql::SQLString query("SHOW INDEX FROM `"); query.append(schema).append("`.`").append(table).append("`"); boost::scoped_ptr< sql::ResultSet > rs(NULL); try { rs.reset(stmt->executeQuery(query)); } catch (SQLException &) { // schema and/or table doesn't exist. return empty set // do nothing here } while (rs.get() && rs->next()) { unsigned int row_unique; std::istringstream buffer(rs->getString("Non_unique")); buffer >> row_unique; if (!(buffer.rdstate() & std::istringstream::failbit) && unique && row_unique != 0){ continue; } MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(schema); // TABLE_SCHEM rs_data_row.push_back(rs->getString("Table")); // TABLE_NAME rs_data_row.push_back(atoi(rs->getString("Non_unique").c_str())? true:false); // NON_UNIQUE rs_data_row.push_back(schema); // INDEX_QUALIFIER rs_data_row.push_back(rs->getString("Key_name")); // INDEX_NAME if (!rs->getString("Index_type").compare("HASH")) { rs_data_row.push_back((const char *) indexHash); // TYPE } else { rs_data_row.push_back((const char *) indexOther); // TYPE } rs_data_row.push_back(rs->getString("Seq_in_index")); // ORDINAL_POSITION rs_data_row.push_back(rs->getString("Column_name")); // COLUMN_NAME rs_data_row.push_back(rs->getString("Collation")); // ASC_OR_DESC rs_data_row.push_back(rs->getString("Cardinality")); // CARDINALITY rs_data_row.push_back("0"); // PAGES rs_data_row.push_back(""); // FILTER_CONDITION rs_data->push_back(rs_data_row); } rs_data.get()->sort(compareIndexInfo); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getCDBCMajorVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getCDBCMajorVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getCDBCMajorVersion"); return 3; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getCDBCMinorVersion() -I- */ unsigned int MySQL_ConnectionMetaData::getCDBCMinorVersion() { CPP_ENTER("MySQL_ConnectionMetaData::getCDBCMinorVersion"); return 0; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxBinaryLiteralLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxBinaryLiteralLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxBinaryLiteralLength"); return 16777208L; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxCatalogNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxCatalogNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxCatalogNameLength"); return 32; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxCharLiteralLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxCharLiteralLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxCharLiteralLength"); return 16777208; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxColumnNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxColumnNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxColumnNameLength"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxColumnsInGroupBy() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxColumnsInGroupBy() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxColumnsInGroupBy"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxColumnsInIndex() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxColumnsInIndex() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxColumnsInIndex"); return 16; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxColumnsInOrderBy() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxColumnsInOrderBy() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxColumnsInOrderBy"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxColumnsInSelect() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxColumnsInSelect() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxColumnsInSelect"); return 256; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxColumnsInTable() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxColumnsInTable() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxColumnsInTable"); return 512; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxConnections() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxConnections() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxConnections"); return atoi(connection->getSessionVariable("max_connections").c_str()); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxCursorNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxCursorNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxCursorNameLength"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxIndexLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxIndexLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxIndexLength"); return 256; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxProcedureNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxProcedureNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxProcedureNameLength"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxRowSize() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxRowSize() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxRowSize"); return 2147483647L - 8; // Max buffer size - HEADER } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxSchemaNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxSchemaNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxSchemaNameLength"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxStatementLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxStatementLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxStatementLength"); return atoi(connection->getSessionVariable("max_allowed_packet").c_str()) - 4; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxStatements() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxStatements() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxStatements"); return 0; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxTableNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxTableNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxTableNameLength"); return 64; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxTablesInSelect() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxTablesInSelect() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxTablesInSelect"); return 256; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getMaxUserNameLength() -I- */ unsigned int MySQL_ConnectionMetaData::getMaxUserNameLength() { CPP_ENTER("MySQL_ConnectionMetaData::getMaxUserNameLength"); return 16; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getNumericFunctions() -I- */ const sql::SQLString & MySQL_ConnectionMetaData::getNumericFunctions() { CPP_ENTER("MySQL_ConnectionMetaData::getNumericFunctions"); static const sql::SQLString funcs("ABS,ACOS,ASIN,ATAN,ATAN2,BIT_COUNT,CEILING,COS," "COT,DEGREES,EXP,FLOOR,LOG,LOG10,MAX,MIN,MOD,PI,POW," "POWER,RADIANS,RAND,ROUND,SIN,SQRT,TAN,TRUNCATE"); return funcs; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getPrimaryKeys() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) { CPP_ENTER("MySQL_ConnectionMetaData::getPrimaryKeys"); CPP_INFO_FMT("catalog=%s schema=%s table=%s", catalog.c_str(), schema.c_str(), table.c_str()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("KEY_SEQ"); rs_field_data.push_back("PK_NAME"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); /* Bind Problems with 49999, check later why */ if (use_info_schema && server_version > 49999) { const sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, " "COLUMN_NAME, SEQ_IN_INDEX AS KEY_SEQ, INDEX_NAME AS PK_NAME FROM INFORMATION_SCHEMA.STATISTICS " "WHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ? AND INDEX_NAME='PRIMARY' " "ORDER BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, schema); pStmt->setString(2, table); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // COLUMN_NAME rs_data_row.push_back(rs->getString(5)); // KEY_SEQ rs_data_row.push_back(rs->getString(6)); // PK_NAME rs_data->push_back(rs_data_row); } } else { sql::SQLString query("SHOW KEYS FROM `"); query.append(schema).append("`.`").append(table).append("`"); boost::scoped_ptr< sql::ResultSet > rs(NULL); try { rs.reset(stmt->executeQuery(query)); } catch (SQLException &) { // probably schema and/or table doesn't exist. return empty set // do nothing here } while (rs.get() && rs->next()) { sql::SQLString key_name = rs->getString("Key_name"); if (!key_name.compare("PRIMARY") || !key_name.compare("PRI")) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(schema); // TABLE_SCHEM rs_data_row.push_back(rs->getString(1)); // TABLE_NAME rs_data_row.push_back(rs->getString("Column_name")); // COLUMN_NAME rs_data_row.push_back(rs->getString("Seq_in_index")); // KEY_SEQ rs_data_row.push_back(key_name); // PK_NAME rs_data->push_back(rs_data_row); } } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getUniqueNonNullableKeys() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getUniqueNonNullableKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) { CPP_ENTER("MySQL_ConnectionMetaData::getPrimaryKeys"); CPP_INFO_FMT("catalog=%s schema=%s table=%s", catalog.c_str(), schema.c_str(), table.c_str()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("KEY_SEQ"); rs_field_data.push_back("PK_NAME"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); /* Bind Problems with 49999, check later why */ if (use_info_schema && server_version > 50002) { const sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME," " COLUMN_NAME, SEQ_IN_INDEX AS KEY_SEQ, INDEX_NAME AS PK_NAME " "FROM INFORMATION_SCHEMA.STATISTICS " "WHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ? AND INDEX_NAME <> 'PRIMARY'" " AND NON_UNIQUE = 0 AND NULLABLE <> 'YES'" "ORDER BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX"); boost::scoped_ptr< sql::PreparedStatement > stmt(connection->prepareStatement(query)); stmt->setString(1, schema); stmt->setString(2, table); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // COLUMN_NAME rs_data_row.push_back(rs->getString(5)); // KEY_SEQ rs_data_row.push_back(rs->getString(6)); // PK_NAME rs_data->push_back(rs_data_row); } } else { sql::SQLString query("SHOW KEYS FROM `"); query.append(schema).append("`.`").append(table).append("`"); boost::scoped_ptr< sql::Statement > stmt(connection->createStatement()); boost::scoped_ptr< sql::ResultSet > rs(NULL); try { rs.reset(stmt->executeQuery(query)); } catch (SQLException &) { // probably schema and/or table doesn't exist. return empty set // do nothing here } if (rs.get()) { while (rs->next()) { int non_unique = rs->getInt("Non_unique"); sql::SQLString nullable = rs->getString("Null"); if (non_unique == 0 && nullable.compare("YES")) { sql::SQLString key_name = rs->getString("Key_name"); MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(schema); // TABLE_SCHEM rs_data_row.push_back(rs->getString(1)); // TABLE_NAME rs_data_row.push_back(rs->getString("Column_name")); // COLUMN_NAME rs_data_row.push_back(rs->getString("Seq_in_index")); // KEY_SEQ rs_data_row.push_back(key_name); // PK_NAME rs_data->push_back(rs_data_row); } } } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getProcedureColumns() -U- */ sql::ResultSet * MySQL_ConnectionMetaData::getProcedureColumns(const sql::SQLString& /* catalog */, const sql::SQLString& /* schemaPattern */, const sql::SQLString& /* procedureNamePattern */, const sql::SQLString& /* columnNamePattern */) { CPP_ENTER("MySQL_ConnectionMetaData::getProcedureColumns"); throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::getURL"); return NULL; // fool compiler #if A0 std::list rs_field_data; rs_field_data.push_back("PROCEDURE_CAT"); rs_field_data.push_back("PROCEDURE_SCHEM"); rs_field_data.push_back("PROCEDURE_NAME"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("COLUMN_TYPE"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("PRECISION"); rs_field_data.push_back("LENGTH"); rs_field_data.push_back("SCALE"); rs_field_data.push_back("RADIX"); rs_field_data.push_back("NULLABLE"); rs_field_data.push_back("REMARKS"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; #endif } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getProcedures() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getProcedures(const sql::SQLString& /*catalog*/, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) { CPP_ENTER("MySQL_ConnectionMetaData::getProcedures"); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); sql::SQLString escapedProcedureNamePattern = connection->escapeString(procedureNamePattern); std::list rs_field_data; rs_field_data.push_back("PROCEDURE_CAT"); rs_field_data.push_back("PROCEDURE_SCHEM"); rs_field_data.push_back("PROCEDURE_NAME"); rs_field_data.push_back("RESERVERD_1"); rs_field_data.push_back("RESERVERD_2"); rs_field_data.push_back("RESERVERD_3"); rs_field_data.push_back("REMARKS"); rs_field_data.push_back("PROCEDURE_TYPE"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); char procRetNoRes[5]; my_i_to_a(procRetNoRes, sizeof(procRetNoRes) - 1, procedureNoResult); char procRetRes[5]; my_i_to_a(procRetRes, sizeof(procRetRes) - 1, procedureReturnsResult); char procRetUnknown[5]; my_i_to_a(procRetUnknown, sizeof(procRetUnknown) - 1, procedureResultUnknown); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); if (use_info_schema && server_version > 49999) { sql::SQLString query("SELECT ROUTINE_CATALOG AS PROCEDURE_CAT, ROUTINE_SCHEMA AS PROCEDURE_SCHEM, " "ROUTINE_NAME AS PROCEDURE_NAME, NULL AS RESERVED_1, NULL AS RESERVERD_2, NULL as RESERVED_3," "ROUTINE_COMMENT AS REMARKS, " "CASE WHEN ROUTINE_TYPE = 'PROCEDURE' THEN "); query.append(procRetNoRes); query.append(" WHEN ROUTINE_TYPE='FUNCTION' THEN "); query.append(procRetRes); query.append(" ELSE "); query.append(procRetUnknown); query.append(" END AS PROCEDURE_TYPE\nFROM INFORMATION_SCHEMA.ROUTINES\n" "WHERE ROUTINE_SCHEMA LIKE ? AND ROUTINE_NAME LIKE ?\n" "ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, escapedSchemaPattern); pStmt->setString(2, escapedProcedureNamePattern.length() ? escapedProcedureNamePattern : "%"); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // PROCEDURE_CAT rs_data_row.push_back(rs->getString(2)); // PROCEDURE_SCHEM rs_data_row.push_back(rs->getString(3)); // PROCEDURE_NAME rs_data_row.push_back(rs->getString(4)); // reserved1 rs_data_row.push_back(rs->getString(5)); // reserved2 rs_data_row.push_back(rs->getString(6)); // reserved3 rs_data_row.push_back(rs->getString(7)); // REMARKS rs_data_row.push_back(rs->getString(8)); // PROCEDURE_TYPE rs_data->push_back(rs_data_row); } } else if (server_version > 49999) { bool got_exception = false; do { sql::SQLString query("SELECT 'def' AS PROCEDURE_CAT, db as PROCEDURE_SCHEM, " "name AS PROCEDURE_NAME, NULL as RESERVERD_1, NULL as RESERVERD_2, " "NULL AS RESERVERD_3, comment as REMARKS, "); query.append(" CASE WHEN TYPE='FUNCTION' THEN ").append(procRetRes); query.append(" WHEN TYPE='PROCEDURE' THEN ").append(procRetNoRes).append(" ELSE ").append(procRetUnknown); query.append(" END AS PROCEDURE_TYPE FROM mysql.proc WHERE name LIKE ? AND db <=> ? ORDER BY name"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, escapedProcedureNamePattern); pStmt->setString(2, escapedSchemaPattern); boost::scoped_ptr< sql::ResultSet > rs(NULL); try { rs.reset(pStmt->executeQuery()); } catch (SQLException & /*e*/) { /* We don't have direct access to the mysql.proc, use SHOW */ got_exception = true; break; } while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // PROCEDURE_CAT rs_data_row.push_back(rs->getString(2)); // PROCEDURE_SCHEM rs_data_row.push_back(rs->getString(3)); // PROCEDURE_NAME rs_data_row.push_back(rs->getString(4)); // reserved1 rs_data_row.push_back(rs->getString(5)); // reserved2 rs_data_row.push_back(rs->getString(6)); // reserved3 rs_data_row.push_back(rs->getString(7)); // REMARKS rs_data_row.push_back(rs->getString(8)); // PROCEDURE_TYPE rs_data->push_back(rs_data_row); } } while (0); if (got_exception) { sql::SQLString query("SHOW PROCEDURE STATUS"); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery(query)); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // PROCEDURE_CAT rs_data_row.push_back(rs->getString(1)); // PROCEDURE_SCHEM rs_data_row.push_back(rs->getString(2)); // PROCEDURE_NAME rs_data_row.push_back(""); // reserved1 rs_data_row.push_back(""); // reserved2 rs_data_row.push_back(""); // reserved3 rs_data_row.push_back(rs->getString(8)); // REMARKS rs_data_row.push_back(sql::SQLString(!rs->getString(3).compare("PROCEDURE")? procRetNoRes:procRetRes)); // PROCEDURE_TYPE rs_data->push_back(rs_data_row); } } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getProcedureTerm() -I- */ const sql::SQLString & MySQL_ConnectionMetaData::getProcedureTerm() { CPP_ENTER("MySQL_ConnectionMetaData::getProcedureTerm"); static const sql::SQLString term("procedure"); return term; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getResultSetHoldability() -I- */ int MySQL_ConnectionMetaData::getResultSetHoldability() { CPP_ENTER("MySQL_ConnectionMetaData::getResultSetHoldability"); return sql::ResultSet::HOLD_CURSORS_OVER_COMMIT; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemas() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSchemas() { CPP_ENTER("MySQL_ConnectionMetaData::getSchemas"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_CATALOG"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); boost::scoped_ptr< sql::ResultSet > rs( stmt->executeQuery(use_info_schema && server_version > 49999? "SELECT SCHEMA_NAME AS TABLE_SCHEM, CATALOG_NAME AS TABLE_CATALOG FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY SCHEMA_NAME": "SHOW DATABASES")); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); if (use_info_schema && server_version > 49999) { rs_data_row.push_back(rs->getString(2)); } else { rs_data_row.push_back(""); } rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemaTerm() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getSchemaTerm() { CPP_ENTER("MySQL_ConnectionMetaData::getSchemaTerm"); static const sql::SQLString term("database"); return term; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemaCollation() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSchemaCollation(const sql::SQLString& /* catalog */, const sql::SQLString& schemaPattern) { CPP_ENTER("MySQL_ConnectionMetaData::getSchemaCollation"); CPP_INFO_FMT("schemaPattern=%s", schemaPattern.c_str()); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("SCHEMA_CAT"); rs_field_data.push_back("SCHEMA_NAME"); rs_field_data.push_back("SCHEMA_COLLATION"); sql::SQLString query("SELECT CATALOG_NAME AS SCHEMA_CAT, SCHEMA_NAME, " "DEFAULT_COLLATION_NAME AS SCHEMA_COLLATION FROM INFORMATION_SCHEMA.SCHEMATA " "where SCHEMA_NAME LIKE '"); query.append(escapedSchemaPattern).append("'"); boost::scoped_ptr< sql::Statement > stmt(connection->createStatement()); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery(query)); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // SCHEMA_CAT rs_data_row.push_back(rs->getString(2)); // SCHEMA_NAME rs_data_row.push_back(rs->getString(3)); // SCHEMA_COLLATION rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSchemaCharset() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSchemaCharset(const sql::SQLString& /* catalog */, const sql::SQLString& schemaPattern) { CPP_ENTER("MySQL_ConnectionMetaData::getSchemaCharset"); CPP_INFO_FMT("schemaPattern=%s", schemaPattern.c_str()); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("SCHEMA_CAT"); rs_field_data.push_back("SCHEMA_NAME"); rs_field_data.push_back("SCHEMA_CHARSET"); sql::SQLString query("SELECT CATALOG_NAME AS SCHEMA_CAT, SCHEMA_NAME, " "DEFAULT_CHARACTER_SET_NAME AS SCHEMA_CHARSET FROM INFORMATION_SCHEMA.SCHEMATA " "where SCHEMA_NAME LIKE '"); query.append(escapedSchemaPattern).append("'"); boost::scoped_ptr< sql::Statement > stmt(connection->createStatement()); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery(query)); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // SCHEMA_CAT rs_data_row.push_back(rs->getString(2)); // SCHEMA_NAME rs_data_row.push_back(rs->getString(3)); // SCHEMA_CHARSET rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSearchStringEscape() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getSearchStringEscape() { CPP_ENTER("MySQL_ConnectionMetaData::getSearchStringEscape"); static const sql::SQLString escape("\\"); return escape; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSQLKeywords() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getSQLKeywords() { CPP_ENTER("MySQL_ConnectionMetaData::getSQLKeywords"); static const sql::SQLString keywords( "ACCESSIBLE, ADD, ALL,"\ "ALTER, ANALYZE, AND, AS, ASC, ASENSITIVE, BEFORE,"\ "BETWEEN, BIGINT, BINARY, BLOB, BOTH, BY, CALL,"\ "CASCADE, CASE, CHANGE, CHAR, CHARACTER, CHECK,"\ "COLLATE, COLUMN, CONDITION, CONNECTION, CONSTRAINT,"\ "CONTINUE, CONVERT, CREATE, CROSS, CURRENT_DATE,"\ "CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,"\ "DATABASE, DATABASES, DAY_HOUR, DAY_MICROSECOND,"\ "DAY_MINUTE, DAY_SECOND, DEC, DECIMAL, DECLARE,"\ "DEFAULT, DELAYED, DELETE, DESC, DESCRIBE,"\ "DETERMINISTIC, DISTINCT, DISTINCTROW, DIV, DOUBLE,"\ "DROP, DUAL, EACH, ELSE, ELSEIF, ENCLOSED,"\ "ESCAPED, EXISTS, EXIT, EXPLAIN, FALSE, FETCH,"\ "FLOAT, FLOAT4, FLOAT8, FOR, FORCE, FOREIGN, FROM,"\ "FULLTEXT, GRANT, GROUP, HAVING, HIGH_PRIORITY,"\ "HOUR_MICROSECOND, HOUR_MINUTE, HOUR_SECOND, IF,"\ "IGNORE, IN, INDEX, INFILE, INNER, INOUT,"\ "INSENSITIVE, INSERT, INT, INT1, INT2, INT3, INT4,"\ "INT8, INTEGER, INTERVAL, INTO, IS, ITERATE, JOIN,"\ "KEY, KEYS, KILL, LEADING, LEAVE, LEFT, LIKE,"\ "LOCALTIMESTAMP, LOCK, LONG, LONGBLOB, LONGTEXT,"\ "LOOP, LOW_PRIORITY, MATCH, MEDIUMBLOB, MEDIUMINT,"\ "MEDIUMTEXT, MIDDLEINT, MINUTE_MICROSECOND,"\ "MINUTE_SECOND, MOD, MODIFIES, NATURAL, NOT,"\ "NO_WRITE_TO_BINLOG, NULL, NUMERIC, ON, OPTIMIZE,"\ "OPTION, OPTIONALLY, OR, ORDER, OUT, OUTER,"\ "OUTFILE, PRECISION, PRIMARY, PROCEDURE, PURGE,"\ "RANGE, READ, READS, READ_ONLY, READ_WRITE, REAL,"\ "REFERENCES, REGEXP, RELEASE, RENAME, REPEAT,"\ "REPLACE, REQUIRE, RESTRICT, RETURN, REVOKE, RIGHT,"\ "RLIKE, SCHEMA, SCHEMAS, SECOND_MICROSECOND, SELECT,"\ "SENSITIVE, SEPARATOR, SET, SHOW, SMALLINT, SPATIAL,"\ "SPECIFIC, SQL, SQLEXCEPTION, SQLSTATE, SQLWARNING,"\ "SQL_BIG_RESULT, SQL_CALC_FOUND_ROWS, SQL_SMALL_RESULT,"\ "SSL, STARTING, STRAIGHT_JOIN, TABLE, TERMINATED,"\ "THEN, TINYBLOB, TINYINT, TINYTEXT, TO, TRAILING,"\ "TRIGGER, TRUE, UNDO, UNION, UNIQUE, UNLOCK,"\ "UNSIGNED, UPDATE, USAGE, USE, USING, UTC_DATE,"\ "UTC_TIME, UTC_TIMESTAMP, VALUES, VARBINARY, VARCHAR,"\ "VARCHARACTER, VARYING, WHEN, WHERE, WHILE, WITH,"\ "WRITE, X509, XOR, YEAR_MONTH, ZEROFILL" \ "GENERAL, IGNORE_SERVER_IDS, MASTER_HEARTBEAT_PERIOD," \ "MAXVALUE, RESIGNAL, SIGNAL, SLOW"); return keywords; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSQLStateType() -I- */ int MySQL_ConnectionMetaData::getSQLStateType() { CPP_ENTER("MySQL_ConnectionMetaData::getSQLStateType"); return sqlStateSQL99; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getStringFunctions() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getStringFunctions() { CPP_ENTER("MySQL_ConnectionMetaData::getStringFunctions"); static const sql::SQLString funcs( "ASCII,BIN,BIT_LENGTH,CHAR,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT," "CONCAT_WS,CONV,ELT,EXPORT_SET,FIELD,FIND_IN_SET,HEX,INSERT," "INSTR,LCASE,LEFT,LENGTH,LOAD_FILE,LOCATE,LOCATE,LOWER,LPAD," "LTRIM,MAKE_SET,MATCH,MID,OCT,OCTET_LENGTH,ORD,POSITION," "QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX," "SPACE,STRCMP,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING," "SUBSTRING_INDEX,TRIM,UCASE,UPPER"); return funcs; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSuperTables() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSuperTables(const sql::SQLString& /*catalog*/, const sql::SQLString& /*schemaPattern*/, const sql::SQLString& /*tableNamePattern*/) { CPP_ENTER("MySQL_ConnectionMetaData::getSuperTables"); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("SUPERTABLE_NAME"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSuperTypes() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getSuperTypes(const sql::SQLString& /*catalog*/, const sql::SQLString& /*schemaPattern*/, const sql::SQLString& /*typeNamePattern*/) { CPP_ENTER("MySQL_ConnectionMetaData::getSuperTypes"); std::list rs_field_data; rs_field_data.push_back("TYPE_CAT"); rs_field_data.push_back("TYPE_SCHEM"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("SUPERTYPE_CAT"); rs_field_data.push_back("SUPERTYPE_SCHEM"); rs_field_data.push_back("SUPERTYPE_NAME"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getSystemFunctions() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getSystemFunctions() { CPP_ENTER("MySQL_ConnectionMetaData::getSystemFunctions"); static const sql::SQLString funcs( "DATABASE,USER,SYSTEM_USER," "SESSION_USER,PASSWORD,ENCRYPT,LAST_INSERT_ID,VERSION"); return funcs; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTablePrivileges() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) { CPP_ENTER("MySQL_ConnectionMetaData::getTablePrivileges"); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery("SHOW GRANTS")); std::list< sql::SQLString > aPrivileges, aSchemas, aTables; sql::SQLString strAllPrivs("ALTER, DELETE, DROP, INDEX, INSERT, LOCK TABLES, SELECT, UPDATE"); sql::SQLString cQuote(getIdentifierQuoteString()); while (rs->next() ) { sql::SQLString aGrant = rs->getString(1); aGrant = aGrant.replace(0, 6, ""); size_t pos = aGrant.find("ALL PRIVILEGES"); if (pos != sql::SQLString::npos) { aGrant = aGrant.replace(pos, sizeof("ALL PRIVILEGES") - 1, strAllPrivs); } pos = aGrant.find("ON"); //ASSERT(pos != sql::SQLString::npos); aPrivileges.push_back(aGrant.substr(0, pos - 1)); /* -1 for trim */ aGrant = aGrant.substr(pos + 3); /* remove "ON " */ if (aGrant[0] != '*') { pos = 1; do { pos = aGrant.find(cQuote, pos); } while (pos != sql::SQLString::npos && aGrant[pos - 1] == '\\'); aSchemas.push_back(aGrant.substr(1, pos - 1)); /* From pos 1, without the quoting */ aGrant = aGrant.replace(0, pos + 1 + 1, ""); // remove the quote, the dot too } else { aSchemas.push_back("*"); aGrant = aGrant.replace(0, 1 + 1, ""); // remove the star, the dot too } /* first char is the quotestring, the last too "`xyz`." Dot is at 5, copy from 1, 5 - 1 - 1 = xyz */ if (aGrant[0] != '*') { // What if the names are not quoted. They should be, no? int idx = 1; pos = idx; do { pos = aGrant.find(cQuote, pos); } while (pos != sql::SQLString::npos && aGrant[pos - 1] == '\\'); aTables.push_back(aGrant.substr(1, pos - 1)); } else { aTables.push_back("*"); } /* `aaa`.`xyz` - jump over the dot and the quote . = 5 ` = 6 x = 7 = idx ` = 10 ` - x = 10 - 7 = 3 -> xyz */ } std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("GRANTOR"); rs_field_data.push_back("GRANTEE"); rs_field_data.push_back("PRIVILEGE"); rs_field_data.push_back("IS_GRANTABLE"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list< sql::SQLString > tableTypes; tableTypes.push_back(sql::SQLString("TABLE")); boost::scoped_ptr< sql::ResultSet > tables(getTables(catalog, schemaPattern, tableNamePattern, tableTypes)); sql::SQLString schema, table; while (tables->next()) { schema = tables->getString(2); table = tables->getString(3); std::list::const_iterator it_priv, it_schemas, it_tables; it_priv = aPrivileges.begin(); it_schemas = aSchemas.begin(); it_tables = aTables.begin(); for (; it_priv != aPrivileges.end(); ++it_priv, ++it_schemas, ++it_tables) { /* skip usage */ if (it_priv->compare("USAGE") && matchTable(*it_schemas, *it_tables, schema, table)) { size_t pos, idx; pos = 0; do { while ((*it_priv)[pos] == ' ') ++pos; // Eat the whitespace idx = it_priv->find(",", pos); sql::SQLString privToken; // check for sql::SQLString::npos if (idx != sql::SQLString::npos) { privToken = it_priv->substr(pos, idx - pos); pos = idx + 1; /* skip ',' */ } else { privToken = it_priv->substr(pos, it_priv->length() - pos); } // ToDo: Why? if (privToken.find_first_of('/') == sql::SQLString::npos) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(schema); // TABLE_SCHEM rs_data_row.push_back(table); // TABLE_NAME rs_data_row.push_back(""); // GRANTOR rs_data_row.push_back(getUserName()); // GRANTEE rs_data_row.push_back(privToken); // PRIVILEGE rs_data_row.push_back(""); // IS_GRANTABLE - ToDo maybe here WITH GRANT OPTION?? rs_data->push_back(rs_data_row); } } while (idx != sql::SQLString::npos); break; } } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTables() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getTables(const sql::SQLString& /* catalog */, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list &types) { CPP_ENTER("MySQL_ConnectionMetaData::getTables"); CPP_INFO_FMT("schemaPattern=%s tablePattern=%s", schemaPattern.c_str(), tableNamePattern.c_str()); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); sql::SQLString escapedTableNamePattern = connection->escapeString(tableNamePattern); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEM"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("TABLE_TYPE"); rs_field_data.push_back("REMARKS"); connection->getClientOption("metadataUseInfoSchema", (void *) &use_info_schema); /* Bind Problems with 49999, check later why */ if (use_info_schema && server_version > 49999) { const sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME," "IF(STRCMP(TABLE_TYPE,'BASE TABLE'), " "IF(STRCMP(TABLE_TYPE,'SYSTEM VIEW'), TABLE_TYPE, 'VIEW')," " 'TABLE') AS TABLE_TYPE, TABLE_COMMENT AS REMARKS\n" "FROM INFORMATION_SCHEMA.TABLES\nWHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ?\n" "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME"); boost::scoped_ptr< sql::PreparedStatement > pStmt(connection->prepareStatement(query)); pStmt->setString(1, escapedSchemaPattern); pStmt->setString(2, escapedTableNamePattern); boost::scoped_ptr< sql::ResultSet > rs(pStmt->executeQuery()); while (rs->next()) { std::list::const_iterator it = types.begin(); for (; it != types.end(); ++it) { if (*it == rs->getString(4)) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // TABLE_TYPE rs_data_row.push_back(rs->getString(5)); // REMARKS rs_data->push_back(rs_data_row); break; } } } } else { sql::SQLString query1("SHOW DATABASES LIKE '"); query1.append(escapedSchemaPattern).append("'"); boost::scoped_ptr< sql::ResultSet > rs1(stmt->executeQuery(query1)); while (rs1->next()) { sql::SQLString current_schema(rs1->getString(1)); sql::SQLString query2("SHOW FULL TABLES FROM `"); query2.append(current_schema).append("` LIKE '").append(escapedTableNamePattern).append("'"); boost::scoped_ptr< sql::ResultSet > rs2(stmt->executeQuery(query2)); while (rs2->next()) { std::list< sql::SQLString >::const_iterator it = types.begin(); for (; it != types.end(); ++it) { /* < 49999 knows only TABLE, no VIEWS */ /* TODO: Optimize this everytime checking, put it outside of the loop */ if (!it->compare("TABLE") && !(rs2->getString(2)).compare("BASE TABLE")) { MySQL_ArtResultSet::row_t rs_data_row; CPP_INFO_FMT("[][%s][%s][TABLE][]", current_schema.c_str(), rs2->getString(1).c_str()); rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(current_schema); // TABLE_SCHEM rs_data_row.push_back(rs2->getString(1)); // TABLE_NAME rs_data_row.push_back("TABLE"); // TABLE_TYPE rs_data_row.push_back(""); // REMARKS rs_data->push_back(rs_data_row); break; } else if (!it->compare(rs2->getString(2)) && server_version > 49999) { MySQL_ArtResultSet::row_t rs_data_row; CPP_INFO_FMT("[][%s][%s][TABLE][]", current_schema.c_str(), rs2->getString(1).c_str()); rs_data_row.push_back("def"); // TABLE_CAT rs_data_row.push_back(current_schema); // TABLE_SCHEM rs_data_row.push_back(rs2->getString(1)); // TABLE_NAME rs_data_row.push_back("VIEW"); // TABLE_TYPE rs_data_row.push_back(""); // REMARKS rs_data->push_back(rs_data_row); break; } } } } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTableTypes() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getTableTypes() { CPP_ENTER("MySQL_ConnectionMetaData::getTableTypes"); static const char * const table_types[] = {"TABLE", "VIEW", "LOCAL TEMPORARY"}; static unsigned int requiredVersion[] = {32200, 50000, 32200}; std::list rs_field_data; rs_field_data.push_back("TABLE_TYPE"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); for (unsigned int i = 0; i < 3; ++i) { if (server_version >= requiredVersion[i]) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(table_types[i]); rs_data->push_back(rs_data_row); } } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTableCollation() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getTableCollation(const sql::SQLString& /* catalog */, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) { CPP_ENTER("MySQL_ConnectionMetaData::getTableCollation"); CPP_INFO_FMT("schemaPattern=%s tablePattern=%s", schemaPattern.c_str(), tableNamePattern.c_str()); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); sql::SQLString escapedTableNamePattern = connection->escapeString(tableNamePattern); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEMA"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("TABLE_COLLATION"); sql::SQLString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEMA, " "TABLE_NAME, TABLE_COLLATION FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME LIKE '"); query.append(escapedTableNamePattern).append("' ").append("AND TABLE_SCHEMA LIKE '"); query.append(escapedSchemaPattern).append("'"); boost::scoped_ptr< sql::Statement > stmt(connection->createStatement()); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery(query)); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // TABLE_COLLATION rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTableCharset() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getTableCharset(const sql::SQLString& /* catalog */, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) { CPP_ENTER("MySQL_ConnectionMetaData::getTableCharset"); CPP_INFO_FMT("schemaPattern=%s tablePattern=%s", schemaPattern.c_str(), tableNamePattern.c_str()); sql::SQLString escapedSchemaPattern = connection->escapeString(schemaPattern); sql::SQLString escapedTableNamePattern = connection->escapeString(tableNamePattern); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); std::list rs_field_data; rs_field_data.push_back("TABLE_CAT"); rs_field_data.push_back("TABLE_SCHEMA"); rs_field_data.push_back("TABLE_NAME"); rs_field_data.push_back("TABLE_CHARSET"); sql::SQLString query("SELECT t.TABLE_CATALOG AS TABLE_CAT, t.TABLE_SCHEMA AS TABLE_SCHEMA, t.TABLE_NAME, " "c.CHARACTER_SET_NAME AS TABLE_CHARSET FROM INFORMATION_SCHEMA.TABLES t, " "INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY c " "WHERE t.TABLE_COLLATION = c.COLLATION_NAME AND t.TABLE_NAME LIKE '"); query.append(escapedTableNamePattern).append("' ").append("AND t.TABLE_SCHEMA LIKE '"); query.append(escapedSchemaPattern).append("'"); boost::scoped_ptr< sql::Statement > stmt(connection->createStatement()); boost::scoped_ptr< sql::ResultSet > rs(stmt->executeQuery(query)); while (rs->next()) { MySQL_ArtResultSet::row_t rs_data_row; rs_data_row.push_back(rs->getString(1)); // TABLE_CAT rs_data_row.push_back(rs->getString(2)); // TABLE_SCHEM rs_data_row.push_back(rs->getString(3)); // TABLE_NAME rs_data_row.push_back(rs->getString(4)); // TABLE_CHARSET rs_data->push_back(rs_data_row); } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTimeDateFunctions() -I- */ const sql::SQLString& MySQL_ConnectionMetaData::getTimeDateFunctions() { CPP_ENTER("MySQL_ConnectionMetaData::getTimeDateFunctions"); static const sql::SQLString funcs( "DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR,MONTH,DAYNAME," "MONTHNAME,QUARTER,WEEK,YEAR,HOUR,MINUTE,SECOND,PERIOD_ADD," "PERIOD_DIFF,TO_DAYS,FROM_DAYS,DATE_FORMAT,TIME_FORMAT," "CURDATE,CURRENT_DATE,CURTIME,CURRENT_TIME,NOW,SYSDATE," "CURRENT_TIMESTAMP,UNIX_TIMESTAMP,FROM_UNIXTIME," "SEC_TO_TIME,TIME_TO_SEC"); return funcs; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getTypeInfo() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getTypeInfo() { CPP_ENTER("MySQL_ConnectionMetaData::getTypeInfo"); std::list rs_field_data; rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("PRECISION"); rs_field_data.push_back("LITERAL_PREFIX"); rs_field_data.push_back("LITERAL_SUFFIX"); rs_field_data.push_back("CREATE_PARAMS"); rs_field_data.push_back("NULLABLE"); rs_field_data.push_back("CASE_SENSITIVE"); rs_field_data.push_back("SEARCHABLE"); rs_field_data.push_back("UNSIGNED_ATTRIBUTE"); rs_field_data.push_back("FIXED_PREC_SCALE"); rs_field_data.push_back("AUTO_INCREMENT"); rs_field_data.push_back("LOCAL_TYPE_NAME"); rs_field_data.push_back("MINIMUM_SCALE"); rs_field_data.push_back("MAXIMUM_SCALE"); rs_field_data.push_back("SQL_DATA_TYPE"); rs_field_data.push_back("SQL_DATETIME_SUB"); rs_field_data.push_back("NUM_PREC_RADIX"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); int i = 0; while (mysqlc_types[i].typeName) { MySQL_ArtResultSet::row_t rs_data_row; const TypeInfoDef * const curr = &mysqlc_types[i]; rs_data_row.push_back(curr->typeName); rs_data_row.push_back((int64_t) curr->dataType); rs_data_row.push_back((int64_t) curr->precision); rs_data_row.push_back(curr->literalPrefix); rs_data_row.push_back(curr->literalSuffix); rs_data_row.push_back(curr->createParams); rs_data_row.push_back((int64_t) curr->nullable); rs_data_row.push_back((int64_t) curr->caseSensitive); rs_data_row.push_back((int64_t) curr->searchable); rs_data_row.push_back((int64_t) curr->isUnsigned); rs_data_row.push_back((int64_t) curr->fixedPrecScale); rs_data_row.push_back((int64_t) curr->autoIncrement); rs_data_row.push_back(curr->localTypeName); rs_data_row.push_back((int64_t) curr->minScale); rs_data_row.push_back((int64_t) curr->maxScale); rs_data_row.push_back((int64_t) curr->sqlDataType); rs_data_row.push_back((int64_t) curr->sqlDateTimeSub); rs_data_row.push_back((int64_t) curr->numPrecRadix); rs_data->push_back(rs_data_row); ++i; } MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getUDTs() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getUDTs(const sql::SQLString& /*catalog*/, const sql::SQLString& /*schemaPattern*/, const sql::SQLString& /*typeNamePattern*/, std::list & /*types*/) { CPP_ENTER("MySQL_ConnectionMetaData::getUDTs"); std::list rs_field_data; rs_field_data.push_back("TYPE_CAT"); rs_field_data.push_back("TYPE_SCHEM"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("CLASS_NAME"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("REMARKS"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getURL() -U- */ SQLString MySQL_ConnectionMetaData::getURL() { CPP_ENTER("MySQL_ConnectionMetaData::getURL"); throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::getURL"); return ""; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getUserName() -I- */ SQLString MySQL_ConnectionMetaData::getUserName() { CPP_ENTER("MySQL_ConnectionMetaData::getUserName"); boost::scoped_ptr< sql::ResultSet > rset(stmt->executeQuery("SELECT USER()")); if (rset->next()) { return sql::SQLString(rset->getString(1)); } return ""; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::getVersionColumns() -I- */ sql::ResultSet * MySQL_ConnectionMetaData::getVersionColumns(const sql::SQLString& /*catalog*/, const sql::SQLString& /*schema*/, const sql::SQLString& /*table*/) { CPP_ENTER("MySQL_ConnectionMetaData::getVersionColumns"); std::list rs_field_data; rs_field_data.push_back("SCOPE"); rs_field_data.push_back("COLUMN_NAME"); rs_field_data.push_back("DATA_TYPE"); rs_field_data.push_back("TYPE_NAME"); rs_field_data.push_back("COLUMN_SIZE"); rs_field_data.push_back("BUFFER_LENGTH"); rs_field_data.push_back("DECIMAL_DIGITS"); rs_field_data.push_back("PSEUDO_COLUMN"); boost::shared_ptr< MySQL_ArtResultSet::rset_t > rs_data(new MySQL_ArtResultSet::rset_t()); MySQL_ArtResultSet * ret = new MySQL_ArtResultSet(rs_field_data, rs_data, logger); return ret; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::insertsAreDetected() -I- */ bool MySQL_ConnectionMetaData::insertsAreDetected(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::insertsAreDetected"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::isCatalogAtStart() -I- */ bool MySQL_ConnectionMetaData::isCatalogAtStart() { CPP_ENTER("MySQL_ConnectionMetaData::isCatalogAtStart"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::isReadOnly() -I- */ bool MySQL_ConnectionMetaData::isReadOnly() { return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::locatorsUpdateCopy() -U- */ bool MySQL_ConnectionMetaData::locatorsUpdateCopy() { CPP_ENTER("MySQL_ConnectionMetaData::locatorsUpdateCopy"); throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::locatorsUpdateCopy"); return false; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ConnectionMetaData::nullPlusNonNullIsNull() -I- */ bool MySQL_ConnectionMetaData::nullPlusNonNullIsNull() { CPP_ENTER("MySQL_ConnectionMetaData::nullPlusNonNullIsNull"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::nullsAreSortedAtEnd() -I- */ bool MySQL_ConnectionMetaData::nullsAreSortedAtEnd() { CPP_ENTER("MySQL_ConnectionMetaData::nullsAreSortedAtEnd"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::nullsAreSortedAtStart() -I- */ bool MySQL_ConnectionMetaData::nullsAreSortedAtStart() { CPP_ENTER("MySQL_ConnectionMetaData::nullsAreSortedAtStart"); return server_version > 40001 && server_version < 40011; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::nullsAreSortedHigh() -I- */ bool MySQL_ConnectionMetaData::nullsAreSortedHigh() { CPP_ENTER("MySQL_ConnectionMetaData::nullsAreSortedHigh"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::nullsAreSortedLow() -I- */ bool MySQL_ConnectionMetaData::nullsAreSortedLow() { CPP_ENTER("MySQL_ConnectionMetaData::nullsAreSortedLow"); return !nullsAreSortedHigh(); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::othersDeletesAreVisible() -I- */ bool MySQL_ConnectionMetaData::othersDeletesAreVisible(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::othersDeletesAreVisible"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::othersInsertsAreVisible() -I- */ bool MySQL_ConnectionMetaData::othersInsertsAreVisible(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::othersInsertsAreVisible"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::othersUpdatesAreVisible() -I- */ bool MySQL_ConnectionMetaData::othersUpdatesAreVisible(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::othersUpdatesAreVisible"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::ownDeletesAreVisible() -I- */ bool MySQL_ConnectionMetaData::ownDeletesAreVisible(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::ownDeletesAreVisible"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::ownInsertsAreVisible() -I- */ bool MySQL_ConnectionMetaData::ownInsertsAreVisible(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::ownInsertsAreVisible"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::ownUpdatesAreVisible() -I- */ bool MySQL_ConnectionMetaData::ownUpdatesAreVisible(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::ownUpdatesAreVisible"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::storesLowerCaseIdentifiers() -I- */ bool MySQL_ConnectionMetaData::storesLowerCaseIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::storesLowerCaseIdentifiers"); return (lower_case_table_names.compare("1")==0 || lower_case_table_names.compare("2")==0); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::storesLowerCaseQuotedIdentifiers() -I- */ bool MySQL_ConnectionMetaData::storesLowerCaseQuotedIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::storesLowerCaseQuotedIdentifiers"); return (lower_case_table_names.compare("1")==0 || lower_case_table_names.compare("2")==0); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::storesMixedCaseIdentifiers() -I- */ bool MySQL_ConnectionMetaData::storesMixedCaseIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::storesMixedCaseIdentifiers"); return !(lower_case_table_names.compare("1")==0 || lower_case_table_names.compare("2")==0); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::storesMixedCaseQuotedIdentifiers() -I- */ bool MySQL_ConnectionMetaData::storesMixedCaseQuotedIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::storesMixedCaseQuotedIdentifiers"); return !(lower_case_table_names.compare("1")==0 || lower_case_table_names.compare("2")==0); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::storesUpperCaseIdentifiers() -I- */ bool MySQL_ConnectionMetaData::storesUpperCaseIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::storesUpperCaseIdentifiers"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::storesUpperCaseQuotedIdentifiers() -I- */ bool MySQL_ConnectionMetaData::storesUpperCaseQuotedIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::storesUpperCaseQuotedIdentifiers"); return true; // not actually true, but required by JDBC spec!? } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsAlterTableWithAddColumn() -I- */ bool MySQL_ConnectionMetaData::supportsAlterTableWithAddColumn() { CPP_ENTER("MySQL_ConnectionMetaData::supportsAlterTableWithAddColumn"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsAlterTableWithDropColumn() -I- */ bool MySQL_ConnectionMetaData::supportsAlterTableWithDropColumn() { CPP_ENTER("MySQL_ConnectionMetaData::supportsAlterTableWithDropColumn"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsANSI92EntryLevelSQL -I- */ bool MySQL_ConnectionMetaData::supportsANSI92EntryLevelSQL() { CPP_ENTER("MySQL_ConnectionMetaData::supportsANSI92EntryLevelSQL"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsANSI92FullSQL() -I- */ bool MySQL_ConnectionMetaData::supportsANSI92FullSQL() { CPP_ENTER("MySQL_ConnectionMetaData::supportsANSI92FullSQL"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsANSI92IntermediateSQL() -I- */ bool MySQL_ConnectionMetaData::supportsANSI92IntermediateSQL() { CPP_ENTER("MySQL_ConnectionMetaData::supportsANSI92IntermediateSQL"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsBatchUpdates() -I- */ bool MySQL_ConnectionMetaData::supportsBatchUpdates() { CPP_ENTER("MySQL_ConnectionMetaData::supportsBatchUpdates"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCatalogsInDataManipulation() -I- */ bool MySQL_ConnectionMetaData::supportsCatalogsInDataManipulation() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCatalogsInDataManipulation"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCatalogsInIndexDefinitions() -I- */ bool MySQL_ConnectionMetaData::supportsCatalogsInIndexDefinitions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCatalogsInIndexDefinitions"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCatalogsInPrivilegeDefinitions() -I- */ bool MySQL_ConnectionMetaData::supportsCatalogsInPrivilegeDefinitions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCatalogsInPrivilegeDefinitions"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCatalogsInProcedureCalls() -I- */ bool MySQL_ConnectionMetaData::supportsCatalogsInProcedureCalls() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCatalogsInProcedureCalls"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCatalogsInTableDefinitions() -I- */ bool MySQL_ConnectionMetaData::supportsCatalogsInTableDefinitions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCatalogsInTableDefinitions"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsColumnAliasing() -I- */ bool MySQL_ConnectionMetaData::supportsColumnAliasing() { CPP_ENTER("MySQL_ConnectionMetaData::supportsColumnAliasing"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsConvert() -I- */ bool MySQL_ConnectionMetaData::supportsConvert() { CPP_ENTER("MySQL_ConnectionMetaData::supportsConvert"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsConvert() -I- */ bool MySQL_ConnectionMetaData::supportsConvert(int fromType, int toType) { CPP_ENTER("MySQL_ConnectionMetaData::supportsConvert"); switch (fromType) { // The char/binary types can be converted to pretty much anything. case sql::DataType::CHAR: case sql::DataType::VARCHAR: case sql::DataType::LONGVARCHAR: case sql::DataType::BINARY: case sql::DataType::VARBINARY: case sql::DataType::LONGVARBINARY: { switch (toType) { case sql::DataType::DECIMAL: case sql::DataType::NUMERIC: case sql::DataType::REAL: case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: case sql::DataType::DOUBLE: case sql::DataType::CHAR: case sql::DataType::VARCHAR: case sql::DataType::LONGVARCHAR: case sql::DataType::BINARY: case sql::DataType::VARBINARY: case sql::DataType::LONGVARBINARY: case sql::DataType::DATE: case sql::DataType::TIME: case sql::DataType::TIMESTAMP: return true; default: return false; } } // We don't handle the BIT type yet. case sql::DataType::BIT: return false; // The numeric types. Basically they can convert among themselves, and case sql::DataType::DECIMAL: case sql::DataType::NUMERIC: case sql::DataType::REAL: case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: case sql::DataType::DOUBLE: { switch (toType) { case sql::DataType::DECIMAL: case sql::DataType::NUMERIC: case sql::DataType::REAL: case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: case sql::DataType::DOUBLE: case sql::DataType::CHAR: case sql::DataType::VARCHAR: case sql::DataType::LONGVARCHAR: case sql::DataType::BINARY: case sql::DataType::VARBINARY: case sql::DataType::LONGVARBINARY: return true; default: return false; } } // MySQL doesn't support a NULL type case sql::DataType::SQLNULL: return false; // Dates can be converted to char/binary types case sql::DataType::DATE: { switch (toType) { case sql::DataType::CHAR: case sql::DataType::VARCHAR: case sql::DataType::LONGVARCHAR: case sql::DataType::BINARY: case sql::DataType::VARBINARY: case sql::DataType::LONGVARBINARY: return true; default: return false; } } // Time can be converted to char/binary types case sql::DataType::TIME: { switch (toType) { case sql::DataType::CHAR: case sql::DataType::VARCHAR: case sql::DataType::LONGVARCHAR: case sql::DataType::BINARY: case sql::DataType::VARBINARY: case sql::DataType::LONGVARBINARY: return true; default: return false; } } // Timestamp can be converted to char/binary types and date/time types (with loss of precision). case sql::DataType::TIMESTAMP: { switch (toType) { case sql::DataType::CHAR: case sql::DataType::VARCHAR: case sql::DataType::LONGVARCHAR: case sql::DataType::BINARY: case sql::DataType::VARBINARY: case sql::DataType::LONGVARBINARY: case sql::DataType::TIME: case sql::DataType::DATE: return true; default: return false; } } // We shouldn't get here! default: return false; // not sure } } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCoreSQLGrammar() -I- */ bool MySQL_ConnectionMetaData::supportsCoreSQLGrammar() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCoreSQLGrammar"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsCorrelatedSubqueries() -I- */ bool MySQL_ConnectionMetaData::supportsCorrelatedSubqueries() { CPP_ENTER("MySQL_ConnectionMetaData::supportsCorrelatedSubqueries"); return server_version >= 40100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsDataDefinitionAndDataManipulationTransactions() -I- */ bool MySQL_ConnectionMetaData::supportsDataDefinitionAndDataManipulationTransactions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsDataDefinitionAndDataManipulationTransactions"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsDataManipulationTransactionsOnly() -I- */ bool MySQL_ConnectionMetaData::supportsDataManipulationTransactionsOnly() { CPP_ENTER("MySQL_ConnectionMetaData::supportsDataManipulationTransactionsOnly"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsDifferentTableCorrelationNames() -I- */ bool MySQL_ConnectionMetaData::supportsDifferentTableCorrelationNames() { CPP_ENTER("MySQL_ConnectionMetaData::supportsDifferentTableCorrelationNames"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsExpressionsInOrderBy() -I- */ bool MySQL_ConnectionMetaData::supportsExpressionsInOrderBy() { CPP_ENTER("MySQL_ConnectionMetaData::supportsExpressionsInOrderBy"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsExtendedSQLGrammar() -I- */ bool MySQL_ConnectionMetaData::supportsExtendedSQLGrammar() { CPP_ENTER("MySQL_ConnectionMetaData::supportsExtendedSQLGrammar"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsFullOuterJoins() -I- */ bool MySQL_ConnectionMetaData::supportsFullOuterJoins() { CPP_ENTER("MySQL_ConnectionMetaData::supportsFullOuterJoins"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsGetGeneratedKeys() -I- */ bool MySQL_ConnectionMetaData::supportsGetGeneratedKeys() { CPP_ENTER("MySQL_ConnectionMetaData::supportsGetGeneratedKeys"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsGroupBy() -I- */ bool MySQL_ConnectionMetaData::supportsGroupBy() { CPP_ENTER("MySQL_ConnectionMetaData::supportsGroupBy"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsGroupByBeyondSelect() -I- */ bool MySQL_ConnectionMetaData::supportsGroupByBeyondSelect() { CPP_ENTER("MySQL_ConnectionMetaData::supportsGroupByBeyondSelect"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsGroupByUnrelated() -I- */ bool MySQL_ConnectionMetaData::supportsGroupByUnrelated() { CPP_ENTER("MySQL_ConnectionMetaData::supportsGroupByUnrelated"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsIntegrityEnhancementFacility() -U- */ bool MySQL_ConnectionMetaData::supportsIntegrityEnhancementFacility() { CPP_ENTER("MySQL_ConnectionMetaData::supportsIntegrityEnhancementFacility"); throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::supportsIntegrityEnhancementFacility"); return false; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsLikeEscapeClause() -I- */ bool MySQL_ConnectionMetaData::supportsLikeEscapeClause() { CPP_ENTER("MySQL_ConnectionMetaData::supportsLikeEscapeClause"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsLimitedOuterJoins() -I- */ bool MySQL_ConnectionMetaData::supportsLimitedOuterJoins() { CPP_ENTER("MySQL_ConnectionMetaData::supportsLimitedOuterJoins"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsMinimumSQLGrammar() -I- */ bool MySQL_ConnectionMetaData::supportsMinimumSQLGrammar() { CPP_ENTER("MySQL_ConnectionMetaData::supportsMinimumSQLGrammar"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsMixedCaseIdentifiers() -I- */ bool MySQL_ConnectionMetaData::supportsMixedCaseIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::supportsMixedCaseIdentifiers"); return !((lower_case_table_names.compare("1") || lower_case_table_names.compare("2"))); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsMixedCaseQuotedIdentifiers() -I- */ bool MySQL_ConnectionMetaData::supportsMixedCaseQuotedIdentifiers() { CPP_ENTER("MySQL_ConnectionMetaData::supportsMixedCaseQuotedIdentifiers"); return !((lower_case_table_names.compare("1") || lower_case_table_names.compare("2"))); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsMultipleOpenResults() -I- */ bool MySQL_ConnectionMetaData::supportsMultipleOpenResults() { CPP_ENTER("MySQL_ConnectionMetaData::supportsMultipleOpenResults"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsMultipleResultSets() -I- */ bool MySQL_ConnectionMetaData::supportsMultipleResultSets() { CPP_ENTER("MySQL_ConnectionMetaData::supportsMultipleResultSets"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsMultipleTransactions() -I- */ bool MySQL_ConnectionMetaData::supportsMultipleTransactions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsMultipleTransactions"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsNamedParameters() -I- */ bool MySQL_ConnectionMetaData::supportsNamedParameters() { CPP_ENTER("MySQL_ConnectionMetaData::supportsNamedParameters"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsNonNullableColumns() -I- */ bool MySQL_ConnectionMetaData::supportsNonNullableColumns() { CPP_ENTER("MySQL_ConnectionMetaData::supportsNonNullableColumns"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsOpenCursorsAcrossCommit() -I- */ bool MySQL_ConnectionMetaData::supportsOpenCursorsAcrossCommit() { CPP_ENTER("MySQL_ConnectionMetaData::supportsOpenCursorsAcrossCommit"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsOpenCursorsAcrossRollback() -I- */ bool MySQL_ConnectionMetaData::supportsOpenCursorsAcrossRollback() { CPP_ENTER("MySQL_ConnectionMetaData::supportsOpenCursorsAcrossRollback"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsOpenStatementsAcrossCommit() -I- */ bool MySQL_ConnectionMetaData::supportsOpenStatementsAcrossCommit() { CPP_ENTER("MySQL_ConnectionMetaData::supportsOpenStatementsAcrossCommit"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsOpenStatementsAcrossRollback() -I- */ bool MySQL_ConnectionMetaData::supportsOpenStatementsAcrossRollback() { CPP_ENTER("MySQL_ConnectionMetaData::supportsOpenStatementsAcrossRollback"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsOrderByUnrelated() -I- */ bool MySQL_ConnectionMetaData::supportsOrderByUnrelated() { CPP_ENTER("MySQL_ConnectionMetaData::supportsOrderByUnrelated"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsOuterJoins() -I- */ bool MySQL_ConnectionMetaData::supportsOuterJoins() { CPP_ENTER("MySQL_ConnectionMetaData::supportsOuterJoins"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsPositionedDelete() -I- */ bool MySQL_ConnectionMetaData::supportsPositionedDelete() { CPP_ENTER("MySQL_ConnectionMetaData::supportsPositionedDelete"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsPositionedUpdate() -I- */ bool MySQL_ConnectionMetaData::supportsPositionedUpdate() { CPP_ENTER("MySQL_ConnectionMetaData::supportsPositionedUpdate"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsResultSetConcurrency() -U- */ bool MySQL_ConnectionMetaData::supportsResultSetConcurrency(int /* type */, int /* concurrency */) { CPP_ENTER("MySQL_ConnectionMetaData::supportsResultSetConcurrency"); throw sql::MethodNotImplementedException("MySQL_ConnectionMetaData::supportsResultSetConcurrency"); return false; // This will shut up compilers } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsResultSetHoldability() -I- */ bool MySQL_ConnectionMetaData::supportsResultSetHoldability(int holdability) { CPP_ENTER("MySQL_ConnectionMetaData::supportsResultSetHoldability"); return (holdability == sql::ResultSet::HOLD_CURSORS_OVER_COMMIT); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsResultSetType() -I- */ bool MySQL_ConnectionMetaData::supportsResultSetType(int type) { CPP_ENTER("MySQL_ConnectionMetaData::supportsResultSetType"); return (type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSavepoints() -I- */ bool MySQL_ConnectionMetaData::supportsSavepoints() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSavepoints"); return (server_version >= 40014 || server_version >= 40101); } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSchemasInDataManipulation() -I- */ bool MySQL_ConnectionMetaData::supportsSchemasInDataManipulation() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSchemasInDataManipulation"); return server_version >= 32200; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSchemasInIndexDefinitions() -I- */ bool MySQL_ConnectionMetaData::supportsSchemasInIndexDefinitions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSchemasInIndexDefinitions"); return server_version >= 32200; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSchemasInPrivilegeDefinitions() -I- */ bool MySQL_ConnectionMetaData::supportsSchemasInPrivilegeDefinitions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSchemasInPrivilegeDefinitions"); return server_version > 32200; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSchemasInProcedureCalls() -I- */ bool MySQL_ConnectionMetaData::supportsSchemasInProcedureCalls() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSchemasInProcedureCalls"); return server_version >= 32200; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSchemasInTableDefinitions() -I- */ bool MySQL_ConnectionMetaData::supportsSchemasInTableDefinitions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSchemasInTableDefinitions"); return server_version >= 32200; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSelectForUpdate() -I- */ bool MySQL_ConnectionMetaData::supportsSelectForUpdate() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSelectForUpdate"); return server_version >= 40000; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsStatementPooling() -I- */ bool MySQL_ConnectionMetaData::supportsStatementPooling() { CPP_ENTER("MySQL_ConnectionMetaData::supportsStatementPooling"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsStoredProcedures() -I- */ bool MySQL_ConnectionMetaData::supportsStoredProcedures() { CPP_ENTER("MySQL_ConnectionMetaData::supportsStoredProcedures"); return server_version >= 50000; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSubqueriesInComparisons() -I- */ bool MySQL_ConnectionMetaData::supportsSubqueriesInComparisons() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSubqueriesInComparisons"); return server_version >= 40100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSubqueriesInExists() -I- */ bool MySQL_ConnectionMetaData::supportsSubqueriesInExists() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSubqueriesInExists"); return server_version >= 40100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSubqueriesInIns() -I- */ bool MySQL_ConnectionMetaData::supportsSubqueriesInIns() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSubqueriesInIns"); return server_version >= 40100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsSubqueriesInQuantifieds() -I- */ bool MySQL_ConnectionMetaData::supportsSubqueriesInQuantifieds() { CPP_ENTER("MySQL_ConnectionMetaData::supportsSubqueriesInQuantifieds"); return server_version >= 40100; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsTableCorrelationNames() -I- */ bool MySQL_ConnectionMetaData::supportsTableCorrelationNames() { CPP_ENTER("MySQL_ConnectionMetaData::supportsTableCorrelationNames"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsTransactionIsolationLevel() -I- */ bool MySQL_ConnectionMetaData::supportsTransactionIsolationLevel(int /* level */) { CPP_ENTER("MySQL_ConnectionMetaData::supportsTransactionIsolationLevel"); return server_version >= 32336; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsTransactions() -I- */ bool MySQL_ConnectionMetaData::supportsTransactions() { CPP_ENTER("MySQL_ConnectionMetaData::supportsTransactions"); return server_version >= 32315; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsTypeConversion() -I- */ bool MySQL_ConnectionMetaData::supportsTypeConversion() { CPP_ENTER("MySQL_ConnectionMetaData::supportsTypeConversion"); return true; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsUnion() -I- */ bool MySQL_ConnectionMetaData::supportsUnion() { CPP_ENTER("MySQL_ConnectionMetaData::supportsUnion"); return server_version >= 40000; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::supportsUnionAll() -I- */ bool MySQL_ConnectionMetaData::supportsUnionAll() { CPP_ENTER("MySQL_ConnectionMetaData::supportsUnionAll"); return server_version >= 40000; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::updatesAreDetected() -I- */ bool MySQL_ConnectionMetaData::updatesAreDetected(int /* type */) { CPP_ENTER("MySQL_ConnectionMetaData::updatesAreDetected"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::usesLocalFilePerTable() -I- */ bool MySQL_ConnectionMetaData::usesLocalFilePerTable() { CPP_ENTER("MySQL_ConnectionMetaData::usesLocalFilePerTable"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::usesLocalFiles() -I- */ bool MySQL_ConnectionMetaData::usesLocalFiles() { CPP_ENTER("MySQL_ConnectionMetaData::usesLocalFiles"); return false; } /* }}} */ /* {{{ MySQL_ConnectionMetaData::matchTable() -I- */ bool MySQL_ConnectionMetaData::matchTable(const sql::SQLString & sPattern, const sql::SQLString & tPattern, const sql::SQLString & schema, const sql::SQLString & table) { CPP_ENTER("MySQL_ConnectionMetaData::matchTable"); return (!sPattern.compare("*") || !sPattern.compare(schema)) && (!tPattern.compare("*") || !tPattern.compare(table)); } } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_metadata.h000644 015771 000012 00000030167 12645244436 022443 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_METADATA_H_ #define _MYSQL_METADATA_H_ #include #include #include namespace sql { class ResultSet; namespace mysql { class MySQL_Connection; class MySQL_DebugLogger; namespace NativeAPI { class IMySQLCAPI; } class MySQL_ConnectionMetaData : public sql::DatabaseMetaData { sql::Statement * stmt; MySQL_Connection * connection; unsigned long server_version; boost::shared_ptr< MySQL_DebugLogger > logger; boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy; sql::SQLString lower_case_table_names; bool use_info_schema; public: MySQL_ConnectionMetaData(sql::Statement * const service, boost::shared_ptr _capi, boost::shared_ptr< MySQL_DebugLogger > & l); virtual ~MySQL_ConnectionMetaData(); bool allProceduresAreCallable(); bool allTablesAreSelectable(); bool dataDefinitionCausesTransactionCommit(); bool dataDefinitionIgnoredInTransactions(); bool deletesAreDetected(int type); bool doesMaxRowSizeIncludeBlobs(); sql::ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern); sql::ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable); sql::ResultSet * getCatalogs(); const sql::SQLString& getCatalogSeparator(); const sql::SQLString& getCatalogTerm(); sql::ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern); sql::ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern); sql::Connection * getConnection(); sql::ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable); unsigned int getDatabaseMajorVersion(); unsigned int getDatabaseMinorVersion(); unsigned int getDatabasePatchVersion(); const sql::SQLString& getDatabaseProductName(); SQLString getDatabaseProductVersion(); int getDefaultTransactionIsolation(); unsigned int getDriverMajorVersion(); unsigned int getDriverMinorVersion(); unsigned int getDriverPatchVersion(); const sql::SQLString& getDriverName(); const sql::SQLString& getDriverVersion(); sql::ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table); const sql::SQLString& getExtraNameCharacters(); const sql::SQLString& getIdentifierQuoteString(); sql::ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table); sql::ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate); unsigned int getCDBCMajorVersion(); unsigned int getCDBCMinorVersion(); unsigned int getMaxBinaryLiteralLength(); unsigned int getMaxCatalogNameLength(); unsigned int getMaxCharLiteralLength(); unsigned int getMaxColumnNameLength(); unsigned int getMaxColumnsInGroupBy(); unsigned int getMaxColumnsInIndex(); unsigned int getMaxColumnsInOrderBy(); unsigned int getMaxColumnsInSelect(); unsigned int getMaxColumnsInTable(); unsigned int getMaxConnections(); unsigned int getMaxCursorNameLength(); unsigned int getMaxIndexLength(); unsigned int getMaxProcedureNameLength(); unsigned int getMaxRowSize(); unsigned int getMaxSchemaNameLength(); unsigned int getMaxStatementLength(); unsigned int getMaxStatements(); unsigned int getMaxTableNameLength(); unsigned int getMaxTablesInSelect(); unsigned int getMaxUserNameLength(); const sql::SQLString& getNumericFunctions(); sql::ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table); sql::ResultSet * getUniqueNonNullableKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table); sql::ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern); sql::ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern); const sql::SQLString& getProcedureTerm(); int getResultSetHoldability(); sql::ResultSet * getSchemas(); const sql::SQLString& getSchemaTerm(); sql::ResultSet * getSchemaCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern); sql::ResultSet * getSchemaCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern); const sql::SQLString& getSearchStringEscape(); const sql::SQLString& getSQLKeywords(); int getSQLStateType(); const sql::SQLString& getStringFunctions(); sql::ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern); sql::ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern); const sql::SQLString& getSystemFunctions(); sql::ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern); sql::ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list &types); sql::ResultSet * getTableTypes(); sql::ResultSet * getTableCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern); sql::ResultSet * getTableCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern); const sql::SQLString& getTimeDateFunctions(); sql::ResultSet * getTypeInfo(); sql::ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list &types); SQLString getURL(); SQLString getUserName(); sql::ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table); bool insertsAreDetected(int type); bool isCatalogAtStart(); bool isReadOnly(); bool locatorsUpdateCopy(); bool nullPlusNonNullIsNull(); bool nullsAreSortedAtEnd(); bool nullsAreSortedAtStart(); bool nullsAreSortedHigh(); bool nullsAreSortedLow(); bool othersDeletesAreVisible(int type); bool othersInsertsAreVisible(int type); bool othersUpdatesAreVisible(int type); bool ownDeletesAreVisible(int type); bool ownInsertsAreVisible(int type); bool ownUpdatesAreVisible(int type); bool storesLowerCaseIdentifiers(); bool storesLowerCaseQuotedIdentifiers(); bool storesMixedCaseIdentifiers(); bool storesMixedCaseQuotedIdentifiers(); bool storesUpperCaseIdentifiers(); bool storesUpperCaseQuotedIdentifiers(); bool supportsAlterTableWithAddColumn(); bool supportsAlterTableWithDropColumn(); bool supportsANSI92EntryLevelSQL(); bool supportsANSI92FullSQL(); bool supportsANSI92IntermediateSQL(); bool supportsBatchUpdates(); bool supportsCatalogsInDataManipulation(); bool supportsCatalogsInIndexDefinitions(); bool supportsCatalogsInPrivilegeDefinitions(); bool supportsCatalogsInProcedureCalls(); bool supportsCatalogsInTableDefinitions(); bool supportsColumnAliasing(); bool supportsConvert(); bool supportsConvert(int fromType, int toType); bool supportsCoreSQLGrammar(); bool supportsCorrelatedSubqueries(); bool supportsDataDefinitionAndDataManipulationTransactions(); bool supportsDataManipulationTransactionsOnly(); bool supportsDifferentTableCorrelationNames(); bool supportsExpressionsInOrderBy(); bool supportsExtendedSQLGrammar(); bool supportsFullOuterJoins(); bool supportsGetGeneratedKeys(); bool supportsGroupBy(); bool supportsGroupByBeyondSelect(); bool supportsGroupByUnrelated(); bool supportsIntegrityEnhancementFacility(); bool supportsLikeEscapeClause(); bool supportsLimitedOuterJoins(); bool supportsMinimumSQLGrammar(); bool supportsMixedCaseIdentifiers(); bool supportsMixedCaseQuotedIdentifiers(); bool supportsMultipleOpenResults(); bool supportsMultipleResultSets(); bool supportsMultipleTransactions(); bool supportsNamedParameters(); bool supportsNonNullableColumns(); bool supportsOpenCursorsAcrossCommit(); bool supportsOpenCursorsAcrossRollback(); bool supportsOpenStatementsAcrossCommit(); bool supportsOpenStatementsAcrossRollback(); bool supportsOrderByUnrelated(); bool supportsOuterJoins(); bool supportsPositionedDelete(); bool supportsPositionedUpdate(); bool supportsResultSetConcurrency(int type, int concurrency); bool supportsResultSetHoldability(int holdability); bool supportsResultSetType(int type); bool supportsSavepoints(); bool supportsSchemasInDataManipulation(); bool supportsSchemasInIndexDefinitions(); bool supportsSchemasInPrivilegeDefinitions(); bool supportsSchemasInProcedureCalls(); bool supportsSchemasInTableDefinitions(); bool supportsSelectForUpdate(); bool supportsStatementPooling(); bool supportsStoredProcedures(); bool supportsSubqueriesInComparisons(); bool supportsSubqueriesInExists(); bool supportsSubqueriesInIns(); bool supportsSubqueriesInQuantifieds(); bool supportsTableCorrelationNames(); bool supportsTransactionIsolationLevel(int level); bool supportsTransactions(); bool supportsTypeConversion(); bool supportsUnion(); bool supportsUnionAll(); bool updatesAreDetected(int type); bool usesLocalFilePerTable(); bool usesLocalFiles(); sql::ResultSet *getSchemata(const sql::SQLString& catalogName = ""); sql::ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "", const sql::SQLString& schemaName = "", const sql::SQLString& objectType = "", bool includingDdl = true, const sql::SQLString& objectName = "", const sql::SQLString& contextTableName = ""); // Returns all schema object types this database supports sql::ResultSet *getSchemaObjectTypes(); private: bool matchTable(const sql::SQLString& sPattern, const sql::SQLString& tPattern, const sql::SQLString& schema, const sql::SQLString& table); bool parseImportedKeys( const sql::SQLString& def, sql::SQLString & constraint_name, std::map< sql::SQLString, sql::SQLString > & keywords_names, std::map< sql::SQLString, std::list< sql::SQLString > > & referenced_fields, std::map< sql::SQLString, int > & update_delete_action ); /* Prevent use of these */ MySQL_ConnectionMetaData(); MySQL_ConnectionMetaData(const MySQL_ConnectionMetaData &); void operator=(MySQL_ConnectionMetaData &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_METADATA_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_parameter_metadata.cpp000644 015771 000012 00000007701 12645244436 025034 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "mysql_parameter_metadata.h" #include "nativeapi/native_statement_wrapper.h" #include namespace sql { namespace mysql { /* {{{ MySQL_ParameterMetaData::MySQL_ParameterMetaData -I- */ MySQL_ParameterMetaData::MySQL_ParameterMetaData(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & stmt) { // 2nd parameter is to be changed to boost::shared_ptr in case it's kept in the object param_count= stmt->param_count(); } /* }}} */ /* {{{ MySQL_ParameterMetaData::getParameterClassName -U- */ sql::SQLString MySQL_ParameterMetaData::getParameterClassName(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return ""; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::getParameterCount -I- */ int MySQL_ParameterMetaData::getParameterCount() { return param_count; } /* }}} */ /* {{{ MySQL_ParameterMetaData::getParameterMode -U- */ int MySQL_ParameterMetaData::getParameterMode(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::getParameterType -U- */ int MySQL_ParameterMetaData::getParameterType(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::getParameterTypeName -U- */ sql::SQLString MySQL_ParameterMetaData::getParameterTypeName(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::getPrecision -U- */ int MySQL_ParameterMetaData::getPrecision(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::getScale -U- */ int MySQL_ParameterMetaData::getScale(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::isNullable -U- */ int MySQL_ParameterMetaData::isNullable(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ParameterMetaData::isSigned -U- */ bool MySQL_ParameterMetaData::isSigned(unsigned int /* paramNo */) { throw sql::MethodNotImplementedException("MySQL_ParameterMetaData::getParameterClassName()"); return 0; // fool compilers } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_parameter_metadata.h000644 015771 000012 00000004514 12645244436 024500 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_PARAMETER_METADATA_H_ #define _MYSQL_PARAMETER_METADATA_H_ #include #include namespace sql { namespace mysql { namespace NativeAPI { class NativeStatementWrapper; } class MySQL_ParameterMetaData : public sql::ParameterMetaData { unsigned int param_count; public: MySQL_ParameterMetaData( boost::shared_ptr< NativeAPI::NativeStatementWrapper > & stmt); virtual ~MySQL_ParameterMetaData() {} virtual sql::SQLString getParameterClassName(unsigned int paramNo); virtual int getParameterCount(); virtual int getParameterMode(unsigned int paramNo); virtual int getParameterType(unsigned int paramNo); virtual sql::SQLString getParameterTypeName(unsigned int paramNo); virtual int getPrecision(unsigned int paramNo); virtual int getScale(unsigned int paramNo); virtual int isNullable(unsigned int paramNo); virtual bool isSigned(unsigned int paramNo); private: /* Prevent use of these */ MySQL_ParameterMetaData(const MySQL_ParameterMetaData &); void operator=(MySQL_ParameterMetaData &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_PARAMETER_METADATA_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_prepared_statement.cpp000644 015771 000012 00000102262 12645244436 025100 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include "mysql_util.h" #include "mysql_connection.h" #include "mysql_statement.h" #include "mysql_prepared_statement.h" #include "mysql_ps_resultset.h" #include "mysql_ps_resultset_metadata.h" #include "mysql_parameter_metadata.h" #include "mysql_warning.h" #include "mysql_resultbind.h" #include "nativeapi/native_statement_wrapper.h" #include "mysql_debug.h" namespace sql { namespace mysql { static const unsigned int MAX_SEND_LONGDATA_BUFFER= 1 << 18; //1<<18=256k (for istream) static const unsigned int MAX_SEND_LONGDATA_CHUNK= 1 << 18; //1<<19=512k (for string) // Visitor class to send long data contained in blob_bind class LongDataSender : public boost::static_visitor { unsigned position; boost::shared_ptr< NativeAPI::NativeStatementWrapper > proxy; boost::shared_ptr logger; LongDataSender() {} public: LongDataSender(unsigned int i, boost::shared_ptr< NativeAPI::NativeStatementWrapper > & _proxy, boost::shared_ptr _logger) : position ( i ) , proxy ( _proxy ) , logger ( _logger ) { } bool operator()(std::istream * my_blob) const { CPP_ENTER("LongDataSender::operator()(std::istream *)"); if (my_blob == NULL) return false; //char buf[MAX_SEND_LONGDATA_BUFFER]; boost::scoped_array buf(new char[MAX_SEND_LONGDATA_BUFFER]); do { if (my_blob->eof()) { break; } my_blob->read(buf.get(), MAX_SEND_LONGDATA_BUFFER); if (my_blob->bad()) { throw SQLException("Error while reading from blob (bad)"); } else if (my_blob->fail()) { if (!my_blob->eof()) { throw SQLException("Error while reading from blob (fail)"); } } if (proxy->send_long_data(position, buf.get(), static_cast(my_blob->gcount()))) { CPP_ERR_FMT("Couldn't send long data : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); switch (proxy->errNo()) { case CR_OUT_OF_MEMORY: throw std::bad_alloc(); case CR_INVALID_BUFFER_USE: throw InvalidArgumentException("MySQL_Prepared_Statement::setBlob: can't set blob value on that column"); case CR_SERVER_GONE_ERROR: case CR_COMMANDS_OUT_OF_SYNC: default: sql::mysql::util::throwSQLException(*proxy.get()); } } } while (1); return true; } bool operator()(sql::SQLString * str) const { CPP_ENTER("LongDataSender::operator()(sql::SQLString *)"); if ( str == NULL ) return false; unsigned int sent= 0, chunkSize; while (sent < str->length()) { chunkSize= (sent + MAX_SEND_LONGDATA_CHUNK > str->length() ? str->length() - sent : MAX_SEND_LONGDATA_CHUNK); if (proxy->send_long_data(position, str->c_str() + sent, chunkSize)) { CPP_ERR_FMT("Couldn't send long data : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); switch (proxy->errNo()) { case CR_OUT_OF_MEMORY: throw std::bad_alloc(); case CR_INVALID_BUFFER_USE: throw InvalidArgumentException("MySQL_Prepared_Statement::setBlob: can't set blob value on that column"); case CR_SERVER_GONE_ERROR: case CR_COMMANDS_OUT_OF_SYNC: default: sql::mysql::util::throwSQLException(*proxy.get()); } } sent+= chunkSize; } return true; } }; class BlobBindDeleter : public boost::static_visitor<> { public: void operator()(sql::SQLString *& str) const { if (str != NULL) { delete str; str= NULL; } } void operator()(std::istream *& my_blob) const { if (my_blob!= NULL) { delete my_blob; my_blob= NULL; } } }; class BlobIsNull : public boost::static_visitor { public: bool operator()(sql::SQLString *& str) const { return str == NULL; } bool operator()(std::istream *& my_blob) const { return my_blob == NULL; } }; void resetBlobBind(MYSQL_BIND & param) { delete [] static_cast(param.buffer); param.buffer_type= MYSQL_TYPE_LONG_BLOB; param.buffer= NULL; param.buffer_length= 0; param.is_null_value= 0; delete param.length; param.length= new unsigned long(0); } class MySQL_ParamBind { public: typedef boost::variant< std::istream *, sql::SQLString *> Blob_t; private: unsigned int param_count; boost::scoped_array< MYSQL_BIND > bind; boost::scoped_array< bool > value_set; boost::scoped_array< bool > delete_blob_after_execute; typedef std::map Blobs; Blobs blob_bind; public: MySQL_ParamBind(unsigned int paramCount) : param_count(paramCount), bind(NULL), value_set(NULL), delete_blob_after_execute(NULL) { if (param_count) { bind.reset(new MYSQL_BIND[paramCount]); memset(bind.get(), 0, sizeof(MYSQL_BIND) * paramCount); value_set.reset(new bool[paramCount]); delete_blob_after_execute.reset(new bool[paramCount]); for (unsigned int i = 0; i < paramCount; ++i) { bind[i].is_null_value = 1; value_set[i] = false; delete_blob_after_execute[i] = false; } } } virtual ~MySQL_ParamBind() { clearParameters(); for (Blobs::iterator it= blob_bind.begin(); it != blob_bind.end(); ++it) { if (delete_blob_after_execute[it->first]) { delete_blob_after_execute[it->first] = false; boost::apply_visitor(::sql::mysql::BlobBindDeleter(), it->second); } } } void set(unsigned int position) { value_set[position] = true; } void unset(unsigned int position) { value_set[position] = false; if (delete_blob_after_execute[position]) { delete_blob_after_execute[position] = false; boost::apply_visitor(::sql::mysql::BlobBindDeleter(),blob_bind[position]); blob_bind.erase(position); } } void setBlob(unsigned int position, Blob_t & blob, bool delete_after_execute) { set(position); resetBlobBind(bind[position]); Blobs::iterator it = blob_bind.find(position); if (it != blob_bind.end() && delete_blob_after_execute[position]) { boost::apply_visitor(::sql::mysql::BlobBindDeleter(), it->second); } if (boost::apply_visitor(::sql::mysql::BlobIsNull(), blob)) { if (it != blob_bind.end()) blob_bind.erase(it); delete_blob_after_execute[position] = false; } else { blob_bind[position] = blob; delete_blob_after_execute[position] = delete_after_execute; } } bool isAllSet() { for (unsigned int i = 0; i < param_count; ++i) { if (!value_set[i]) { return false; } } return true; } void clearParameters() { for (unsigned int i = 0; i < param_count; ++i) { delete (char*) bind[i].length; bind[i].length = NULL; delete[] (char*) bind[i].buffer; bind[i].buffer = NULL; if (value_set[i]) { Blobs::iterator it= blob_bind.find(i); if (it != blob_bind.end() && delete_blob_after_execute[i]) { boost::apply_visitor(::sql::mysql::BlobBindDeleter(), it->second); blob_bind.erase(it); } blob_bind[i] = Blob_t(); value_set[i] = false; } } } // Name get() was too confusing, since class objects are used with smart pointers MYSQL_BIND * getBindObject() { return bind.get(); } boost::variant< std::istream *, SQLString *> getBlobObject(unsigned int position) { Blobs::iterator it= blob_bind.find( position ); if (it != blob_bind.end()) return it->second; return Blob_t(); } }; /* {{{ MySQL_Prepared_Statement::MySQL_Prepared_Statement() -I- */ MySQL_Prepared_Statement::MySQL_Prepared_Statement( boost::shared_ptr< NativeAPI::NativeStatementWrapper > & s, sql::Connection * conn, sql::ResultSet::enum_type rset_type, boost::shared_ptr< MySQL_DebugLogger > & log ) :connection(conn), proxy(s), isClosed(false), warningsHaveBeenLoaded(true), logger(log), resultset_type(rset_type), result_bind(new MySQL_ResultBind(proxy, logger)), warningsCount(0) { CPP_ENTER("MySQL_Prepared_Statement::MySQL_Prepared_Statement"); CPP_INFO_FMT("this=%p", this); param_count = proxy->param_count(); param_bind.reset(new MySQL_ParamBind(param_count)); res_meta.reset(new MySQL_PreparedResultSetMetaData(proxy, logger)); param_meta.reset(new MySQL_ParameterMetaData(proxy)); } /* }}} */ /* {{{ MySQL_Prepared_Statement::~MySQL_Prepared_Statement() -I- */ MySQL_Prepared_Statement::~MySQL_Prepared_Statement() { CPP_ENTER("MySQL_Prepared_Statement::~MySQL_Prepared_Statement"); /* This will free param_bind. We should not do it or there will be double free. */ if (!isClosed) { closeIntern(); } } /* }}} */ /* {{{ MySQL_Prepared_Statement::sendLongDataBeforeParamBind() -I- */ bool MySQL_Prepared_Statement::sendLongDataBeforeParamBind() { CPP_ENTER("MySQL_Prepared_Statement::sendLongDataBeforeParamBind"); MYSQL_BIND * bind= param_bind->getBindObject(); for (unsigned int i = 0; i < param_count; ++i) { if (bind[i].buffer_type == MYSQL_TYPE_LONG_BLOB) { ::sql::mysql::LongDataSender lv(i, proxy, logger); MySQL_ParamBind::Blob_t dummy(param_bind->getBlobObject(i)); boost::apply_visitor(lv, dummy); } } return true; } /* }}} */ /* {{{ MySQL_Prepared_Statement::do_query() -I- */ void MySQL_Prepared_Statement::do_query() { CPP_ENTER("MySQL_Prepared_Statement::do_query"); if (param_count && !param_bind->isAllSet()) { CPP_ERR("Value not set for all parameters"); throw sql::SQLException("Value not set for all parameters"); } if (proxy->bind_param(param_bind->getBindObject())) { CPP_ERR_FMT("Couldn't bind : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); sql::mysql::util::throwSQLException(*proxy.get()); } if (!sendLongDataBeforeParamBind() || proxy->execute()) { CPP_ERR_FMT("Couldn't execute : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); sql::mysql::util::throwSQLException(*proxy.get()); } warningsCount= proxy->warning_count(); warningsHaveBeenLoaded= false; } /* }}} */ /* {{{ MySQL_Prepared_Statement::clearParameters() -I- */ void MySQL_Prepared_Statement::clearParameters() { CPP_ENTER("MySQL_Prepared_Statement::clearParameters"); CPP_INFO_FMT("this=%p", this); checkClosed(); param_bind->clearParameters(); } /* }}} */ /* {{{ MySQL_Prepared_Statement::getConnection() -I- */ sql::Connection * MySQL_Prepared_Statement::getConnection() { CPP_ENTER("MySQL_Prepared_Statement::getConnection"); CPP_INFO_FMT("this=%p", this); checkClosed(); return connection; } /* }}} */ /* {{{ MySQL_Prepared_Statement::execute() -I- */ bool MySQL_Prepared_Statement::execute() { CPP_ENTER("MySQL_Prepared_Statement::execute"); CPP_INFO_FMT("this=%p", this); checkClosed(); do_query(); return (proxy->field_count() > 0); } /* }}} */ /* {{{ MySQL_Prepared_Statement::execute() -U- */ bool MySQL_Prepared_Statement::execute(const sql::SQLString&) { CPP_ENTER("MySQL_Prepared_Statement::execute(const sql::SQLString& sql)"); throw sql::MethodNotImplementedException("MySQL_Prepared_Statement::execute"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::executeQuery() -I- */ sql::ResultSet * MySQL_Prepared_Statement::executeQuery() { CPP_ENTER("MySQL_Prepared_Statement::executeQuery"); CPP_INFO_FMT("this=%p", this); checkClosed(); do_query(); my_bool bool_tmp=1; proxy->attr_set( STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp); sql::ResultSet::enum_type tmp_type; if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) { if (proxy->store_result()) { sql::mysql::util::throwSQLException(*proxy.get()); } tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE; } else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) { tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY; } else { throw SQLException("Invalid value for result set type"); } sql::ResultSet * tmp = new MySQL_Prepared_ResultSet(proxy, result_bind, tmp_type, this, logger); CPP_INFO_FMT("rset=%p", tmp); return tmp; } /* }}} */ /* {{{ MySQL_Prepared_Statement::executeQuery() -U- */ sql::ResultSet * MySQL_Prepared_Statement::executeQuery(const sql::SQLString&) { throw sql::MethodNotImplementedException("MySQL_Prepared_Statement::executeQuery"); /* TODO - what to do? Comes from Statement */ return NULL; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::executeUpdate() -I- */ int MySQL_Prepared_Statement::executeUpdate() { CPP_ENTER("MySQL_Prepared_Statement::executeUpdate"); CPP_INFO_FMT("this=%p", this); checkClosed(); do_query(); return static_cast(proxy->affected_rows()); } /* }}} */ /* {{{ MySQL_Prepared_Statement::executeUpdate() -U- */ int MySQL_Prepared_Statement::executeUpdate(const sql::SQLString&) { throw sql::MethodNotImplementedException("MySQL_Prepared_Statement::executeUpdate"); /* TODO - what to do? Comes from Statement */ return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::setBigInt() -I- */ void MySQL_Prepared_Statement::setBigInt(unsigned int parameterIndex, const sql::SQLString& value) { CPP_ENTER("MySQL_Prepared_Statement::setBigInt"); setString(parameterIndex, value); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setBlob_intern() -I- */ /* void setBlob_intern(unsigned int parameterIndex , / *boost::variant< std::istream *, sql::SQLString *>* /MySQL_ParamBind::Blob_t & blob , bool deleteBlobAfterExecute) { CPP_ENTER("MySQL_Prepared_Statement::setBlob_intern"); CPP_INFO_FMT("this=%p", this); checkClosed(); --parameterIndex; / * DBC counts from 1 * / param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; delete [] static_cast(param->buffer); param->buffer_type = MYSQL_TYPE_LONG_BLOB; param->buffer = NULL; param->buffer_length= 0; param->is_null_value= 0; delete param->length; param->length = new unsigned long(0); param_bind->setBlob(parameterIndex, blob, deleteBlobAfterExecute); }*/ /* }}} */ /* {{{ MySQL_Prepared_Statement::setBlob() -I- */ void MySQL_Prepared_Statement::setBlob(unsigned int parameterIndex, std::istream * blob) { CPP_ENTER("MySQL_Prepared_Statement::setBlob"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setBlob: invalid 'parameterIndex'"); } MySQL_ParamBind::Blob_t dummy(blob); param_bind->setBlob(--parameterIndex, dummy, false); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setBoolean() -I- */ void MySQL_Prepared_Statement::setBoolean(unsigned int parameterIndex, bool value) { CPP_ENTER("MySQL_Prepared_Statement::setBoolean"); setInt(parameterIndex, value); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setDateTime() -I- */ void MySQL_Prepared_Statement::setDateTime(unsigned int parameterIndex, const sql::SQLString& value) { CPP_ENTER("MySQL_Prepared_Statement::setDateTime"); setString(parameterIndex, value); } /* }}} */ typedef std::pair BufferSizePair; static BufferSizePair allocate_buffer_for_type(enum_field_types t) { switch (t) { #if A1 // We don't use these now. When we have setXXX, we can enable them case MYSQL_TYPE_TINY: return BufferSizePair(new char[1], 1); case MYSQL_TYPE_SHORT: return BufferSizePair(new char[2], 2); case MYSQL_TYPE_INT24: case MYSQL_TYPE_FLOAT: #endif case MYSQL_TYPE_LONG: return BufferSizePair(new char[4], 4); case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_LONGLONG: return BufferSizePair(new char[8], 8); #if A1 // We don't use these now. When we have setXXX, we can enable them case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: return BufferSizePair(new char[sizeof(MYSQL_TIME)], sizeof(MYSQL_TIME)); case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: #endif case MYSQL_TYPE_STRING: return BufferSizePair(NULLCSTR, 0); #if A1 // We don't use these now. When we have setXXX, we can enable them case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: return BufferSizePair(new char[64], 64); case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_YEAR: return BufferSizePair(new char[10], 10); #endif #if A0 // There two are not sent over the wire case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: #endif #if A1 // We don't use these now. When we have setXXX, we can enable them case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_BIT: #endif case MYSQL_TYPE_NULL: return BufferSizePair(NULLCSTR, 0); default: throw sql::InvalidArgumentException("allocate_buffer_for_type: invalid result_bind data type"); } } /* {{{ MySQL_Prepared_Statement::setDouble() -I- */ void MySQL_Prepared_Statement::setDouble(unsigned int parameterIndex, double value) { CPP_ENTER("MySQL_Prepared_Statement::setDouble"); CPP_INFO_FMT("this=%p %f", this, value); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setDouble: invalid 'parameterIndex'"); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_DOUBLE; BufferSizePair p = allocate_buffer_for_type(t); param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; param->buffer_type = t; delete [] static_cast(param->buffer); param->buffer = p.first; param->buffer_length = 0; param->is_null_value = 0; delete param->length; param->length = NULL; memcpy(param->buffer, &value, p.second); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setInt() -I- */ void MySQL_Prepared_Statement::setInt(unsigned int parameterIndex, int32_t value) { CPP_ENTER("MySQL_Prepared_Statement::setInt"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("column=%u value=%d", parameterIndex, value); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setInt: invalid 'parameterIndex'"); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_LONG; BufferSizePair p = allocate_buffer_for_type(t); param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; param->buffer_type = t; delete [] static_cast(param->buffer); param->buffer = p.first; param->buffer_length = 0; param->is_null_value = 0; delete param->length; param->length = NULL; memcpy(param->buffer, &value, p.second); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setUInt() -I- */ void MySQL_Prepared_Statement::setUInt(unsigned int parameterIndex, uint32_t value) { CPP_ENTER("MySQL_Prepared_Statement::setUInt"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("column=%u value=%u", parameterIndex, value); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setInt: invalid 'parameterIndex'"); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_LONG; BufferSizePair p = allocate_buffer_for_type(t); param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; param->buffer_type = t; delete [] static_cast(param->buffer); param->buffer = p.first; param->buffer_length = 0; param->is_null_value = 0; param->is_unsigned = 1; delete param->length; param->length = NULL; memcpy(param->buffer, &value, p.second); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setInt64() -I- */ void MySQL_Prepared_Statement::setInt64(unsigned int parameterIndex, int64_t value) { CPP_ENTER("MySQL_Prepared_Statement::setInt64"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setInt64: invalid 'parameterIndex'"); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_LONGLONG; BufferSizePair p = allocate_buffer_for_type(t); param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; param->buffer_type = t; delete [] static_cast(param->buffer); param->buffer = p.first; param->buffer_length = 0; param->is_null_value = 0; delete param->length; param->length = NULL; memcpy(param->buffer, &value, p.second); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setUInt64() -I- */ void MySQL_Prepared_Statement::setUInt64(unsigned int parameterIndex, uint64_t value) { CPP_ENTER("MySQL_Prepared_Statement::setUInt64"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setUInt64: invalid 'parameterIndex'"); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_LONGLONG; BufferSizePair p = allocate_buffer_for_type(t); param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; param->buffer_type = t; delete [] static_cast(param->buffer); param->buffer = p.first; param->buffer_length = 0; param->is_null_value = 0; param->is_unsigned = 1; delete param->length; param->length = NULL; memcpy(param->buffer, &value, p.second); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setNull() -I- */ void MySQL_Prepared_Statement::setNull(unsigned int parameterIndex, int /* sqlType */) { CPP_ENTER("MySQL_Prepared_Statement::setNull"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("column=%u", parameterIndex); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { throw InvalidArgumentException("MySQL_Prepared_Statement::setNull: invalid 'parameterIndex'"); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_NULL; param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; param->buffer_type = t; delete [] static_cast(param->buffer); param->buffer = NULL; delete param->length; param->length = NULL; } /* }}} */ /* {{{ MySQL_Prepared_Statement::setString() -I- */ void MySQL_Prepared_Statement::setString(unsigned int parameterIndex, const sql::SQLString& value) { CPP_ENTER("MySQL_Prepared_Statement::setString"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("column=%u value_len=%d value=%s ", parameterIndex, value.length(), value.c_str()); checkClosed(); if (parameterIndex == 0 || parameterIndex > param_count) { CPP_ERR("Invalid parameterIndex"); throw InvalidArgumentException("MySQL_Prepared_Statement::setString: invalid 'parameterIndex'"); } if (value.length() > 256*1024) { MySQL_ParamBind::Blob_t dummy(const_cast(&value)); return param_bind->setBlob(--parameterIndex, dummy, false); } --parameterIndex; /* DBC counts from 1 */ { MySQL_ParamBind::Blob_t dummy; param_bind->setBlob(parameterIndex, dummy, false); param_bind->unset(parameterIndex); } enum_field_types t = MYSQL_TYPE_STRING; param_bind->set(parameterIndex); MYSQL_BIND * param = ¶m_bind->getBindObject()[parameterIndex]; delete [] static_cast(param->buffer); param->buffer_type = t; param->buffer = memcpy(new char[value.length() + 1], value.c_str(), value.length() + 1); param->buffer_length= static_cast(value.length()) + 1; param->is_null_value= 0; delete param->length; param->length = new unsigned long(static_cast(value.length())); } /* }}} */ /* {{{ MySQL_Prepared_Statement::cancel() -U- */ void MySQL_Prepared_Statement::cancel() { CPP_ENTER("MySQL_Prepared_Statement::cancel"); CPP_INFO_FMT("this=%p", this); checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::cancel"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::getFetchSize() -U- */ size_t MySQL_Prepared_Statement::getFetchSize() { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::getFetchSize"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::getMetaData() -I- */ sql::ResultSetMetaData * MySQL_Prepared_Statement::getMetaData() { CPP_ENTER("MySQL_Prepared_Statement::getMetaData"); CPP_INFO_FMT("this=%p", this); checkClosed(); return res_meta.get(); } /* }}} */ /* {{{ MySQL_Prepared_Statement::getParameterMetaData() -I- */ sql::ParameterMetaData * MySQL_Prepared_Statement::getParameterMetaData() { CPP_ENTER("MySQL_Prepared_Statement::getParameterMetaData"); CPP_INFO_FMT("this=%p", this); checkClosed(); return param_meta.get(); } /* }}} */ /* {{{ MySQL_Prepared_Statement::getResultSet() -I- */ sql::ResultSet * MySQL_Prepared_Statement::getResultSet() { CPP_ENTER("MySQL_Prepared_Statement::getResultSet"); CPP_INFO_FMT("this=%p", this); checkClosed(); my_bool bool_tmp = 1; proxy->attr_set(STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp); sql::ResultSet::enum_type tmp_type; if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) { if (proxy->store_result()) { sql::mysql::util::throwSQLException(*proxy.get()); } tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE; } else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) { tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY; } else { throw SQLException("Invalid value for result set type"); } sql::ResultSet * tmp = new MySQL_Prepared_ResultSet(proxy, result_bind, tmp_type, this, logger); CPP_INFO_FMT("rset=%p", tmp); return tmp; } /* }}} */ /* {{{ MySQL_Prepared_Statement::setFetchSize() -U- */ void MySQL_Prepared_Statement::setFetchSize(size_t /* size */) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setFetchSize"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setQueryTimeout() -U- */ void MySQL_Prepared_Statement::setQueryTimeout(unsigned int) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setQueryTimeout"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::clearWarnings() -I- */ void MySQL_Prepared_Statement::clearWarnings() { CPP_ENTER("MySQL_Prepared_Statement::clearWarnings"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (warnings) { warnings.reset(); } } /* }}} */ /* {{{ MySQL_Prepared_Statement::close() -I- */ void MySQL_Prepared_Statement::close() { CPP_ENTER("MySQL_Prepared_Statement::close"); CPP_INFO_FMT("this=%p", this); checkClosed(); closeIntern(); } /* }}} */ /* {{{ MySQL_Prepared_Statement::getMaxFieldSize() -U- */ unsigned int MySQL_Prepared_Statement::getMaxFieldSize() { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::getMaxFieldSize"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::getMaxRows() -U- */ uint64_t MySQL_Prepared_Statement::getMaxRows() { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::getMaxRows"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::getMoreResults() -U- */ bool MySQL_Prepared_Statement::getMoreResults() { CPP_ENTER("MySQL_Prepared_Statement::getMoreResults"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (proxy->more_results()) { int next_result = proxy->stmt_next_result(); if (next_result == 0) { return proxy->field_count() != 0; } else if (next_result == -1) { throw sql::SQLException("Impossible! more_results() said true, next_result says no more results"); } else { CPP_ERR_FMT("Error during getMoreResults : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); sql::mysql::util::throwSQLException(*proxy.get()); } } return false; } /* }}} */ /* {{{ MySQL_Prepared_Statement::getQueryTimeout() -U- */ unsigned int MySQL_Prepared_Statement::getQueryTimeout() { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::getQueryTimeout"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Statement::getResultSetType() -I- */ sql::ResultSet::enum_type MySQL_Prepared_Statement::getResultSetType() { CPP_ENTER("MySQL_Statement::getResultSetType"); checkClosed(); return resultset_type; } /* }}} */ /* {{{ MySQL_Prepared_Statement::getUpdateCount() -U- */ uint64_t MySQL_Prepared_Statement::getUpdateCount() { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::getUpdateCount"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_Statement::getWarnings() -I- */ const SQLWarning * MySQL_Prepared_Statement::getWarnings() { CPP_ENTER("MySQL_Prepared_Statement::getWarnings"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (!warningsHaveBeenLoaded) { if (warningsCount) warnings.reset( loadMysqlWarnings(connection, warningsCount) ); warningsHaveBeenLoaded= true; } return warnings.get(); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setCursorName() -U- */ void MySQL_Prepared_Statement::setCursorName(const sql::SQLString &) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setCursorName"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setEscapeProcessing() -U- */ void MySQL_Prepared_Statement::setEscapeProcessing(bool) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setEscapeProcessing"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setMaxFieldSize() -U- */ void MySQL_Prepared_Statement::setMaxFieldSize(unsigned int) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setMaxFieldSize"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setMaxRows() -U- */ void MySQL_Prepared_Statement::setMaxRows(unsigned int) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setMaxRows"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setResultSetConcurrency() -U- */ void MySQL_Prepared_Statement::setResultSetConcurrency(int) { checkClosed(); throw MethodNotImplementedException("MySQL_Prepared_Statement::setResultSetConcurrency"); } /* }}} */ /* {{{ MySQL_Prepared_Statement::setResultSetType() -U- */ sql::PreparedStatement * MySQL_Prepared_Statement::setResultSetType(sql::ResultSet::enum_type /* type */) { checkClosed(); #if WE_SUPPORT_USE_RESULT_WITH_PS /* The connector is not ready for unbuffered as we need to refetch */ resultset_type = type; #else throw MethodNotImplementedException("MySQL_Prepared_Statement::setResultSetType"); #endif return this; } /* }}} */ /* {{{ MySQL_Prepared_Statement::checkClosed() -I- */ void MySQL_Prepared_Statement::checkClosed() { CPP_ENTER("MySQL_Prepared_Statement::checkClosed"); if (isClosed) { CPP_ERR("Statement has already been closed"); throw sql::InvalidInstanceException("Statement has been closed"); } } /* }}} */ /* {{{ MySQL_Prepared_Statement::closeIntern() -I- */ void MySQL_Prepared_Statement::closeIntern() { CPP_ENTER("MySQL_Prepared_Statement::closeIntern"); proxy.reset(); clearParameters(); clearWarnings(); isClosed = true; } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_prepared_statement.h000644 015771 000012 00000011405 12645244436 024543 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_PREPARED_STATEMENT_H_ #define _MYSQL_PREPARED_STATEMENT_H_ #include #include #include #include namespace sql { namespace mysql { class MySQL_DebugLogger; class MySQL_ParamBind; class MySQL_ParameterMetaData; class MySQL_PreparedResultSetMetaData; class MySQL_ResultBind; class MySQL_Warning; namespace NativeAPI { class NativeStatementWrapper; } class MySQL_Prepared_Statement : public sql::PreparedStatement { protected: sql::Connection * connection; boost::shared_ptr< NativeAPI::NativeStatementWrapper > proxy; boost::scoped_ptr< MySQL_ParamBind > param_bind; unsigned int param_count; int resultSetConcurrency; int resultSetType; boost::scoped_ptr< MySQL_Warning > warnings; bool isClosed; bool warningsHaveBeenLoaded; boost::shared_ptr< MySQL_DebugLogger > logger; boost::scoped_ptr< MySQL_PreparedResultSetMetaData > res_meta; boost::scoped_ptr< MySQL_ParameterMetaData > param_meta; sql::ResultSet::enum_type resultset_type; boost::shared_ptr< MySQL_ResultBind > result_bind; unsigned int warningsCount; virtual void do_query(); virtual void checkClosed(); virtual void closeIntern(); bool sendLongDataBeforeParamBind(); public: MySQL_Prepared_Statement(boost::shared_ptr & s, sql::Connection * conn, sql::ResultSet::enum_type rset_type, boost::shared_ptr< MySQL_DebugLogger > & log); virtual ~MySQL_Prepared_Statement(); sql::Connection *getConnection(); void cancel(); void clearParameters(); void clearWarnings(); void close(); bool execute(); bool execute(const sql::SQLString& sql); sql::ResultSet *executeQuery(); sql::ResultSet *executeQuery(const sql::SQLString& sql); int executeUpdate(); int executeUpdate(const sql::SQLString& sql); size_t getFetchSize(); unsigned int getMaxFieldSize(); sql::ResultSetMetaData * getMetaData(); uint64_t getMaxRows(); bool getMoreResults(); sql::ParameterMetaData * getParameterMetaData(); unsigned int getQueryTimeout(); sql::ResultSet * getResultSet(); sql::ResultSet::enum_type getResultSetType(); uint64_t getUpdateCount(); const SQLWarning * getWarnings();/* should return different type */ Statement * setBuffered(); void setBlob(unsigned int parameterIndex, std::istream * blob); void setBoolean(unsigned int parameterIndex, bool value); void setBigInt(unsigned int parameterIndex, const sql::SQLString& value); void setCursorName(const sql::SQLString &name); void setDateTime(unsigned int parameterIndex, const sql::SQLString& value); void setDouble(unsigned int parameterIndex, double value); void setEscapeProcessing(bool enable); void setFetchSize(size_t rows); void setInt(unsigned int parameterIndex, int32_t value); void setUInt(unsigned int parameterIndex, uint32_t value); void setInt64(unsigned int parameterIndex, int64_t value); void setUInt64(unsigned int parameterIndex, uint64_t value); void setMaxFieldSize(unsigned int max); void setMaxRows(unsigned int max); void setNull(unsigned int parameterIndex, int sqlType); void setResultSetConcurrency(int concurrencyFlag); void setString(unsigned int parameterIndex, const sql::SQLString& value); void setQueryTimeout(unsigned int seconds); sql::PreparedStatement * setResultSetType(sql::ResultSet::enum_type type); private: /* Prevent use of these */ MySQL_Prepared_Statement(const MySQL_Prepared_Statement &); void operator=(MySQL_Prepared_Statement &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_PREPARED_STATEMENT_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_ps_resultset.cpp000644 015771 000012 00000136220 12645244436 023747 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include "mysql_util.h" #include "mysql_ps_resultset.h" #include "mysql_resultset.h" #include "mysql_prepared_statement.h" #include "mysql_ps_resultset_metadata.h" #include "mysql_resultbind.h" #include "nativeapi/native_statement_wrapper.h" #include "nativeapi/native_resultset_wrapper.h" #include "mysql_debug.h" //Prevent windows min() macro because of std::numeric_limits::min() #undef min namespace sql { namespace mysql { /* {{{ my_l_to_a() -I- */ static inline char * my_l_to_a(char * buf, size_t buf_size, int64_t a) { snprintf(buf, buf_size, "%lld", (long long) a); return buf; } /* }}} */ /* {{{ my_ul_to_a() -I- */ static inline char * my_ul_to_a(char * buf, size_t buf_size, uint64_t a) { snprintf(buf, buf_size, "%llu", (unsigned long long) a); return buf; } /* }}} */ /* {{{ my_f_to_a() -I- */ static inline char * my_f_to_a(char * buf, size_t buf_size, double a) { snprintf(buf, buf_size, "%f", a); return buf; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::MySQL_Prepared_ResultSet() -I- */ MySQL_Prepared_ResultSet::MySQL_Prepared_ResultSet( boost::shared_ptr< NativeAPI::NativeStatementWrapper > & s, boost::shared_ptr< MySQL_ResultBind > & r_bind, sql::ResultSet::enum_type rset_type, MySQL_Prepared_Statement * par, boost::shared_ptr< MySQL_DebugLogger > & l ) : row(NULL), proxy(s), last_queried_column(std::numeric_limits::max()), row_position(0), parent(par), is_valid(true), logger(l), result_bind(r_bind), resultset_type(rset_type) { CPP_ENTER("MySQL_Prepared_ResultSet::MySQL_Prepared_ResultSet"); result_bind->bindResult(); boost::scoped_ptr< NativeAPI::NativeResultsetWrapper > result_meta( proxy->result_metadata() ); num_fields = proxy->field_count(); num_rows = proxy->num_rows(); CPP_INFO_FMT("num_fields=%u num_rows=%u", num_fields, num_rows); for (unsigned int i = 0; i < num_fields; ++i) { boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(result_meta->fetch_field()->name, 0)); field_name_to_index_map[sql::SQLString(upstring.get())] = i; } rs_meta.reset(new MySQL_PreparedResultSetMetaData(proxy, logger)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::~MySQL_Prepared_ResultSet() -I- */ MySQL_Prepared_ResultSet::~MySQL_Prepared_ResultSet() { CPP_ENTER("MySQL_Prepared_ResultSet::~MySQL_Prepared_ResultSet"); closeIntern(); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::absolute() -I- */ bool MySQL_Prepared_ResultSet::absolute(const int new_pos) { CPP_ENTER("MySQL_Prepared_ResultSet::absolute"); checkValid(); checkScrollable(); if (new_pos > 0) { if (new_pos > (int) num_rows) { row_position = num_rows + 1; /* after last row */ } else { row_position = new_pos; seek(); return true; } } else if (new_pos < 0) { if ((-new_pos) > (int) num_rows || (new_pos == std::numeric_limits::min())) { row_position = 0; /* before first new_pos */ } else { row_position = num_rows - (-new_pos) + 1; seek(); return true; } } else { /* According to the JDBC book, absolute(0) means before the result set */ row_position = 0; /* no seek() here, as we are not on data*/ beforeFirst(); } return (row_position > 0 && row_position < (num_rows + 1)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::afterLast() -I- */ void MySQL_Prepared_ResultSet::afterLast() { CPP_ENTER("MySQL_Prepared_ResultSet::afterLast"); checkValid(); checkScrollable(); row_position = num_rows + 1; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::beforeFirst() -I- */ void MySQL_Prepared_ResultSet::beforeFirst() { CPP_ENTER("MySQL_Prepared_ResultSet::beforeFirst"); checkValid(); checkScrollable(); proxy->data_seek(0); row_position = 0; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::cancelRowUpdates() -U- */ void MySQL_Prepared_ResultSet::cancelRowUpdates() { CPP_ENTER("MySQL_Prepared_ResultSet::cancelRowUpdates"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::cancelRowUpdates()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::checkValid() -I- */ void MySQL_Prepared_ResultSet::checkValid() const { CPP_ENTER("MySQL_Prepared_ResultSet::checkValid"); CPP_INFO_FMT("this=%p", this); if (isClosed()) { throw sql::InvalidInstanceException("Statement has been closed"); } } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::checkScrollable() -I- */ void MySQL_Prepared_ResultSet::checkScrollable() const { CPP_ENTER("MySQL_Prepared_ResultSet::checkScrollable"); CPP_INFO_FMT("this=%p", this); if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) { throw sql::NonScrollableException("Nonscrollable result set"); } // reset last_queried_column last_queried_column = std::numeric_limits::max(); } /* }}} */ /* {{{ MySQL_ResultSet::isScrollable() -I- */ bool MySQL_Prepared_ResultSet::isScrollable() const { CPP_ENTER("MySQL_ResultSet::isScrollable"); CPP_INFO_FMT("this=%p", this); return (resultset_type != sql::ResultSet::TYPE_FORWARD_ONLY); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::clearWarnings() -U- */ void MySQL_Prepared_ResultSet::clearWarnings() { CPP_ENTER("MySQL_Prepared_ResultSet::clearWarnings"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::clearWarnings()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::close() -I- */ void MySQL_Prepared_ResultSet::close() { CPP_ENTER("MySQL_Prepared_ResultSet::close"); checkValid(); closeIntern(); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::closeIntern() -I- */ void MySQL_Prepared_ResultSet::closeIntern() { CPP_ENTER("MySQL_Prepared_ResultSet::closeIntern"); //We nee here to check how many MySQL_Prepared_ResultSet instances //exist. Since each one of them has a result_bind, we can use his use_cont //to check if it equals 2 (1 here + 1 on MySQL_Prepared_Statement (parent)) //Only on this case, we can call proxy->stmt_free_result(); if (result_bind.use_count() == 2) proxy->stmt_free_result(); is_valid = false; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::findColumn() -I- */ uint32_t MySQL_Prepared_ResultSet::findColumn(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::findColumn"); checkValid(); boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(columnLabel.c_str(), 0)); FieldNameIndexMap::const_iterator iter= field_name_to_index_map.find(upstring.get()); if (iter == field_name_to_index_map.end()) { return 0; } /* findColumn returns 1-based indexes */ return iter->second + 1; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::first() -I- */ bool MySQL_Prepared_ResultSet::first() { CPP_ENTER("MySQL_Prepared_ResultSet::first"); checkValid(); checkScrollable(); if (num_rows) { row_position = 1; seek(); } return num_rows? true:false; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getBlob() -I- */ std::istream * MySQL_Prepared_ResultSet::getBlob(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getBlob(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getBlob: can't fetch because not on result set"); } return new std::istringstream(getString(columnIndex)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getBlob() -I- */ std::istream * MySQL_Prepared_ResultSet::getBlob(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getBlob(string)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getBlob: can't fetch because not on result set"); } return new std::istringstream(getString(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getBoolean() -I- */ bool MySQL_Prepared_ResultSet::getBoolean(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getBoolean(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getBoolean: can't fetch because not on result set"); } return getInt(columnIndex)? true:false; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getBoolean() -I- */ bool MySQL_Prepared_ResultSet::getBoolean(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getBoolean(string)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getBoolean: can't fetch because not on result set"); } return getInt(columnLabel)? true:false; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getConcurrency() -U- */ int MySQL_Prepared_ResultSet::getConcurrency() { CPP_ENTER("MySQL_Prepared_ResultSet::getConcurrency"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getConcurrency()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getCursorName() -U- */ SQLString MySQL_Prepared_ResultSet::getCursorName() { CPP_ENTER("MySQL_Prepared_ResultSet::getCursorName"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getCursorName()"); return ""; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getDouble() -I- */ long double MySQL_Prepared_ResultSet::getDouble(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getDouble(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getDouble: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQLPreparedResultSet::getDouble: invalid 'columnIndex'"); } last_queried_column = columnIndex; if (*result_bind->rbind[columnIndex - 1].is_null) { return 0.0; } switch (rs_meta->getColumnType(columnIndex)) { case sql::DataType::BIT: case sql::DataType::YEAR: // fetched as a SMALLINT case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::MEDIUMINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: { long double ret; bool is_it_unsigned = result_bind->rbind[columnIndex - 1].is_unsigned != 0; CPP_INFO_FMT("It's an int : %ssigned", is_it_unsigned? "un":""); if (is_it_unsigned) { uint64_t ival = getUInt64_intern(columnIndex, false); CPP_INFO_FMT("value=%llu", ival); ret = static_cast(ival); } else { int64_t ival = getInt64_intern(columnIndex, false); CPP_INFO_FMT("value=%lld", ival); ret = static_cast(ival); } CPP_INFO_FMT("value=%10.10f", (double) ret); return ret; } case sql::DataType::NUMERIC: case sql::DataType::DECIMAL: case sql::DataType::TIMESTAMP: case sql::DataType::DATE: case sql::DataType::TIME: case sql::DataType::CHAR: case sql::DataType::BINARY: case sql::DataType::VARCHAR: case sql::DataType::VARBINARY: case sql::DataType::LONGVARCHAR: case sql::DataType::LONGVARBINARY: case sql::DataType::SET: case sql::DataType::ENUM: case sql::DataType::JSON: { CPP_INFO("It's a string"); long double ret = sql::mysql::util::strtold(getString(columnIndex).c_str(), NULL); CPP_INFO_FMT("value=%10.10f", ret); return ret; } case sql::DataType::REAL: { long double ret = !*result_bind->rbind[columnIndex - 1].is_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0.; CPP_INFO_FMT("value=%10.10f", ret); return ret; } case sql::DataType::DOUBLE: { long double ret = !*result_bind->rbind[columnIndex - 1].is_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0.; CPP_INFO_FMT("value=%10.10f", ret); return ret; } // ToDo : Geometry? default ? } CPP_ERR("MySQL_Prepared_ResultSet::getDouble: unhandled type. Please, report"); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getDouble: unhandled type. Please, report"); return .0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getDouble() -I- */ long double MySQL_Prepared_ResultSet::getDouble(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getDouble(string)"); return getDouble(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getFetchDirection() -U- */ int MySQL_Prepared_ResultSet::getFetchDirection() { CPP_ENTER("MySQL_Prepared_ResultSet::getFetchDirection"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getFetchDirection()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getFetchSize() -U- */ size_t MySQL_Prepared_ResultSet::getFetchSize() { CPP_ENTER("MySQL_Prepared_ResultSet::getFetchSize"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getFetchSize()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getHoldability() -U- */ int MySQL_Prepared_ResultSet::getHoldability() { CPP_ENTER("MySQL_Prepared_ResultSet::getHoldability"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getHoldability()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getInt() -I- */ int32_t MySQL_Prepared_ResultSet::getInt(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getInt(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getInt: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getInt: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (*result_bind->rbind[columnIndex - 1].is_null) { return 0; } return static_cast(getInt64_intern(columnIndex, true)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getInt() -I- */ int32_t MySQL_Prepared_ResultSet::getInt(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getInt(string)"); return getInt(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getUInt() -I- */ uint32_t MySQL_Prepared_ResultSet::getUInt(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getUInt(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getUInt: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getUInt: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (*result_bind->rbind[columnIndex - 1].is_null) { return 0; } return static_cast(getUInt64_intern(columnIndex, true)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getUInt() -I- */ uint32_t MySQL_Prepared_ResultSet::getUInt(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getUInt(string)"); return getUInt(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getInt64_intern() -I- */ int64_t MySQL_Prepared_ResultSet::getInt64_intern(const uint32_t columnIndex, bool /* cutTooBig */) const { CPP_ENTER("MySQL_Prepared_ResultSet::getInt64_intern"); CPP_INFO_FMT("column=%u", columnIndex); switch (rs_meta->getColumnType(columnIndex)) { case sql::DataType::REAL: case sql::DataType::DOUBLE: CPP_INFO("It's a double"); return static_cast(getDouble(columnIndex)); case sql::DataType::NUMERIC: case sql::DataType::DECIMAL: case sql::DataType::TIMESTAMP: case sql::DataType::DATE: case sql::DataType::TIME: case sql::DataType::CHAR: case sql::DataType::BINARY: case sql::DataType::VARCHAR: case sql::DataType::VARBINARY: case sql::DataType::LONGVARCHAR: case sql::DataType::LONGVARBINARY: case sql::DataType::SET: case sql::DataType::ENUM: case sql::DataType::JSON: CPP_INFO("It's a string"); return strtoll(getString(columnIndex).c_str(), NULL, 10); case sql::DataType::BIT: { int64_t uval = 0; /* This length is in bytes, on the contrary to what can be seen in mysql_resultset.cpp where the Meta is used */ switch (*result_bind->rbind[columnIndex - 1].length) { case 8:uval = (int64_t) bit_uint8korr(result_bind->rbind[columnIndex - 1].buffer);break; case 7:uval = (int64_t) bit_uint7korr(result_bind->rbind[columnIndex - 1].buffer);break; case 6:uval = (int64_t) bit_uint6korr(result_bind->rbind[columnIndex - 1].buffer);break; case 5:uval = (int64_t) bit_uint5korr(result_bind->rbind[columnIndex - 1].buffer);break; case 4:uval = (int64_t) bit_uint4korr(result_bind->rbind[columnIndex - 1].buffer);break; case 3:uval = (int64_t) bit_uint3korr(result_bind->rbind[columnIndex - 1].buffer);break; case 2:uval = (int64_t) bit_uint2korr(result_bind->rbind[columnIndex - 1].buffer);break; case 1:uval = (int64_t) bit_uint1korr(result_bind->rbind[columnIndex - 1].buffer);break; } return uval; } case sql::DataType::YEAR: // fetched as a SMALLINT case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::MEDIUMINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: { // sql::DataType::YEAR is fetched as a SMALLINT, thus should not be in the switch int64_t ret; bool is_it_null = *result_bind->rbind[columnIndex - 1].is_null != 0; bool is_it_unsigned = result_bind->rbind[columnIndex - 1].is_unsigned != 0; CPP_INFO_FMT("%d byte, %ssigned, null=%d", result_bind->rbind[columnIndex - 1].buffer_length, is_it_unsigned? "un":"", is_it_null); switch (result_bind->rbind[columnIndex - 1].buffer_length) { case 1: if (is_it_unsigned) { // ToDo: Really reinterpret_case or static_cast ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { // ToDo: Really reinterpret_case or static_cast ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; case 2: if (is_it_unsigned) { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; case 4: if (is_it_unsigned) { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; case 8: if (is_it_unsigned) { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; #if WE_WANT_TO_SEE_MORE_FAILURES_IN_UNIT_RESULTSET if (cutTooBig && ret && *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer) > UL64(9223372036854775807)) { ret = UL64(9223372036854775807); } #endif } else { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; default: throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getInt64_intern: invalid type"); } CPP_INFO_FMT("value=%lld", ret); return ret; } default: break; // ToDo : Geometry? default ? } CPP_ERR("MySQL_Prepared_ResultSet::getInt64_intern: unhandled type. Please, report"); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getInt64_intern: unhandled type. Please, report"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getInt64() -I- */ int64_t MySQL_Prepared_ResultSet::getInt64(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getInt64(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getInt64: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getInt64: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (*result_bind->rbind[columnIndex - 1].is_null) { return 0; } return getInt64_intern(columnIndex, true); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getInt64() -I- */ int64_t MySQL_Prepared_ResultSet::getInt64(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getInt64(string)"); return getInt64(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getUInt64_intern() -I- */ uint64_t MySQL_Prepared_ResultSet::getUInt64_intern(const uint32_t columnIndex, bool /* cutTooBig */) const { CPP_ENTER("MySQL_Prepared_ResultSet::getUInt64_intern"); CPP_INFO_FMT("column=%u", columnIndex); switch (rs_meta->getColumnType(columnIndex)) { case sql::DataType::REAL: case sql::DataType::DOUBLE: CPP_INFO("It's a double"); return static_cast(getDouble(columnIndex)); case sql::DataType::NUMERIC: case sql::DataType::DECIMAL: case sql::DataType::TIMESTAMP: case sql::DataType::DATE: case sql::DataType::TIME: case sql::DataType::CHAR: case sql::DataType::BINARY: case sql::DataType::VARCHAR: case sql::DataType::VARBINARY: case sql::DataType::LONGVARCHAR: case sql::DataType::LONGVARBINARY: case sql::DataType::SET: case sql::DataType::ENUM: case sql::DataType::JSON: CPP_INFO("It's a string"); return strtoull(getString(columnIndex).c_str(), NULL, 10); case sql::DataType::BIT: { uint64_t uval = 0; /* This length is in bytes, on the contrary to what can be seen in mysql_resultset.cpp where the Meta is used */ switch (*result_bind->rbind[columnIndex - 1].length) { case 8:uval = (uint64_t) bit_uint8korr(result_bind->rbind[columnIndex - 1].buffer);break; case 7:uval = (uint64_t) bit_uint7korr(result_bind->rbind[columnIndex - 1].buffer);break; case 6:uval = (uint64_t) bit_uint6korr(result_bind->rbind[columnIndex - 1].buffer);break; case 5:uval = (uint64_t) bit_uint5korr(result_bind->rbind[columnIndex - 1].buffer);break; case 4:uval = (uint64_t) bit_uint4korr(result_bind->rbind[columnIndex - 1].buffer);break; case 3:uval = (uint64_t) bit_uint3korr(result_bind->rbind[columnIndex - 1].buffer);break; case 2:uval = (uint64_t) bit_uint2korr(result_bind->rbind[columnIndex - 1].buffer);break; case 1:uval = (uint64_t) bit_uint1korr(result_bind->rbind[columnIndex - 1].buffer);break; } return uval; } case sql::DataType::YEAR: // fetched as a SMALLINT case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::MEDIUMINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: { // sql::DataType::YEAR is fetched as a SMALLINT, thus should not be in the switch uint64_t ret; bool is_it_null = *result_bind->rbind[columnIndex - 1].is_null != 0; bool is_it_unsigned = result_bind->rbind[columnIndex - 1].is_unsigned != 0; CPP_INFO_FMT("%d byte, %ssigned, null=%d", result_bind->rbind[columnIndex - 1].buffer_length, is_it_unsigned? "un":"", is_it_null); switch (result_bind->rbind[columnIndex - 1].buffer_length) { case 1: if (is_it_unsigned) { // ToDo: Really reinterpret_case or static_cast ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { // ToDo: Really reinterpret_case or static_cast ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; case 2: if (is_it_unsigned) { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; case 4: if (is_it_unsigned) { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } break; case 8: if (is_it_unsigned) { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; } else { ret = !is_it_null? *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer):0; #if WE_WANT_TO_SEE_MORE_FAILURES_IN_UNIT_RESULTSET if (is_it_null) { if (cutTooBig && *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer) < 0) { ret = *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer); } else { ret = *reinterpret_cast(result_bind->rbind[columnIndex - 1].buffer); } } else { ret = 0; } #endif } break; default: throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getInt64_intern: invalid type"); } CPP_INFO_FMT("value=%lld", ret); return ret; } default: break; // ToDo : Geometry? default ? } CPP_ERR("MySQL_Prepared_ResultSet::getUInt64_intern: unhandled type. Please, report"); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getUInt64_intern: unhandled type. Please, report"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getUInt64() -I- */ uint64_t MySQL_Prepared_ResultSet::getUInt64(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getUInt64(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getUInt64: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getUInt64: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (*result_bind->rbind[columnIndex - 1].is_null) { return 0; } return getUInt64_intern(columnIndex, true); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getUInt64() -I- */ uint64_t MySQL_Prepared_ResultSet::getUInt64(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getUInt64(string)"); return getUInt64(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getMetaData() -I- */ sql::ResultSetMetaData * MySQL_Prepared_ResultSet::getMetaData() const { CPP_ENTER("MySQL_Prepared_ResultSet::getMetaData"); checkValid(); return rs_meta.get(); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getRow() -I- */ size_t MySQL_Prepared_ResultSet::getRow() const { CPP_ENTER("MySQL_Prepared_ResultSet::getRow"); checkValid(); /* row_position is 0 based */ return static_cast (row_position); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getRowId() -U- */ sql::RowID * MySQL_Prepared_ResultSet::getRowId(uint32_t) { CPP_ENTER("MySQL_Prepared_ResultSet::getRowId"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getRowId()"); return NULL; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getRowId() -U- */ sql::RowID * MySQL_Prepared_ResultSet::getRowId(const sql::SQLString &) { CPP_ENTER("MySQL_Prepared_ResultSet::getRowId"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getRowId()"); return NULL; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getStatement() -I- */ const sql::Statement * MySQL_Prepared_ResultSet::getStatement() const { CPP_ENTER("MySQL_Prepared_ResultSet::getStatement"); return parent; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getString() -I- */ SQLString MySQL_Prepared_ResultSet::getString(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::getString(int)"); CPP_INFO_FMT("column=%u", columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::getString: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQLPreparedResultSet::getString: invalid 'columnIndex'"); } last_queried_column = columnIndex; if (*result_bind->rbind[columnIndex - 1].is_null) { return sql::SQLString(""); } switch (rs_meta->getColumnType(columnIndex)) { case sql::DataType::TIMESTAMP: { char buf[28]; MYSQL_TIME * t = static_cast(result_bind->rbind[columnIndex - 1].buffer); if (t->second_part) { snprintf(buf, sizeof(buf) - 1, "%04d-%02d-%02d %02d:%02d:%02d.%06lu", t->year, t->month, t->day, t->hour, t->minute, t->second, t->second_part); } else { snprintf(buf, sizeof(buf) - 1, "%04d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); } CPP_INFO_FMT("It's a datetime/timestamp %s", buf); return sql::SQLString(buf); } case sql::DataType::DATE: { char buf[12]; MYSQL_TIME * t = static_cast(result_bind->rbind[columnIndex - 1].buffer); snprintf(buf, sizeof(buf) - 1, "%02d-%02d-%02d", t->year, t->month, t->day); CPP_INFO_FMT("It's a date %s", buf); return sql::SQLString(buf); } case sql::DataType::TIME: { char buf[18]; MYSQL_TIME * t = static_cast(result_bind->rbind[columnIndex - 1].buffer); if (t->second_part) { snprintf(buf, sizeof(buf), "%s%02d:%02d:%02d.%06lu", t->neg? "-":"", t->hour, t->minute, t->second, t->second_part); } else { snprintf(buf, sizeof(buf), "%s%02d:%02d:%02d", t->neg? "-":"", t->hour, t->minute, t->second); } CPP_INFO_FMT("It's a time %s", buf); return sql::SQLString(buf); } case sql::DataType::BIT: case sql::DataType::YEAR: // fetched as a SMALLINT case sql::DataType::TINYINT: case sql::DataType::SMALLINT: case sql::DataType::MEDIUMINT: case sql::DataType::INTEGER: case sql::DataType::BIGINT: { char buf[30]; CPP_INFO("It's an int"); if (result_bind->rbind[columnIndex - 1].is_unsigned) { my_ul_to_a(buf, sizeof(buf) - 1, getUInt64_intern(columnIndex, false)); } else { my_l_to_a(buf, sizeof(buf) - 1, getInt64_intern(columnIndex, false)); } return sql::SQLString(buf); } case sql::DataType::REAL: case sql::DataType::DOUBLE: { char buf[50]; CPP_INFO("It's a double"); my_f_to_a(buf, sizeof(buf) - 1, getDouble(columnIndex)); return sql::SQLString(buf); } case sql::DataType::NUMERIC: case sql::DataType::DECIMAL: case sql::DataType::CHAR: case sql::DataType::BINARY: case sql::DataType::VARCHAR: case sql::DataType::VARBINARY: case sql::DataType::LONGVARCHAR: case sql::DataType::LONGVARBINARY: case sql::DataType::SET: case sql::DataType::ENUM: case sql::DataType::JSON: CPP_INFO("It's a string"); return sql::SQLString(static_cast(result_bind->rbind[columnIndex - 1].buffer), *result_bind->rbind[columnIndex - 1].length); default: break; // ToDo : Geometry? default ? } CPP_ERR("MySQL_Prepared_ResultSet::getString: unhandled type. Please, report"); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getString: unhandled type. Please, report"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getString() -I- */ SQLString MySQL_Prepared_ResultSet::getString(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::getString(string)"); return getString(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getType() -I- */ sql::ResultSet::enum_type MySQL_Prepared_ResultSet::getType() const { CPP_ENTER("MySQL_ResultSet::getType"); checkValid(); return resultset_type; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::getWarnings() -U- */ void MySQL_Prepared_ResultSet::getWarnings() { CPP_ENTER("MySQL_Prepared_ResultSet::getWarnings"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::getWarnings()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isAfterLast() -I- */ bool MySQL_Prepared_ResultSet::isAfterLast() const { CPP_ENTER("MySQL_Prepared_ResultSet::beforeFirst"); checkValid(); checkScrollable(); return (row_position == num_rows + 1); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isBeforeFirst() -I- */ bool MySQL_Prepared_ResultSet::isBeforeFirst() const { CPP_ENTER("MySQL_Prepared_ResultSet::beforeFirst"); checkValid(); return (row_position == 0); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isClosed() -I- */ bool MySQL_Prepared_ResultSet::isClosed() const { return !is_valid; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::insertRow() -U- */ void MySQL_Prepared_ResultSet::insertRow() { CPP_ENTER("MySQL_Prepared_ResultSet::beforeFirst"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::insertRow()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isFirst() -I- */ bool MySQL_Prepared_ResultSet::isFirst() const { CPP_ENTER("MySQL_Prepared_ResultSet::beforeFirst"); checkValid(); return (row_position == 1); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isLast() -I- */ bool MySQL_Prepared_ResultSet::isLast() const { CPP_ENTER("MySQL_Prepared_ResultSet::isLast"); checkValid(); checkScrollable(); return (row_position == num_rows); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isNull() -I- */ bool MySQL_Prepared_ResultSet::isNull(const uint32_t columnIndex) const { CPP_ENTER("MySQL_Prepared_ResultSet::isNull(int)"); checkValid(); if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::isNull: invalid value of 'columnIndex'"); } /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::isNull: can't fetch because not on result set"); } return *result_bind->rbind[columnIndex - 1].is_null != 0; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isNull() -I- */ bool MySQL_Prepared_ResultSet::isNull(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_Prepared_ResultSet::isNull(string)"); uint32_t col_idx = findColumn(columnLabel); if (col_idx == 0) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::isNull: invalid value of 'columnLabel'"); } return isNull(col_idx); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::last() -I- */ bool MySQL_Prepared_ResultSet::last() { CPP_ENTER("MySQL_Prepared_ResultSet::last"); checkValid(); checkScrollable(); if (num_rows) { row_position = num_rows; seek(); } return num_rows? true:false; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::moveToCurrentRow() -U- */ void MySQL_Prepared_ResultSet::moveToCurrentRow() { CPP_ENTER("MySQL_Prepared_ResultSet::moveToCurrentRow"); checkValid(); checkScrollable(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::moveToCurrentRow()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::moveToInsertRow() -U- */ void MySQL_Prepared_ResultSet::moveToInsertRow() { CPP_ENTER("MySQL_Prepared_ResultSet::moveToInsertRow"); checkValid(); checkScrollable(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::moveToInsertRow()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::next() -I- */ bool MySQL_Prepared_ResultSet::next() { CPP_ENTER("MySQL_Prepared_ResultSet::next"); CPP_INFO_FMT("row_position=%llu num_rows=%llu", row_position, num_rows); checkValid(); bool ret = false; if (isScrollable()) { /* isBeforeFirst checks for validity */ if (isLast()) { ++row_position; ret = false; } else if (row_position < num_rows + 1) { if (row_position == 0) { proxy->data_seek(row_position); } else { /* NOTE: Buffered only optimization. If our position is anything else but beforeFirst/afterLast, then the last cursor operation ended with a mysql_stmt_fetch call, which by definition (?) moves the cursor to the next row after the fetched one. So, we do not need any positioning here. */ } int result = proxy->fetch(); if (!result || result == MYSQL_DATA_TRUNCATED) { ret = true; } if (result == MYSQL_NO_DATA) { ret = false; } if (result == 1) { CPP_ERR_FMT("Error fetching next row %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); sql::SQLException e(proxy->error(), proxy->sqlstate(), proxy->errNo()); throw e; } ++row_position; } CPP_INFO_FMT("new_row_position=%llu ret=%d", row_position, ret); } else { // reset last_queried_column last_queried_column = std::numeric_limits::max(); int result = proxy->fetch(); if (!result || result == MYSQL_DATA_TRUNCATED) { ret = true; } if (result == MYSQL_NO_DATA) { ret = false; } if (result == 1) { CPP_ERR_FMT("Error fetching next row %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); sql::SQLException e(proxy->error(), proxy->sqlstate(), proxy->errNo()); throw e; } ++row_position; } return ret; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::previous() -I- */ bool MySQL_Prepared_ResultSet::previous() { CPP_ENTER("MySQL_Prepared_ResultSet::previous"); checkScrollable(); /* isBeforeFirst checks for validity */ if (isBeforeFirst()) { return false; } else if (isFirst()) { beforeFirst(); return false; } else if (row_position > 1) { --row_position; proxy->data_seek(row_position - 1); int result = proxy->fetch(); if (!result || result == MYSQL_DATA_TRUNCATED) { return true; } if (result == MYSQL_NO_DATA) { return false; } throw sql::SQLException("Error during mysql_stmt_fetch"); } throw sql::SQLException("Impossible"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::refreshRow() -U- */ void MySQL_Prepared_ResultSet::refreshRow() { CPP_ENTER("MySQL_Prepared_ResultSet::refreshRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::refreshRow()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::relative() -I- */ bool MySQL_Prepared_ResultSet::relative(const int rows) { CPP_ENTER("MySQL_Prepared_ResultSet::relative"); checkValid(); checkScrollable(); if (rows != 0) { if (row_position + rows > num_rows || row_position + rows < 1) { row_position = rows > 0? num_rows + 1 : 0; /* after last or before first */ } else { row_position += rows; seek(); } } return (row_position > 0 && row_position <= num_rows); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::rowDeleted() -U- */ bool MySQL_Prepared_ResultSet::rowDeleted() { CPP_ENTER("MySQL_Prepared_ResultSet::rowDeleted"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::rowDeleted()"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::rowInserted() -U- */ bool MySQL_Prepared_ResultSet::rowInserted() { CPP_ENTER("MySQL_Prepared_ResultSet::rowInserted"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::rowInserted()"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::rowUpdated() -U- */ bool MySQL_Prepared_ResultSet::rowUpdated() { CPP_ENTER("MySQL_Prepared_ResultSet::rowUpdated"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::rowUpdated()"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::rowsCount() -I- */ size_t MySQL_Prepared_ResultSet::rowsCount() const { CPP_ENTER("MySQL_Prepared_ResultSet::rowsCount"); checkValid(); checkScrollable(); return static_cast(proxy->num_rows()); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::setFetchSize() -U- */ void MySQL_Prepared_ResultSet::setFetchSize(size_t /* rows */) { CPP_ENTER("MySQL_Prepared_ResultSet::setFetchSize"); checkValid(); throw sql::MethodNotImplementedException("MySQL_Prepared_ResultSet::setFetchSize()"); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::wasNull() -I- */ bool MySQL_Prepared_ResultSet::wasNull() const { CPP_ENTER("MySQL_Prepared_ResultSet::wasNull"); checkValid(); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::wasNull: can't fetch because not on result set"); } if (last_queried_column == std::numeric_limits::max()) { throw sql::InvalidArgumentException("MySQL_Prepared_ResultSet::wasNull: should be called only after one of the getter methods"); } return *result_bind->rbind[last_queried_column - 1].is_null != 0; } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::isBeforeFirstOrAfterLast() -I- */ bool MySQL_Prepared_ResultSet::isBeforeFirstOrAfterLast() const { CPP_ENTER("MySQL_Prepared_ResultSet::isBeforeFirstOrAfterLast"); checkValid(); return (row_position == 0) || (isScrollable() && (row_position == num_rows + 1)); } /* }}} */ /* {{{ MySQL_Prepared_ResultSet::seek() -I- */ void MySQL_Prepared_ResultSet::seek() { CPP_ENTER("MySQL_Prepared_ResultSet::seek"); proxy->data_seek(row_position - 1); proxy->fetch(); } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_ps_resultset.h000644 015771 000012 00000012035 12645244436 023411 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_PS_RESULTSET_H_ #define _MYSQL_PS_RESULTSET_H_ #include #include #include #include #include "nativeapi/mysql_private_iface.h" namespace sql { namespace mysql { class MySQL_Prepared_Statement; class MySQL_DebugLogger; class MySQL_PreparedResultSetMetaData; class MySQL_ResultBind; namespace NativeAPI { class NativeStatementWrapper; } class MySQL_Prepared_ResultSet : public sql::ResultSet { private: MYSQL_ROW row; boost::shared_ptr< NativeAPI::NativeStatementWrapper > proxy; mutable uint32_t last_queried_column; // this is updated by calls to getInt(int), getString(int), etc... unsigned int num_fields; uint64_t num_rows; uint64_t row_position; typedef std::map< sql::SQLString, unsigned int > FieldNameIndexMap; FieldNameIndexMap field_name_to_index_map; bool was_null; const MySQL_Prepared_Statement * parent; bool is_valid; boost::shared_ptr< MySQL_DebugLogger > logger; boost::scoped_ptr< MySQL_PreparedResultSetMetaData > rs_meta; boost::shared_ptr< MySQL_ResultBind > result_bind; sql::ResultSet::enum_type resultset_type; protected: void checkValid() const; void checkScrollable() const; bool isScrollable() const; void closeIntern(); bool isBeforeFirstOrAfterLast() const; void seek(); int64_t getInt64_intern(const uint32_t columnIndex, bool cutTooBig) const; uint64_t getUInt64_intern(const uint32_t columnIndex, bool cutTooBig) const; public: MySQL_Prepared_ResultSet(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & s, boost::shared_ptr< MySQL_ResultBind > & r_bind, sql::ResultSet::enum_type rset_type, MySQL_Prepared_Statement * par, boost::shared_ptr< MySQL_DebugLogger > &l); virtual ~MySQL_Prepared_ResultSet(); bool absolute(int row); void afterLast(); void beforeFirst(); void cancelRowUpdates(); void clearWarnings(); void close(); uint32_t findColumn(const sql::SQLString& columnLabel) const; bool first(); std::istream * getBlob(uint32_t columnIndex) const; std::istream * getBlob(const sql::SQLString& columnLabel) const; bool getBoolean(uint32_t columnIndex) const; bool getBoolean(const sql::SQLString& columnLabel) const; int getConcurrency(); SQLString getCursorName(); long double getDouble(uint32_t columnIndex) const; long double getDouble(const sql::SQLString& columnLabel) const; int getFetchDirection(); size_t getFetchSize(); int getHoldability(); int32_t getInt(uint32_t columnIndex) const; int32_t getInt(const sql::SQLString& columnLabel) const; uint32_t getUInt(uint32_t columnIndex) const; uint32_t getUInt(const sql::SQLString& columnLabel) const; int64_t getInt64(uint32_t columnIndex) const; int64_t getInt64(const sql::SQLString& columnLabel) const; uint64_t getUInt64(uint32_t columnIndex) const; uint64_t getUInt64(const sql::SQLString& columnLabel) const; sql::ResultSetMetaData * getMetaData() const; size_t getRow() const; sql::RowID * getRowId(uint32_t columnIndex); sql::RowID * getRowId(const sql::SQLString & columnLabel); const sql::Statement * getStatement() const; SQLString getString(uint32_t columnIndex) const; SQLString getString(const sql::SQLString& columnLabel) const; sql::ResultSet::enum_type getType() const; void getWarnings(); bool isAfterLast() const; bool isBeforeFirst() const; bool isClosed() const; void insertRow(); bool isFirst() const; bool isLast() const; bool isNull(uint32_t columnIndex) const; bool isNull(const sql::SQLString& columnLabel) const; bool last(); void moveToCurrentRow(); void moveToInsertRow(); bool next(); bool previous(); void refreshRow(); bool relative(int rows); bool rowDeleted(); bool rowInserted(); bool rowUpdated(); size_t rowsCount() const; void setFetchSize(size_t rows); bool wasNull() const; }; } /* namespace mysql*/ } /* namespace sql*/ #endif // _MYSQL_PS_RESULTSET_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_ps_resultset_metadata.cpp000644 015771 000012 00000031344 12645244436 025610 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "mysql_util.h" #include "mysql_ps_resultset.h" #include "mysql_ps_resultset_metadata.h" #include "nativeapi/native_statement_wrapper.h" #include "nativeapi/native_resultset_wrapper.h" #include "mysql_debug.h" #define MAX_LEN_PER_CHAR 4 namespace sql { namespace mysql { /* {{{ MySQL_PreparedResultSetMetaData::MySQL_PreparedResultSetMetaData -I- */ MySQL_PreparedResultSetMetaData::MySQL_PreparedResultSetMetaData(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & _proxy, boost::shared_ptr< MySQL_DebugLogger> & l) : proxy(_proxy), logger(l), result_meta( _proxy->result_metadata()), num_fields(_proxy->field_count()) { CPP_ENTER("MySQL_PreparedResultSetMetaData::MySQL_PreparedResultSetMetaData"); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::~MySQL_PreparedResultSetMetaData -I- */ MySQL_PreparedResultSetMetaData::~MySQL_PreparedResultSetMetaData() { CPP_ENTER("MySQL_PreparedResultSetMetaData::~MySQL_PreparedResultSetMetaData"); CPP_INFO_FMT("this=%p", this); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::checkColumnIndex -I- */ void MySQL_PreparedResultSetMetaData::checkColumnIndex(unsigned int columnIndex) const { if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("Invalid value for columnIndex"); } } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getCatalogName -I- */ SQLString MySQL_PreparedResultSetMetaData::getCatalogName(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getCatalogName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->catalog; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnCount -I- */ unsigned int MySQL_PreparedResultSetMetaData::getColumnCount() { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnCount"); CPP_INFO_FMT("this=%p", this); return num_fields; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnDisplaySize -I- */ unsigned int MySQL_PreparedResultSetMetaData::getColumnDisplaySize(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnDisplaySize"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } int ret = field->length / cs->char_maxlen; CPP_INFO_FMT("column=%u display_size=%d", columnIndex, ret); return ret; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnLabel -I- */ SQLString MySQL_PreparedResultSetMetaData::getColumnLabel(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnLabel"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->name; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnName -I- */ SQLString MySQL_PreparedResultSetMetaData::getColumnName(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->org_name; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnType -I- */ int MySQL_PreparedResultSetMetaData::getColumnType(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnType"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("column=%u", columnIndex); checkColumnIndex(columnIndex); int mysql_type = getFieldMeta(columnIndex)->type; CPP_INFO_FMT("type=%d", mysql_type); int ret = sql::mysql::util::mysql_type_to_datatype( getFieldMeta(columnIndex) ); CPP_INFO_FMT("our type is %d", ret); return ret; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnTypeName -I- */ SQLString MySQL_PreparedResultSetMetaData::getColumnTypeName(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnTypeName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return sql::mysql::util::mysql_type_to_string(getFieldMeta(columnIndex), this->logger); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnCharset -I- */ SQLString MySQL_PreparedResultSetMetaData::getColumnCharset(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnCharset"); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg; msg << "Server sent unknown charsetnr (" << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return cs->name; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getColumnCollation -I- */ SQLString MySQL_PreparedResultSetMetaData::getColumnCollation(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getColumnCollation"); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg; msg << "Server sent unknown charsetnr (" << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return cs->collation; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getFieldMeta -I- */ MYSQL_FIELD * MySQL_PreparedResultSetMetaData::getFieldMeta(unsigned int columnIndex) const { return result_meta->fetch_field_direct(columnIndex - 1); } /* }}} */ // Precision - total number of digits /* {{{ MySQL_PreparedResultSetMetaData::getPrecision -I- */ unsigned int MySQL_PreparedResultSetMetaData::getPrecision(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getPrecision"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); unsigned int ret = getFieldMeta(columnIndex)->max_length - getScale(columnIndex); CPP_INFO_FMT("column=%u precision=%d", columnIndex, ret); return ret; } /* }}} */ // Scale - Number of digits right of the decimal point /* {{{ MySQL_PreparedResultSetMetaData::getScale -I- */ unsigned int MySQL_PreparedResultSetMetaData::getScale(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getScale"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); unsigned int ret = getFieldMeta(columnIndex)->decimals; CPP_INFO_FMT("column=%u scale=%d", columnIndex, ret); return ret; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getSchemaName -I- */ SQLString MySQL_PreparedResultSetMetaData::getSchemaName(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getSchemaName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); const char * const db = getFieldMeta(columnIndex)->db; return db ? db : ""; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::getTableName -I- */ SQLString MySQL_PreparedResultSetMetaData::getTableName(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::getTableName"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->org_table; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isAutoIncrement -I- */ bool MySQL_PreparedResultSetMetaData::isAutoIncrement(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isAutoIncrement"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return (getFieldMeta(columnIndex)->flags & AUTO_INCREMENT_FLAG ) != 0; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isCaseSensitive -I- */ bool MySQL_PreparedResultSetMetaData::isCaseSensitive(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isCaseSensitive"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); if (field->flags & NUM_FLAG || field->type == MYSQL_TYPE_NEWDECIMAL || field->type == MYSQL_TYPE_DECIMAL) { return false; } const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return NULL == strstr(cs->collation, "_ci"); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isCurrency -I- */ bool MySQL_PreparedResultSetMetaData::isCurrency(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isCurrency"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isDefinitelyWritable -I- */ bool MySQL_PreparedResultSetMetaData::isDefinitelyWritable(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isDefinitelyWritable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return isWritable(columnIndex); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isNullable -I- */ int MySQL_PreparedResultSetMetaData::isNullable(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isNullable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->flags & NOT_NULL_FLAG? columnNoNulls : columnNullable; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isNumeric -I- */ bool MySQL_PreparedResultSetMetaData::isNumeric(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isNumeric"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return (getFieldMeta(columnIndex)->flags & NUM_FLAG) != 0; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isReadOnly -I- */ bool MySQL_PreparedResultSetMetaData::isReadOnly(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isReadOnly"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); /* Seems for Views, where the value is generated DB is empty everything else is set */ const char * const db = getFieldMeta(columnIndex)->db; return !(db && strlen(db)); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isSearchable -I- */ bool MySQL_PreparedResultSetMetaData::isSearchable(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isSearchable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return true; } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isSigned -I- */ bool MySQL_PreparedResultSetMetaData::isSigned(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isSigned"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); if (getFieldMeta(columnIndex)->type == FIELD_TYPE_YEAR) { return false; } return !(getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isWritable -I- */ bool MySQL_PreparedResultSetMetaData::isWritable(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isWritable"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return !isReadOnly(columnIndex); } /* }}} */ /* {{{ MySQL_PreparedResultSetMetaData::isZerofill -I- */ bool MySQL_PreparedResultSetMetaData::isZerofill(unsigned int columnIndex) { CPP_ENTER("MySQL_PreparedResultSetMetaData::isZerofill"); CPP_INFO_FMT("this=%p", this); checkColumnIndex(columnIndex); return (getFieldMeta(columnIndex)->flags & ZEROFILL_FLAG) != 0; } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_ps_resultset_metadata.h000644 015771 000012 00000007150 12645244436 025253 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_PS_RESULTSET_METADATA_H_ #define _MYSQL_PS_RESULTSET_METADATA_H_ #include #include #include "nativeapi/mysql_private_iface.h" #include #include namespace sql { namespace mysql { namespace NativeAPI { class NativeResultsetWrapper; class NativeStatementWrapper; } class MySQL_DebugLogger; class MySQL_PreparedResultSetMetaData : public sql::ResultSetMetaData { boost::shared_ptr< NativeAPI::NativeStatementWrapper > proxy; boost::shared_ptr< MySQL_DebugLogger > logger; boost::scoped_ptr< NativeAPI::NativeResultsetWrapper > result_meta; unsigned int num_fields; public: MySQL_PreparedResultSetMetaData(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & _proxy, boost::shared_ptr< MySQL_DebugLogger> & l); virtual ~MySQL_PreparedResultSetMetaData(); SQLString getCatalogName(unsigned int columnIndex); unsigned int getColumnCount(); unsigned int getColumnDisplaySize(unsigned int columnIndex); SQLString getColumnLabel(unsigned int columnIndex); SQLString getColumnName(unsigned int columnIndex); int getColumnType(unsigned int columnIndex); SQLString getColumnTypeName(unsigned int columnIndex); SQLString getColumnCharset(unsigned int columnIndex); SQLString getColumnCollation(unsigned int columnIndex); unsigned int getPrecision(unsigned int columnIndex); unsigned int getScale(unsigned int columnIndex); SQLString getSchemaName(unsigned int columnIndex); SQLString getTableName(unsigned int columnIndex); bool isAutoIncrement(unsigned int columnIndex); bool isCaseSensitive(unsigned int columnIndex); bool isCurrency(unsigned int columnIndex); bool isDefinitelyWritable(unsigned int columnIndex); int isNullable(unsigned int columnIndex); bool isNumeric(unsigned int columnIndex); bool isReadOnly(unsigned int columnIndex); bool isSearchable(unsigned int columnIndex); bool isSigned(unsigned int columnIndex); bool isWritable(unsigned int columnIndex); bool isZerofill(unsigned int column); protected: void checkColumnIndex(unsigned int columnIndex) const; MYSQL_FIELD * getFieldMeta(unsigned int columnIndex) const; private: /* Prevent use of these */ MySQL_PreparedResultSetMetaData(const MySQL_PreparedResultSetMetaData &); void operator=(MySQL_PreparedResultSetMetaData &); }; } /* namespace mysql */ } /* namespace sql */ #endif /* _MYSQL_PS_RESULTSET_METADATA_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_public_iface.h000644 015771 000012 00000003374 12645244436 023270 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Public interface of the MySQL Connector/C++. You might not use it but directly include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #ifndef MYSQL_PUBLIC_IFACE_H_ #define MYSQL_PUBLIC_IFACE_H_ #include #include #include #include #include #include #include #include /*#include #endif /* MYSQL_PUBLIC_IFACE_H_ */ mysql-connector-c++-1.1.7/driver/mysql_resultbind.cpp000644 015771 000012 00000013471 12645244436 023370 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "mysql_util.h" #include "mysql_debug.h" #include "mysql_resultbind.h" #include "nativeapi/native_statement_wrapper.h" #include "nativeapi/native_resultset_wrapper.h" #include #include namespace sql { namespace mysql { struct st_buffer_size_type { char * buffer; size_t size; enum_field_types type; st_buffer_size_type(char * b, size_t s, enum_field_types t) : buffer(b), size(s), type(t) {} }; /* {{{ allocate_buffer_for_field() -I- */ typedef std::pair BufferSizePair; static struct st_buffer_size_type allocate_buffer_for_field(const MYSQL_FIELD * const field) { switch (field->type) { case MYSQL_TYPE_NULL: return st_buffer_size_type(NULL, 0, field->type); case MYSQL_TYPE_TINY: return st_buffer_size_type(new char[1], 1, field->type); case MYSQL_TYPE_SHORT: return st_buffer_size_type(new char[2], 2, field->type); case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_FLOAT: return st_buffer_size_type(new char[4], 4, field->type); case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_LONGLONG: return st_buffer_size_type(new char[8], 8, field->type); case MYSQL_TYPE_YEAR: return st_buffer_size_type(new char[2], 2, MYSQL_TYPE_SHORT); case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: return st_buffer_size_type(new char[sizeof(MYSQL_TIME)], sizeof(MYSQL_TIME), field->type); case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_JSON: return st_buffer_size_type(new char[field->max_length + 1], field->max_length + 1, field->type); case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: return st_buffer_size_type(new char[64], 64, field->type); #if A1 case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_YEAR: return st_buffer_size_type(new char[10], 10, field->type); #endif #if A0 // There two are not sent over the wire case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: #endif case MYSQL_TYPE_BIT: return st_buffer_size_type(new char[8], 8, MYSQL_TYPE_BIT); case MYSQL_TYPE_GEOMETRY: default: // TODO: Andrey, there can be crashes when we go through this. Please fix. throw sql::InvalidArgumentException("allocate_buffer_for_field: invalid rbind data type"); } } /* }}} */ /* {{{ MySQL_ResultBind::MySQL_ResultBind -I- */ MySQL_ResultBind::MySQL_ResultBind(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & stmt, boost::shared_ptr< MySQL_DebugLogger > & log) : num_fields(0), is_null(NULL), err(NULL), len(NULL), proxy(stmt), logger(log), rbind(NULL) { } /* }}} */ /* {{{ MySQL_ResultBind::~MySQL_ResultBind() -I- */ MySQL_ResultBind::~MySQL_ResultBind() { if (rbind.get()) { for (unsigned int i = 0; i < num_fields; ++i) { delete[] (char *) rbind[i].buffer; } } } /* }}} */ /* {{{ MySQL_ResultBind::bindResult() -I- */ void MySQL_ResultBind::bindResult() { CPP_ENTER("MySQL_Prepared_Statement::bindResult"); for (unsigned int i = 0; i < num_fields; ++i) { delete[] (char *) rbind[i].buffer; } rbind.reset(NULL); is_null.reset(NULL); err.reset(NULL); len.reset(NULL); num_fields = proxy->field_count(); if (!num_fields) { return; } rbind.reset(new MYSQL_BIND[num_fields]); memset(rbind.get(), 0, sizeof(MYSQL_BIND) * num_fields); is_null.reset(new my_bool[num_fields]); memset(is_null.get(), 0, sizeof(my_bool) * num_fields); err.reset(new my_bool[num_fields]); memset(err.get(), 0, sizeof(my_bool) * num_fields); len.reset(new unsigned long[num_fields]); memset(len.get(), 0, sizeof(unsigned long) * num_fields); boost::scoped_ptr< NativeAPI::NativeResultsetWrapper > resultMeta(proxy->result_metadata()); for (unsigned int i = 0; i < num_fields; ++i) { MYSQL_FIELD * field = resultMeta->fetch_field(); struct st_buffer_size_type p = allocate_buffer_for_field(field); rbind[i].buffer_type= p.type; rbind[i].buffer = p.buffer; rbind[i].buffer_length= static_cast(p.size); rbind[i].length = &len[i]; rbind[i].is_null = &is_null[i]; rbind[i].error = &err[i]; rbind[i].is_unsigned= field->flags & UNSIGNED_FLAG; } if (proxy->bind_result(rbind.get())) { CPP_ERR_FMT("Couldn't bind : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str()); sql::mysql::util::throwSQLException(*proxy.get()); } } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_resultbind.h000644 015771 000012 00000004125 12645244436 023031 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_RESULTBIND_H_ #define _MYSQL_RESULTBIND_H_ #include #include #include #include "nativeapi/mysql_private_iface.h" #include "mysql_util.h" namespace sql { namespace mysql { namespace NativeAPI { class NativeStatementWrapper; } class MySQL_ResultBind { unsigned int num_fields; boost::scoped_array< char > is_null; boost::scoped_array< char > err; boost::scoped_array< unsigned long > len; boost::shared_ptr< NativeAPI::NativeStatementWrapper > proxy; boost::shared_ptr< MySQL_DebugLogger > logger; public: boost::scoped_array< MYSQL_BIND > rbind; MySQL_ResultBind( boost::shared_ptr< NativeAPI::NativeStatementWrapper > & _capi, boost::shared_ptr< MySQL_DebugLogger > & log); ~MySQL_ResultBind(); void bindResult(); }; } /* namespace mysql */ } /* namespace sql */ #endif /* _MYSQL_RESULTBIND_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_resultset.cpp000644 015771 000012 00000073157 12645244436 023256 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include "mysql_util.h" #include "mysql_resultset.h" #include "mysql_resultset_metadata.h" #include "mysql_statement.h" #include "nativeapi/native_connection_wrapper.h" #include "nativeapi/native_resultset_wrapper.h" #include "mysql_debug.h" //Prevent windows min() macro because of std::numeric_limits::min() #undef min namespace sql { namespace mysql { /* {{{ MySQL_ResultSet::MySQL_ResultSet() -I- */ MySQL_ResultSet::MySQL_ResultSet(boost::shared_ptr< NativeAPI::NativeResultsetWrapper > res, boost::weak_ptr< NativeAPI::NativeConnectionWrapper > _proxy, sql::ResultSet::enum_type rset_type, MySQL_Statement * par, boost::shared_ptr< MySQL_DebugLogger > & l ) : row(NULL), result(res), proxy(_proxy), row_position(0), was_null(false), last_queried_column(-1), parent(par), logger(l), resultset_type(rset_type) { CPP_ENTER("MySQL_ResultSet::MySQL_ResultSet"); num_rows = result->num_rows(); num_fields = result->num_fields(); for (unsigned int i = 0; i < num_fields; ++i) { #if A0 std::cout << "Elements=" << field_name_to_index_map.size() << "\n"; #endif boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(getFieldMeta(i + 1)->name, 0)); field_name_to_index_map[upstring.get()] = i; } #if A0 std::cout << "Elements=" << field_name_to_index_map.size() << "\n"; #endif rs_meta.reset(new MySQL_ResultSetMetaData(result, logger)); } /* }}} */ /* {{{ MySQL_ResultSet::~MySQL_ResultSet() -I- */ MySQL_ResultSet::~MySQL_ResultSet() { CPP_ENTER("MySQL_ResultSet::~MySQL_ResultSet"); } /* }}} */ /* {{{ MySQL_ResultSet::absolute() -I- */ bool MySQL_ResultSet::absolute(const int new_pos) { CPP_ENTER("MySQL_ResultSet::absolute"); checkValid(); checkScrollable(); if (new_pos > 0) { if (new_pos > (int) num_rows) { row_position = num_rows + 1; /* after last row */ } else { row_position = (my_ulonglong) new_pos; /* the cast is inspected and is valid */ seek(); return true; } } else if (new_pos < 0) { if ((-new_pos) > (int) num_rows || (new_pos == std::numeric_limits::min())) { row_position = 0; /* before first new_pos */ } else { row_position = num_rows - (-new_pos) + 1; seek(); return true; } } else { /* According to the JDBC book, absolute(0) means before the result set */ row_position = 0; /* no seek() here, as we are not on data*/ result->data_seek(0); } return (row_position > 0 && row_position < (num_rows + 1)); } /* }}} */ /* {{{ MySQL_ResultSet::afterLast() -I- */ void MySQL_ResultSet::afterLast() { CPP_ENTER("MySQL_ResultSet::afterLast"); checkValid(); row_position = num_rows + 1; } /* }}} */ /* {{{ MySQL_ResultSet::beforeFirst() -I- */ void MySQL_ResultSet::beforeFirst() { CPP_ENTER("MySQL_ResultSet::beforeFirst"); checkValid(); checkScrollable(); result->data_seek(0); row_position = 0; } /* }}} */ /* {{{ MySQL_ResultSet::cancelRowUpdates() -U- */ void MySQL_ResultSet::cancelRowUpdates() { CPP_ENTER("MySQL_ResultSet::cancelRowUpdates"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::cancelRowUpdates()"); } /* }}} */ /* {{{ MySQL_ResultSet::checkScrollable() -I- */ void MySQL_ResultSet::checkScrollable() const { CPP_ENTER("MySQL_ResultSet::checkScrollable"); CPP_INFO_FMT("this=%p", this); if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) { throw sql::NonScrollableException("Nonscrollable result set"); } // reset last_queried_column last_queried_column = -1; } /* }}} */ /* {{{ MySQL_ResultSet::isScrollable() -I- */ bool MySQL_ResultSet::isScrollable() const { // CPP_ENTER("MySQL_ResultSet::isScrollable"); // CPP_INFO_FMT("this=%p", this); return (resultset_type != sql::ResultSet::TYPE_FORWARD_ONLY); } /* }}} */ /* {{{ MySQL_ResultSet::checkValid() -I- */ void MySQL_ResultSet::checkValid() const { CPP_ENTER("MySQL_ResultSet::checkValid"); CPP_INFO_FMT("this=%p", this); if (isClosed()) { throw sql::InvalidInstanceException("ResultSet has been closed"); } } /* }}} */ /* {{{ MySQL_ResultSet::clearWarnings() -U- */ void MySQL_ResultSet::clearWarnings() { CPP_ENTER("MySQL_ResultSet::clearWarnings"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::clearWarnings()"); } /* }}} */ /* {{{ MySQL_ResultSet::close() -I- */ void MySQL_ResultSet::close() { CPP_ENTER("MySQL_ResultSet::close"); checkValid(); result.reset(); // result->dispose(); } /* }}} */ /* {{{ MySQL_ResultSet::findColumn() -I- */ uint32_t MySQL_ResultSet::findColumn(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::findColumn"); checkValid(); boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(columnLabel.c_str(), 0)); #if A0 std::cout << "Elements=" << field_name_to_index_map.size() << "\n"; FieldNameIndexMap::const_iterator tmp_iter = field_name_to_index_map.begin(); FieldNameIndexMap::const_iterator tmp_iter_end = field_name_to_index_map.end(); for (;tmp_iter != tmp_iter_end; tmp_iter++) { std::cout << "[[" << tmp_iter->first << "]] second=[[" << tmp_iter->second << "]]\n"; } sql::SQLString tmp(upstring.get()); std::cout << "[" << tmp << "]\n"; #endif FieldNameIndexMap::const_iterator iter = field_name_to_index_map.find(sql::SQLString(upstring.get())); if (iter == field_name_to_index_map.end()) { return 0; } /* findColumn returns 1-based indexes */ return iter->second + 1; } /* }}} */ /* {{{ MySQL_ResultSet::first() -I- */ bool MySQL_ResultSet::first() { CPP_ENTER("MySQL_ResultSet::first"); checkValid(); checkScrollable(); if (num_rows) { row_position = 1; seek(); } return num_rows != 0; } /* }}} */ /* {{{ MySQL_ResultSet::getBlob() -I- */ std::istream * MySQL_ResultSet::getBlob(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getBlob(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set"); } return new std::istringstream(getString(columnIndex)); } /* }}} */ /* {{{ MySQL_ResultSet::getBlob() -I- */ std::istream * MySQL_ResultSet::getBlob(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getBlob(string)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set"); } return new std::istringstream(getString(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getBoolean() -I- */ bool MySQL_ResultSet::getBoolean(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getBoolean(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set"); } return getInt(columnIndex)? true:false; } /* }}} */ /* {{{ MySQL_ResultSet::getBoolean() -I- */ bool MySQL_ResultSet::getBoolean(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getBoolean(string)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set"); } return getInt(columnLabel)? true:false; } /* }}} */ /* {{{ MySQL_ResultSet::getConcurrency() -U- */ int MySQL_ResultSet::getConcurrency() { CPP_ENTER("MySQL_ResultSet::getConcurrency"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getConcurrency()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getCursorName() -U- */ SQLString MySQL_ResultSet::getCursorName() { CPP_ENTER("MySQL_ResultSet::getCursorName"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getCursorName()"); return ""; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getDouble() -I- */ long double MySQL_ResultSet::getDouble(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getDouble(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getDouble: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::getDouble: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (row[columnIndex - 1] == NULL) { was_null = true; return 0.0; } was_null = false; if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT) { return static_cast(getInt64(columnIndex)); } return sql::mysql::util::strtold(row[columnIndex - 1], NULL); } /* }}} */ /* {{{ MySQL_ResultSet::getDouble() -I- */ long double MySQL_ResultSet::getDouble(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getDouble(string)"); return getDouble(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getFetchDirection() -U- */ int MySQL_ResultSet::getFetchDirection() { CPP_ENTER("MySQL_ResultSet::getFetchDirection"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getFetchDirection()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getFetchSize() -U- */ size_t MySQL_ResultSet::getFetchSize() { CPP_ENTER("MySQL_ResultSet::getFetchSize"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getFetchSize()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getFieldMeta() -U- */ MYSQL_FIELD * MySQL_ResultSet::getFieldMeta(unsigned int columnIndex) const { return result->fetch_field_direct(columnIndex - 1); } /* }}} */ /* {{{ MySQL_ResultSet::getHoldability() -U- */ int MySQL_ResultSet::getHoldability() { CPP_ENTER("MySQL_ResultSet::getHoldability"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getHoldability()"); return 0; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getInt() -I- */ int32_t MySQL_ResultSet::getInt(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getInt(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getInt: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::getInt: invalid value of 'columnIndex'"); } CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":""); if (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG) { return static_cast(getInt64(columnIndex)); } return static_cast(getInt64(columnIndex)); } /* }}} */ /* {{{ MySQL_ResultSet::getInt() -I- */ int32_t MySQL_ResultSet::getInt(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getInt(string)"); return getInt(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getUInt() -I- */ uint32_t MySQL_ResultSet::getUInt(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getUInt(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt: invalid value of 'columnIndex'"); } CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":""); return static_cast(getUInt64(columnIndex));// & 0xffffffff; } /* }}} */ /* {{{ MySQL_ResultSet::getUInt() -I- */ uint32_t MySQL_ResultSet::getUInt(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getUInt(string)"); return getUInt(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getInt64() -I- */ int64_t MySQL_ResultSet::getInt64(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getInt64(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getInt64: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::getInt64: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (row[columnIndex - 1] == NULL) { was_null = true; return 0; } CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":""); was_null = false; if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT && getFieldMeta(columnIndex)->flags != (BINARY_FLAG|UNSIGNED_FLAG)) { uint64_t uval = 0; std::div_t length= std::div(getFieldMeta(columnIndex)->length, 8); if (length.rem) { ++length.quot; } switch (length.quot) { case 8:uval = (uint64_t) bit_uint8korr(row[columnIndex - 1]);break; case 7:uval = (uint64_t) bit_uint7korr(row[columnIndex - 1]);break; case 6:uval = (uint64_t) bit_uint6korr(row[columnIndex - 1]);break; case 5:uval = (uint64_t) bit_uint5korr(row[columnIndex - 1]);break; case 4:uval = (uint64_t) bit_uint4korr(row[columnIndex - 1]);break; case 3:uval = (uint64_t) bit_uint3korr(row[columnIndex - 1]);break; case 2:uval = (uint64_t) bit_uint2korr(row[columnIndex - 1]);break; case 1:uval = (uint64_t) bit_uint1korr(row[columnIndex - 1]);break; } return uval; } if (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG) { return strtoull(row[columnIndex - 1], NULL, 10); } return strtoll(row[columnIndex - 1], NULL, 10); } /* }}} */ /* {{{ MySQL_ResultSet::getInt64() -I- */ int64_t MySQL_ResultSet::getInt64(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getInt64(string)"); return getInt64(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getUInt64() -I- */ uint64_t MySQL_ResultSet::getUInt64(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getUInt64(int)"); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt64: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt64: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (row[columnIndex - 1] == NULL) { was_null = true; return 0; } CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":""); was_null = false; if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT && getFieldMeta(columnIndex)->flags != (BINARY_FLAG|UNSIGNED_FLAG)) { uint64_t uval = 0; std::div_t length= std::div(getFieldMeta(columnIndex)->length, 8); if (length.rem) { ++length.quot; } switch (length.quot) { case 8:uval = (uint64_t) bit_uint8korr(row[columnIndex - 1]);break; case 7:uval = (uint64_t) bit_uint7korr(row[columnIndex - 1]);break; case 6:uval = (uint64_t) bit_uint6korr(row[columnIndex - 1]);break; case 5:uval = (uint64_t) bit_uint5korr(row[columnIndex - 1]);break; case 4:uval = (uint64_t) bit_uint4korr(row[columnIndex - 1]);break; case 3:uval = (uint64_t) bit_uint3korr(row[columnIndex - 1]);break; case 2:uval = (uint64_t) bit_uint2korr(row[columnIndex - 1]);break; case 1:uval = (uint64_t) bit_uint1korr(row[columnIndex - 1]);break; } return uval; } if (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG) { return strtoull(row[columnIndex - 1], NULL, 10); } return strtoll(row[columnIndex - 1], NULL, 10); } /* }}} */ /* {{{ MySQL_ResultSet::getUInt64() -I- */ uint64_t MySQL_ResultSet::getUInt64(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getUInt64(string)"); return getUInt64(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getMetaData() -I- */ sql::ResultSetMetaData * MySQL_ResultSet::getMetaData() const { CPP_ENTER("MySQL_ResultSet::getMetaData"); checkValid(); return rs_meta.get(); } /* }}} */ /* {{{ MySQL_ResultSet::getRow() -I- */ size_t MySQL_ResultSet::getRow() const { CPP_ENTER("MySQL_ResultSet::getRow"); checkValid(); /* row_position is 0 based */ return static_cast(row_position); } /* }}} */ /* {{{ MySQL_ResultSet::getRowId() -U- */ sql::RowID * MySQL_ResultSet::getRowId(uint32_t) { CPP_ENTER("MySQL_ResultSet::getRowId"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getRowId(uint32_t columnIndex)"); return NULL; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getRowId() -U- */ sql::RowID * MySQL_ResultSet::getRowId(const sql::SQLString &) { CPP_ENTER("MySQL_ResultSet::getRowId"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getRowId(const sql::SQLString & columnLabel)"); return NULL; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::getStatement() -I- */ const sql::Statement * MySQL_ResultSet::getStatement() const { CPP_ENTER("MySQL_ResultSet::getStatement"); return parent; } /* }}} */ /* {{{ MySQL_ResultSet::getString() -I- */ SQLString MySQL_ResultSet::getString(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::getString(int)"); CPP_INFO_FMT("this=%p column=%u", this, columnIndex); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getString: can't fetch because not on result set"); } if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::getString: invalid value of 'columnIndex'"); } last_queried_column = columnIndex; if (row == NULL || row[columnIndex - 1] == NULL) { was_null = true; return ""; } if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT) { char buf[30]; snprintf(buf, sizeof(buf) - 1, "%llu", (unsigned long long) getUInt64(columnIndex)); return sql::SQLString(buf); } size_t len = result->fetch_lengths()[columnIndex - 1]; CPP_INFO_FMT("value=%*s", len> 50? 50:len, row[columnIndex - 1]); was_null = false; return sql::SQLString(row[columnIndex - 1], len); } /* }}} */ /* {{{ MySQL_ResultSet::getString() -I- */ SQLString MySQL_ResultSet::getString(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::getString(string)"); return getString(findColumn(columnLabel)); } /* }}} */ /* {{{ MySQL_ResultSet::getType() -I- */ sql::ResultSet::enum_type MySQL_ResultSet::getType() const { CPP_ENTER("MySQL_ResultSet::getType"); checkValid(); return resultset_type; } /* }}} */ /* {{{ MySQL_ResultSet::getWarnings() -U- */ void MySQL_ResultSet::getWarnings() { CPP_ENTER("MySQL_ResultSet::getWarnings"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::getWarnings()"); } /* }}} */ /* {{{ MySQL_ResultSet::insertRow() -U- */ void MySQL_ResultSet::insertRow() { CPP_ENTER("MySQL_ResultSet::insertRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::insertRow()"); } /* }}} */ /* {{{ MySQL_ResultSet::isAfterLast() -I- */ bool MySQL_ResultSet::isAfterLast() const { CPP_ENTER("MySQL_ResultSet::isAfterLast"); checkValid(); checkScrollable(); return (row_position == num_rows + 1); } /* }}} */ /* {{{ MySQL_ResultSet::isBeforeFirst() -I- */ bool MySQL_ResultSet::isBeforeFirst() const { CPP_ENTER("MySQL_ResultSet::isBeforeFirst"); checkValid(); return (row_position == 0); } /* }}} */ /* {{{ MySQL_ResultSet::isClosed() -I- */ bool MySQL_ResultSet::isClosed() const { CPP_ENTER("MySQL_ResultSet::isClosed"); return !result; // return !result->isValid(); } /* }}} */ /* {{{ MySQL_ResultSet::isFirst() -I- */ bool MySQL_ResultSet::isFirst() const { CPP_ENTER("MySQL_ResultSet::isFirst"); checkValid(); return (row_position == 1); } /* }}} */ /* {{{ MySQL_ResultSet::isLast() -I- */ bool MySQL_ResultSet::isLast() const { CPP_ENTER("MySQL_ResultSet::isLast"); checkValid(); checkScrollable(); return (row_position == num_rows); } /* }}} */ /* {{{ MySQL_ResultSet::isNull() -I- */ bool MySQL_ResultSet::isNull(const uint32_t columnIndex) const { CPP_ENTER("MySQL_ResultSet::isNull(int)"); checkValid(); if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("MySQL_ResultSet::isNull: invalid value of 'columnIndex'"); } /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::getDouble: can't fetch because not on result set"); } return (row[columnIndex - 1] == NULL); } /* }}} */ /* {{{ MySQL_ResultSet::isNull() -I- */ bool MySQL_ResultSet::isNull(const sql::SQLString& columnLabel) const { CPP_ENTER("MySQL_ResultSet::isNull(string)"); int32_t col_idx = findColumn(columnLabel); if (col_idx == 0) { throw sql::InvalidArgumentException("MySQL_ResultSet::isNull: invalid value of 'columnLabel'"); } return isNull(col_idx); } /* }}} */ /* {{{ MySQL_ResultSet::last() -I- */ bool MySQL_ResultSet::last() { CPP_ENTER("MySQL_ResultSet::last"); checkValid(); checkScrollable(); if (num_rows) { row_position = num_rows; seek(); } return num_rows != 0; } /* }}} */ /* {{{ MySQL_ResultSet::moveToCurrentRow() -U- */ void MySQL_ResultSet::moveToCurrentRow() { CPP_ENTER("MySQL_ResultSet::moveToCurrentRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::moveToCurrentRow()"); checkScrollable(); } /* }}} */ /* {{{ MySQL_ResultSet::moveToInsertRow() -U- */ void MySQL_ResultSet::moveToInsertRow() { CPP_ENTER("MySQL_ResultSet::moveToInsertRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::moveToInsertRow()"); checkScrollable(); } /* }}} */ /* {{{ MySQL_ResultSet::next() -I- */ bool MySQL_ResultSet::next() { CPP_ENTER("MySQL_ResultSet::next"); checkValid(); bool ret = false; if (isScrollable()) { if (isLast()) { afterLast(); } else if (row_position < num_rows + 1) { row = result->fetch_row(); boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } if (row == NULL && (proxy_p->errNo() == 2013 || proxy_p->errNo() == 2000)) { CPP_ERR_FMT("Error fetching next row %d:(%s) %s", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); sql::SQLException e(proxy_p->error(), proxy_p->sqlstate(), proxy_p->errNo()); throw e; } ++row_position; ret = (row != NULL); } } else { // reset last_queried_column last_queried_column = -1; row = result->fetch_row(); boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } if (row == NULL && (proxy_p->errNo() == 2013 || proxy_p->errNo() == 2000)) { CPP_ERR_FMT("Error fetching next row %d:(%s) %s", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); sql::SQLException e(proxy_p->error(), proxy_p->sqlstate(), proxy_p->errNo()); throw e; } if ((ret = (row != NULL))) { ++row_position; } else { row_position = 0; } } CPP_INFO_FMT("new_position=%llu num_rows=%llu", row_position, num_rows); return ret; } /* }}} */ /* {{{ MySQL_ResultSet::previous() -I- */ bool MySQL_ResultSet::previous() { CPP_ENTER("MySQL_ResultSet::previous"); checkScrollable(); /* isBeforeFirst checks for validity */ if (isBeforeFirst()) { return false; } else if (isFirst()) { beforeFirst(); return false; } else if (row_position > 1) { --row_position; seek(); return true; } throw sql::SQLException("Impossible"); } /* }}} */ /* {{{ MySQL_ResultSet::refreshRow() -U- */ void MySQL_ResultSet::refreshRow() { CPP_ENTER("MySQL_ResultSet::refreshRow"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::refreshRow()"); } /* }}} */ /* {{{ MySQL_ResultSet::relative() -I- */ bool MySQL_ResultSet::relative(const int rows) { CPP_ENTER("MySQL_ResultSet::relative"); checkValid(); checkScrollable(); if (rows != 0) { if ((row_position + rows) > num_rows || (row_position + rows) < 1) { row_position = rows > 0? num_rows + 1 : 0; /* after last or before first */ } else { row_position += rows; seek(); } } return (row_position > 0 && row_position <= num_rows); } /* }}} */ /* {{{ MySQL_ResultSet::rowDeleted() -U- */ bool MySQL_ResultSet::rowDeleted() { CPP_ENTER("MySQL_ResultSet::rowDeleted"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::rowDeleted()"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::rowInserted() -U- */ bool MySQL_ResultSet::rowInserted() { CPP_ENTER("MySQL_ResultSet::rowInserted"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::rowInserted()"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::rowUpdated() -U- */ bool MySQL_ResultSet::rowUpdated() { CPP_ENTER("MySQL_ResultSet::rowUpdated"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::rowUpdated()"); return false; // fool compilers } /* }}} */ /* {{{ MySQL_ResultSet::rowsCount() -I- */ size_t MySQL_ResultSet::rowsCount() const { CPP_ENTER("MySQL_ResultSet::rowsCount"); checkValid(); checkScrollable(); return static_cast(result->num_rows()); } /* }}} */ /* {{{ MySQL_ResultSet::setFetchSize() -U- */ void MySQL_ResultSet::setFetchSize(size_t /* rows */) { CPP_ENTER("MySQL_ResultSet::setFetchSize"); checkValid(); throw sql::MethodNotImplementedException("MySQL_ResultSet::setFetchSize()"); } /* }}} */ /* {{{ MySQL_ResultSet::wasNull() -I- */ bool MySQL_ResultSet::wasNull() const { CPP_ENTER("MySQL_ResultSet::wasNull"); checkValid(); /* isBeforeFirst checks for validity */ if (isBeforeFirstOrAfterLast()) { throw sql::InvalidArgumentException("MySQL_ResultSet::wasNull: can't fetch because not on result set"); } if (last_queried_column == std::numeric_limits::max()) { throw sql::InvalidArgumentException("MySQL_ResultSet::wasNull: should be called only after one of the getter methods"); } return was_null; } /* }}} */ /* {{{ MySQL_ResultSet::isBeforeFirstOrAfterLast() -I- */ bool MySQL_ResultSet::isBeforeFirstOrAfterLast() const { CPP_ENTER("MySQL_ResultSet::isBeforeFirstOrAfterLast"); checkValid(); return (row_position == 0) || (isScrollable() && (row_position == num_rows + 1)); } /* }}} */ /* {{{ MySQL_ResultSet::seek() -I- */ void MySQL_ResultSet::seek() { CPP_ENTER("MySQL_ResultSet::seek"); checkScrollable(); result->data_seek(row_position - 1); row = result->fetch_row(); } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_resultset.h000644 015771 000012 00000012062 12645244436 022707 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_RESULTSET_H_ #define _MYSQL_RESULTSET_H_ #include #include #include #include #include "nativeapi/mysql_private_iface.h" namespace sql { namespace mysql { class MySQL_Statement; class MySQL_DebugLogger; class MySQL_ResultSetMetaData; namespace NativeAPI { class NativeResultsetWrapper; } class MySQL_ResultSet : public sql::ResultSet { MYSQL_ROW row; boost::shared_ptr< NativeAPI::NativeResultsetWrapper > result; boost::weak_ptr< NativeAPI::NativeConnectionWrapper > proxy; unsigned int num_fields; uint64_t num_rows; uint64_t row_position; /* 0 = before first row, 1 - first row, 'num_rows + 1' - after last row */ typedef std::map< sql::SQLString, unsigned int > FieldNameIndexMap; FieldNameIndexMap field_name_to_index_map; mutable bool was_null; // this is updated by calls to getInt(int), getString(int), etc... mutable uint32_t last_queried_column; const MySQL_Statement * parent; boost::shared_ptr< MySQL_DebugLogger > logger; boost::scoped_ptr< MySQL_ResultSetMetaData > rs_meta; sql::ResultSet::enum_type resultset_type; protected: void checkValid() const; void checkScrollable() const; bool isScrollable() const; bool isBeforeFirstOrAfterLast() const; void seek(); MYSQL_FIELD * getFieldMeta(unsigned int columnIndex) const; public: MySQL_ResultSet(boost::shared_ptr< NativeAPI::NativeResultsetWrapper > res, boost::weak_ptr< NativeAPI::NativeConnectionWrapper > _proxy, sql::ResultSet::enum_type rset_type, MySQL_Statement * par, boost::shared_ptr< MySQL_DebugLogger > & l); virtual ~MySQL_ResultSet(); bool absolute(int row); void afterLast(); void beforeFirst(); void cancelRowUpdates(); void clearWarnings(); void close(); uint32_t findColumn(const sql::SQLString& columnLabel) const; bool first(); std::istream * getBlob(uint32_t columnIndex) const; std::istream * getBlob(const sql::SQLString& columnLabel) const; bool getBoolean(uint32_t columnIndex) const; bool getBoolean(const sql::SQLString& columnLabel) const; int getConcurrency(); SQLString getCursorName(); long double getDouble(uint32_t columnIndex) const; long double getDouble(const sql::SQLString& columnLabel) const; int getFetchDirection(); size_t getFetchSize(); int getHoldability(); int32_t getInt(uint32_t columnIndex) const; int32_t getInt(const sql::SQLString& columnLabel) const; uint32_t getUInt(uint32_t columnIndex) const; uint32_t getUInt(const sql::SQLString& columnLabel) const; int64_t getInt64(uint32_t columnIndex) const; int64_t getInt64(const sql::SQLString& columnLabel) const; uint64_t getUInt64(uint32_t columnIndex) const; uint64_t getUInt64(const sql::SQLString& columnLabel) const; sql::ResultSetMetaData * getMetaData() const; size_t getRow() const; sql::RowID * getRowId(uint32_t columnIndex); sql::RowID * getRowId(const sql::SQLString & columnLabel); const sql::Statement * getStatement() const; SQLString getString(uint32_t columnIndex) const; SQLString getString(const sql::SQLString& columnLabel) const; sql::ResultSet::enum_type getType() const; void getWarnings(); void insertRow(); bool isAfterLast() const; bool isBeforeFirst()const; bool isClosed() const; bool isFirst() const; bool isLast() const; bool isNull(uint32_t columnIndex) const; bool isNull(const sql::SQLString& columnLabel) const; bool last(); void moveToCurrentRow(); void moveToInsertRow(); bool next(); bool previous(); void refreshRow(); bool relative(int rows); bool rowDeleted(); bool rowInserted(); bool rowUpdated(); size_t rowsCount() const; void setFetchSize(size_t rows); bool wasNull() const; private: /* Prevent use of these */ MySQL_ResultSet(const MySQL_ResultSet &); void operator=(MySQL_ResultSet &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_RESULTSET_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_resultset_metadata.cpp000644 015771 000012 00000027357 12645244436 025117 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include "mysql_util.h" #include "mysql_resultset.h" #include "mysql_resultset_metadata.h" #include "nativeapi/native_resultset_wrapper.h" #include "mysql_debug.h" namespace sql { namespace mysql { /* {{{ MySQL_ResultSetMetaData::MySQL_ResultSetMetaData -I- */ MySQL_ResultSetMetaData::MySQL_ResultSetMetaData(boost::shared_ptr< NativeAPI::NativeResultsetWrapper > res, boost::shared_ptr< MySQL_DebugLogger > & l) : result(res), logger(l) { CPP_ENTER("MySQL_ResultSetMetaData::MySQL_ResultSetMetaData"); boost::shared_ptr< NativeAPI::NativeResultsetWrapper > result_p = result.lock(); if (result_p) { num_fields = result_p->num_fields(); } } /* }}} */ /* {{{ MySQL_ResultSetMetaData::~MySQL_ResultSetMetaData -I- */ MySQL_ResultSetMetaData::~MySQL_ResultSetMetaData() { CPP_ENTER("MySQL_ResultSetMetaData::~MySQL_ResultSetMetaData"); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::checkColumnIndex -I- */ void MySQL_ResultSetMetaData::checkColumnIndex(unsigned int columnIndex) const { if (columnIndex == 0 || columnIndex > num_fields) { throw sql::InvalidArgumentException("Invalid value for columnIndex"); } } /* }}} */ /* {{{ MySQL_ResultSetMetaData::checkValid -I- */ void MySQL_ResultSetMetaData::checkValid() const { CPP_ENTER("MySQL_ResultSetMetaData::checkValid"); boost::shared_ptr< NativeAPI::NativeResultsetWrapper > result_p = result.lock(); if (!result_p) { throw sql::InvalidArgumentException("ResultSet is not valid anymore"); } } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getCatalogName -I- */ SQLString MySQL_ResultSetMetaData::getCatalogName(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getCatalogName"); checkValid(); checkColumnIndex(columnIndex); return ""; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnCount -I- */ unsigned int MySQL_ResultSetMetaData::getColumnCount() { CPP_ENTER("MySQL_ResultSetMetaData::getColumnCount"); checkValid(); return num_fields; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnDisplaySize -I- */ unsigned int MySQL_ResultSetMetaData::getColumnDisplaySize(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnDisplaySize"); checkValid(); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } int ret = field->length / cs->char_maxlen; CPP_INFO_FMT("column=%u name=%s display_size=%d", columnIndex, getFieldMeta(columnIndex)->name, ret); return ret; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnLabel -I- */ SQLString MySQL_ResultSetMetaData::getColumnLabel(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnLabel"); checkValid(); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->name; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnName -I- */ SQLString MySQL_ResultSetMetaData::getColumnName(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnName"); checkValid(); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->org_name; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnType -I- */ int MySQL_ResultSetMetaData::getColumnType(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnType"); checkValid(); checkColumnIndex(columnIndex); return sql::mysql::util::mysql_type_to_datatype(getFieldMeta(columnIndex)); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnTypeName -I- */ SQLString MySQL_ResultSetMetaData::getColumnTypeName(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnTypeName"); checkValid(); checkColumnIndex(columnIndex); return sql::mysql::util::mysql_type_to_string(getFieldMeta(columnIndex), this->logger); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnCharset -I- */ SQLString MySQL_ResultSetMetaData::getColumnCharset(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnCharset"); checkValid(); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg; msg << "Server sent unknown charsetnr (" << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return cs->name; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getColumnCollation -I- */ SQLString MySQL_ResultSetMetaData::getColumnCollation(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getColumnCollation"); checkValid(); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg; msg << "Server sent unknown charsetnr (" << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return cs->collation; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getFieldMeta -I- */ MYSQL_FIELD * MySQL_ResultSetMetaData::getFieldMeta(unsigned int columnIndex) const { boost::shared_ptr< NativeAPI::NativeResultsetWrapper > result_p = result.lock(); return result_p->fetch_field_direct(columnIndex - 1); } /* }}} */ // Precision - total number of digits /* {{{ MySQL_ResultSetMetaData::getPrecision -I- */ unsigned int MySQL_ResultSetMetaData::getPrecision(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getPrecision"); checkValid(); checkColumnIndex(columnIndex); unsigned int ret = getFieldMeta(columnIndex)->max_length - getScale(columnIndex); CPP_INFO_FMT("column=%u precision=%d", columnIndex, ret); return ret; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getScale -I- */ unsigned int MySQL_ResultSetMetaData::getScale(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getScale"); checkValid(); checkColumnIndex(columnIndex); unsigned int ret = getFieldMeta(columnIndex)->decimals; CPP_INFO_FMT("column=%u scale=%d", columnIndex, ret); return ret; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getSchemaName -I- */ SQLString MySQL_ResultSetMetaData::getSchemaName(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getSchemaName"); checkValid(); checkColumnIndex(columnIndex); const char * const db = getFieldMeta(columnIndex)->db; return db ? db : ""; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::getTableName -I- */ SQLString MySQL_ResultSetMetaData::getTableName(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::getTableName"); checkValid(); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->org_table; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isAutoIncrement -I- */ bool MySQL_ResultSetMetaData::isAutoIncrement(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isAutoIncrement"); checkValid(); checkColumnIndex(columnIndex); return (getFieldMeta(columnIndex)->flags & AUTO_INCREMENT_FLAG ) != 0; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isCaseSensitive -I- */ bool MySQL_ResultSetMetaData::isCaseSensitive(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isCaseSensitive"); checkValid(); checkColumnIndex(columnIndex); const MYSQL_FIELD * const field = getFieldMeta(columnIndex); if (field->flags & NUM_FLAG || field->type == MYSQL_TYPE_NEWDECIMAL || field->type == MYSQL_TYPE_DECIMAL) { return false; } const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg; msg << "Server sent unknown charsetnr (" << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return NULL == strstr(cs->collation, "_ci"); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isCurrency -I- */ bool MySQL_ResultSetMetaData::isCurrency(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isCurrency"); checkValid(); checkColumnIndex(columnIndex); return false; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isDefinitelyWritable -I- */ bool MySQL_ResultSetMetaData::isDefinitelyWritable(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isDefinitelyWritable"); checkValid(); checkColumnIndex(columnIndex); return isWritable(columnIndex); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isNullable -I- */ int MySQL_ResultSetMetaData::isNullable(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isNullable"); checkValid(); checkColumnIndex(columnIndex); return getFieldMeta(columnIndex)->flags & NOT_NULL_FLAG? columnNoNulls:columnNullable; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isNumeric -I- */ bool MySQL_ResultSetMetaData::isNumeric(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isNumeric"); checkValid(); checkColumnIndex(columnIndex); return (getFieldMeta(columnIndex)->flags & NUM_FLAG) != 0; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isReadOnly -I- */ bool MySQL_ResultSetMetaData::isReadOnly(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isReadOnly"); checkValid(); checkColumnIndex(columnIndex); const char * const db = getFieldMeta(columnIndex)->db; return !(db && strlen(db)); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isSearchable -I- */ bool MySQL_ResultSetMetaData::isSearchable(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isSearchable"); checkValid(); checkColumnIndex(columnIndex); return true; } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isSigned -I- */ bool MySQL_ResultSetMetaData::isSigned(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isSigned"); checkValid(); checkColumnIndex(columnIndex); if (getFieldMeta(columnIndex)->type == FIELD_TYPE_YEAR) { return false; } return !(getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isWritable -I- */ bool MySQL_ResultSetMetaData::isWritable(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isWritable"); checkValid(); checkColumnIndex(columnIndex); return !isReadOnly(columnIndex); } /* }}} */ /* {{{ MySQL_ResultSetMetaData::isZerofill -I- */ bool MySQL_ResultSetMetaData::isZerofill(unsigned int columnIndex) { CPP_ENTER("MySQL_ResultSetMetaData::isZerofill"); checkValid(); checkColumnIndex(columnIndex); return (getFieldMeta(columnIndex)->flags & ZEROFILL_FLAG) != 0; } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_resultset_metadata.h000644 015771 000012 00000006606 12645244436 024556 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_RESULTSET_METADATA_H_ #define _MYSQL_RESULTSET_METADATA_H_ #include #include struct st_mysql_field; namespace sql { namespace mysql { namespace NativeAPI { class NativeResultsetWrapper; } class MySQL_DebugLogger; class MySQL_ResultSetMetaData : public sql::ResultSetMetaData { boost::weak_ptr< NativeAPI::NativeResultsetWrapper > result; boost::shared_ptr< MySQL_DebugLogger > logger; unsigned int num_fields; public: MySQL_ResultSetMetaData(boost::shared_ptr< NativeAPI::NativeResultsetWrapper > res, boost::shared_ptr< MySQL_DebugLogger > & l); virtual ~MySQL_ResultSetMetaData(); SQLString getCatalogName(unsigned int columnIndex); unsigned int getColumnCount(); unsigned int getColumnDisplaySize(unsigned int columnIndex); SQLString getColumnLabel(unsigned int columnIndex); SQLString getColumnName(unsigned int columnIndex); int getColumnType(unsigned int columnIndex); SQLString getColumnTypeName(unsigned int columnIndex); SQLString getColumnCharset(unsigned int columnIndex); SQLString getColumnCollation(unsigned int columnIndex); unsigned int getPrecision(unsigned int columnIndex); unsigned int getScale(unsigned int columnIndex); SQLString getSchemaName(unsigned int columnIndex); SQLString getTableName(unsigned int columnIndex); bool isAutoIncrement(unsigned int columnIndex); bool isCaseSensitive(unsigned int columnIndex); bool isCurrency(unsigned int columnIndex); bool isDefinitelyWritable(unsigned int columnIndex); int isNullable(unsigned int columnIndex); bool isNumeric(unsigned int columnIndex); bool isReadOnly(unsigned int columnIndex); bool isSearchable(unsigned int columnIndex); bool isSigned(unsigned int columnIndex); bool isWritable(unsigned int columnIndex); bool isZerofill(unsigned int columnIndex); protected: void checkValid() const; void checkColumnIndex(unsigned int columnIndex) const; ::st_mysql_field * getFieldMeta(unsigned int columnIndex) const; private: /* Prevent use of these */ MySQL_ResultSetMetaData(const MySQL_ResultSetMetaData &); void operator=(MySQL_ResultSetMetaData &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_RESULTSET_METADATA_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_statement.cpp000644 015771 000012 00000035130 12645244436 023215 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include /* * mysql_util.h includes private_iface, ie libmysql headers. and they must go * prior to any header including config.h to avoid annoying redefenition warnings */ #include "mysql_util.h" #include #include #include #include "mysql_connection.h" #include "mysql_statement.h" #include "mysql_resultset.h" #include "mysql_warning.h" #include "nativeapi/native_connection_wrapper.h" #include "nativeapi/native_resultset_wrapper.h" #include "mysql_debug.h" namespace sql { namespace mysql { /* {{{ MySQL_Statement::MySQL_Statement() -I- */ MySQL_Statement::MySQL_Statement(MySQL_Connection * conn, boost::shared_ptr< NativeAPI::NativeConnectionWrapper > & _proxy, sql::ResultSet::enum_type rset_type, boost::shared_ptr< MySQL_DebugLogger > & l) : warnings(NULL), connection(conn), proxy(_proxy), isClosed(false), warningsHaveBeenLoaded(true), last_update_count(UL64(~0)), logger(l), resultset_type(rset_type), warningsCount(0) { CPP_ENTER("MySQL_Statement::MySQL_Statement"); CPP_INFO_FMT("this=%p", this); } /* }}} */ /* {{{ MySQL_Statement::~MySQL_Statement() -I- */ MySQL_Statement::~MySQL_Statement() { CPP_ENTER("MySQL_Statement::~MySQL_Statement"); CPP_INFO_FMT("this=%p", this); warnings.reset(); } /* }}} */ /* {{{ MySQL_Statement::do_query() -I- */ /* All callers passed c_str from string, and we here created new string to pass to proxy->query. It didn't make much sense so changed interface here */ void MySQL_Statement::do_query(const ::sql::SQLString &q) { CPP_ENTER("MySQL_Statement::do_query"); CPP_INFO_FMT("this=%p", this); checkClosed(); boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } if (proxy_p->query(q) && proxy_p->errNo()) { CPP_ERR_FMT("Error during proxy->query : %d:(%s) %s", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); sql::mysql::util::throwSQLException(*proxy_p.get()); } warningsCount= proxy_p->warning_count(); warningsHaveBeenLoaded= false; } /* }}} */ /* {{{ MySQL_Statement::get_resultset() -I- */ boost::shared_ptr< NativeAPI::NativeResultsetWrapper > MySQL_Statement::get_resultset() { CPP_ENTER("MySQL_Statement::get_resultset"); CPP_INFO_FMT("this=%p", this); checkClosed(); NativeAPI::NativeResultsetWrapper * result; boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } //TODO: again - probably no need to catch-n-throw here. Or maybe no need to throw further try { result= (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) ? proxy_p->use_result() : proxy_p->store_result(); if (!result) { sql::mysql::util::throwSQLException(*proxy_p.get()); } } catch (::sql::SQLException & e) { CPP_ERR_FMT("Error during %s_result : %d:(%s) %s", resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY? "use":"store", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); throw e; } return boost::shared_ptr< NativeAPI::NativeResultsetWrapper >(result); } /* }}} */ /* {{{ MySQL_Statement::cancel() -U- */ void MySQL_Statement::cancel() { CPP_ENTER("MySQL_Statement::cancel"); CPP_INFO_FMT("this=%p", this); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::cancel"); } /* }}} */ /* {{{ MySQL_Statement::execute() -I- */ bool MySQL_Statement::execute(const sql::SQLString& sql) { CPP_ENTER("MySQL_Statement::execute"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("query=%s", sql.c_str()); checkClosed(); do_query(sql); boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } bool ret = proxy_p->field_count() > 0; last_update_count = ret? UL64(~0):proxy_p->affected_rows(); return ret; } /* }}} */ /* {{{ MySQL_Statement::executeQuery() -I- */ sql::ResultSet * MySQL_Statement::executeQuery(const sql::SQLString& sql) { CPP_ENTER("MySQL_Statement::executeQuery"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("query=%s", sql.c_str()); checkClosed(); last_update_count = UL64(~0); do_query(sql); sql::ResultSet *tmp = new MySQL_ResultSet( get_resultset(), proxy, resultset_type==sql::ResultSet::TYPE_FORWARD_ONLY ? resultset_type : sql::ResultSet::TYPE_SCROLL_INSENSITIVE, this, logger ); CPP_INFO_FMT("rset=%p", tmp); return tmp; } /* }}} */ /*{{{ sql::mysql::dirty_drop_resultset -I- */ void dirty_drop_rs(boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy) { boost::scoped_ptr result(proxy->store_result()); // Destructor will do the job on result freeing } /* {{{ MySQL_Statement::executeUpdate() -I- */ int MySQL_Statement::executeUpdate(const sql::SQLString& sql) { CPP_ENTER("MySQL_Statement::executeUpdate"); CPP_INFO_FMT("this=%p", this); CPP_INFO_FMT("query=%s", sql.c_str()); checkClosed(); do_query(sql); bool got_rs= false; boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } do { if (proxy_p->field_count()) { /* We can't just throw - we need to walk through rest of results */ got_rs= true; dirty_drop_rs(proxy_p); } else { /* We return update count for last query */ last_update_count= proxy_p->affected_rows(); } if (!proxy_p->more_results()) { if (got_rs){ throw sql::InvalidArgumentException("Statement returning result set"); } else { return static_cast(last_update_count); } } switch (proxy_p->next_result()) { case 0: // There is next result and we go on next cycle iteration to process it break; case -1: throw sql::SQLException("Impossible! more_results() said true, next_result says no more results"); default/* > 0 */: CPP_ERR_FMT("Error during executeUpdate : %d:(%s) %s", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); sql::mysql::util::throwSQLException(*proxy_p.get()); } } while (1); /* Should not actually get here*/ return 0; } /* }}} */ /* {{{ MySQL_Statement::getConnection() -I- */ sql::Connection * MySQL_Statement::getConnection() { CPP_ENTER("MySQL_Statement::getConnection"); CPP_INFO_FMT("this=%p", this); checkClosed(); return connection; } /* }}} */ /* {{{ MySQL_Statement::getFetchSize() -U- */ size_t MySQL_Statement::getFetchSize() { CPP_ENTER("MySQL_Statement::getFetchSize"); CPP_INFO_FMT("this=%p", this); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::getFetchSize"); return 0; } /* }}} */ /* {{{ MySQL_Statement::getResultSet() -I- */ sql::ResultSet * MySQL_Statement::getResultSet() { CPP_ENTER("MySQL_Statement::getResultSet"); CPP_INFO_FMT("this=%p", this); checkClosed(); last_update_count = UL64(~0); boost::shared_ptr< NativeAPI::NativeResultsetWrapper > result; boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } sql::ResultSet::enum_type tmp_type; try { NativeAPI::NativeResultsetWrapper * tmp_ptr; switch (resultset_type) { case sql::ResultSet::TYPE_FORWARD_ONLY: if (!(tmp_ptr = proxy_p->use_result())) { sql::mysql::util::throwSQLException(*proxy_p.get()); } result.reset(tmp_ptr); tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY; break; default: if (!(tmp_ptr = proxy_p->store_result())) { sql::mysql::util::throwSQLException(*proxy_p.get()); } result.reset(tmp_ptr); tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE; } } catch (::sql::SQLException & e ) { if (proxy_p->errNo() != 0) { CPP_ERR_FMT("Error during %s_result : %d:(%s) %s", resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY? "use":"store", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); throw e; } else { return NULL; } } if (!result) { /* if there was an update then this method should return NULL and not throw */ return NULL; } sql::ResultSet * ret = new MySQL_ResultSet(result, proxy, tmp_type, this, logger); CPP_INFO_FMT("res=%p", ret); return ret; } /* }}} */ /* {{{ MySQL_Statement::setFetchSize() -U- */ void MySQL_Statement::setFetchSize(size_t /* fetch */) { CPP_ENTER("MySQL_Statement::setFetchSize"); CPP_INFO_FMT("this=%p", this); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::setFetchSize"); } /* }}} */ /* {{{ MySQL_Statement::setQueryTimeout() -U- */ void MySQL_Statement::setQueryTimeout(unsigned int timeout) { CPP_ENTER("MySQL_Statement::setQueryTimeout"); CPP_INFO_FMT("this=%p", this); checkClosed(); connection->setSessionVariable("max_statement_time", timeout); } /* }}} */ /* {{{ MySQL_Statement::clearWarnings() -I- */ void MySQL_Statement::clearWarnings() { CPP_ENTER("MySQL_Statement::clearWarnings"); CPP_INFO_FMT("this=%p", this); checkClosed(); warnings.reset(); } /* }}} */ /* {{{ MySQL_Statement::close() -i- */ void MySQL_Statement::close() { CPP_ENTER("MySQL_Statement::close"); CPP_INFO_FMT("this=%p", this); checkClosed(); clearWarnings(); isClosed = true; } /* }}} */ /* {{{ MySQL_Statement::getMaxFieldSize() -U- */ unsigned int MySQL_Statement::getMaxFieldSize() { CPP_ENTER("MySQL_Statement::getMaxFieldSize"); CPP_INFO_FMT("this=%p", this); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::getMaxFieldSize"); return 0; } /* }}} */ /* {{{ MySQL_Statement::getMaxRows() -U- */ uint64_t MySQL_Statement::getMaxRows() { CPP_ENTER("MySQL_Statement::getMaxRows"); CPP_INFO_FMT("this=%p", this); checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::getMaxRows"); return 0; } /* }}} */ /* {{{ MySQL_Statement::getMoreResults() -I- */ bool MySQL_Statement::getMoreResults() { CPP_ENTER("MySQL_Statement::getMoreResults"); CPP_INFO_FMT("this=%p", this); checkClosed(); last_update_count = UL64(~0); boost::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy_p = proxy.lock(); if (!proxy_p) { throw sql::InvalidInstanceException("Connection has been closed"); } if (proxy_p->more_results()) { int next_result = proxy_p->next_result(); if (next_result > 0) { CPP_ERR_FMT("Error during getMoreResults : %d:(%s) %s", proxy_p->errNo(), proxy_p->sqlstate().c_str(), proxy_p->error().c_str()); sql::mysql::util::throwSQLException(*proxy_p.get()); } else if (next_result == 0) { return proxy_p->field_count() != 0; } else if (next_result == -1) { throw sql::SQLException("Impossible! more_results() said true, next_result says no more results"); } } return false; } /* }}} */ /* {{{ MySQL_Statement::getQueryTimeout() -U- */ unsigned int MySQL_Statement::getQueryTimeout() { checkClosed(); sql::SQLString value= connection->getSessionVariable("max_statement_time"); if (value.length() > 0) { unsigned int timeout; std::istringstream buffer(value); buffer >> timeout; if (buffer.rdstate() & std::istringstream::failbit) { return 0; } else { return timeout; } } else { return 0; } } /* }}} */ /* {{{ MySQL_Statement::getResultSetType() -I- */ sql::ResultSet::enum_type MySQL_Statement::getResultSetType() { CPP_ENTER("MySQL_Statement::getResultSetType"); checkClosed(); return resultset_type; } /* }}} */ /* {{{ MySQL_Statement::getUpdateCount() -I- */ uint64_t MySQL_Statement::getUpdateCount() { CPP_ENTER("MySQL_Statement::getUpdateCount"); checkClosed(); if (last_update_count == UL64(~0)) { return UL64(~0); } uint64_t ret = last_update_count; last_update_count = UL64(~0); /* the value will be returned once per result set */ return ret; } /* }}} */ /* {{{ MySQL_Statement::getWarnings() -I- */ const SQLWarning * MySQL_Statement::getWarnings() { CPP_ENTER("MySQL_Statement::getWarnings"); CPP_INFO_FMT("this=%p", this); checkClosed(); if (!warningsHaveBeenLoaded) { warnings.reset(loadMysqlWarnings(connection, warningsCount)); warningsHaveBeenLoaded= true; } return warnings.get(); } /* }}} */ /* {{{ MySQL_Statement::setCursorName() -U- */ void MySQL_Statement::setCursorName(const sql::SQLString &) { checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::setCursorName"); } /* }}} */ /* {{{ MySQL_Statement::setEscapeProcessing() -U- */ void MySQL_Statement::setEscapeProcessing(bool) { checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::setEscapeProcessing"); } /* }}} */ /* {{{ MySQL_Statement::setMaxFieldSize() -U- */ void MySQL_Statement::setMaxFieldSize(unsigned int) { checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::setMaxFieldSize"); } /* }}} */ /* {{{ MySQL_Statement::setMaxRows() -U- */ void MySQL_Statement::setMaxRows(unsigned int) { checkClosed(); throw sql::MethodNotImplementedException("MySQL_Statement::setMaxRows"); } /* }}} */ /* {{{ MySQL_Statement::setResultSetType() -I- */ sql::Statement * MySQL_Statement::setResultSetType(sql::ResultSet::enum_type type) { checkClosed(); resultset_type = type; return this; } /* }}} */ /* {{{ MySQL_Statement::checkClosed() -I- */ void MySQL_Statement::checkClosed() { CPP_ENTER("MySQL_Statement::checkClosed"); if (isClosed) { CPP_ERR("Statement has been closed"); throw sql::InvalidInstanceException("Statement has been closed"); } } /* }}} */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_statement.h000644 015771 000012 00000006660 12645244436 022670 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_STATEMENT_H_ #define _MYSQL_STATEMENT_H_ #include #include #include #include #include "mysql_warning.h" #include "mysql_util.h" namespace sql { namespace mysql { class MySQL_Connection; class MySQL_DebugLogger; namespace NativeAPI { class NativeResultsetWrapper; class NativeConnectionWrapper; } class MySQL_Statement : public sql::Statement { protected: boost::scoped_ptr warnings; MySQL_Connection * connection; boost::weak_ptr< NativeAPI::NativeConnectionWrapper > proxy; void do_query(const ::sql::SQLString &q); bool isClosed; bool warningsHaveBeenLoaded; uint64_t last_update_count; boost::shared_ptr< MySQL_DebugLogger > logger; sql::ResultSet::enum_type resultset_type; unsigned int warningsCount; virtual boost::shared_ptr< NativeAPI::NativeResultsetWrapper > get_resultset(); virtual void checkClosed(); public: MySQL_Statement(MySQL_Connection * conn, boost::shared_ptr< NativeAPI::NativeConnectionWrapper > & _proxy, sql::ResultSet::enum_type rset_type, boost::shared_ptr< MySQL_DebugLogger > & l); ~MySQL_Statement(); sql::Connection * getConnection(); void cancel(); void clearWarnings(); void close(); bool execute(const sql::SQLString& sql); sql::ResultSet * executeQuery(const sql::SQLString& sql); int executeUpdate(const sql::SQLString& sql); size_t getFetchSize(); unsigned int getMaxFieldSize(); uint64_t getMaxRows(); bool getMoreResults(); unsigned int getQueryTimeout(); sql::ResultSet * getResultSet(); sql::ResultSet::enum_type getResultSetType(); uint64_t getUpdateCount(); const SQLWarning * getWarnings();/* should return differen type */ Statement * setBuffered(); void setCursorName(const sql::SQLString & name); void setEscapeProcessing(bool enable); void setFetchSize(size_t rows); void setMaxFieldSize(unsigned int max); void setMaxRows(unsigned int max); void setQueryTimeout(unsigned int seconds); sql::Statement * setResultSetType(sql::ResultSet::enum_type type); private: /* Prevent use of these */ MySQL_Statement(const MySQL_Statement &); void operator=(MySQL_Statement &); }; } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_STATEMENT_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_statement_options.h000644 015771 000012 00000003542 12645244436 024437 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_STATEMENT_OPTIONS_H_ #define _MYSQL_STATEMENT_OPTIONS_H_ namespace sql { namespace mysql { enum MySQL_Statement_Options { /* When doing mysql_stmt_store_result calculate max_length attribute of statement metadata. This is to be consistent with the old API, where this was done automatically. In the new API we do that only by request because it slows down mysql_stmt_store_result sufficiently. */ STMT_ATTR_UPDATE_MAX_LENGTH, /* unsigned long with combination of cursor flags (read only, for update, etc) */ STMT_ATTR_CURSOR_TYPE, /* Amount of rows to retrieve from server per one fetch if using cursors. Accepts unsigned long attribute in the range 1 - ulong_max */ STMT_ATTR_PREFETCH_ROWS }; } /* namespace mysql */ } /* namespace sql */ #endif mysql-connector-c++-1.1.7/driver/mysql_uri.cpp000644 015771 000012 00000012763 12645244436 022017 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "mysql_uri.h" #include "mysql_util.h" #include "exception.h" namespace sql { namespace mysql { static const char MYURI_SOCKET_PREFIX[]= "unix://"; static const char MYURI_PIPE_PREFIX[]= "pipe://"; static const char MYURI_TCP_PREFIX[]= "tcp://"; static const char MYURI_HOST_BEGIN= '['; static const char MYURI_HOST_END= ']'; static const int DEFAULT_TCP_PORT= 3306; /* {{{ MySQL_Uri::MySQL_Uri() -I- */ MySQL_Uri::MySQL_Uri() : protocol(NativeAPI::PROTOCOL_TCP), port (DEFAULT_TCP_PORT), /* Perhaps `localhost` has to be default. so w/out any parameter driver will still connect? */ host (""), schema ("") {} /* }}} */ /* {{{ MySQL_Uri::Host() -I- */ const sql::SQLString & MySQL_Uri::Host() { static const sql::SQLString hostValue4Pipe("."); static const sql::SQLString hostValue4sock(util::LOCALHOST); switch (Protocol()) { case NativeAPI::PROTOCOL_TCP: return host; case NativeAPI::PROTOCOL_PIPE: return hostValue4Pipe; case NativeAPI::PROTOCOL_SOCKET: return hostValue4sock; case NativeAPI::PROTOCOL_COUNT: throw sql::InvalidArgumentException("NativeAPI::PROTOCOL_COUNT shouldn't be used."); break; } // throw smoething maybe? return host; } /* }}} */ /* {{{ MySQL_Uri::SocketOrPipe() -I- */ const sql::SQLString & MySQL_Uri::SocketOrPipe() { if (tcpProtocol(*this)) { static const sql::SQLString emptystr(util::EMPTYSTR); return emptystr; } return host; } /* }}} */ /* {{{ MySQL_Uri::setHost() -I- */ void MySQL_Uri::setHost(const sql::SQLString &h) { setProtocol(NativeAPI::PROTOCOL_TCP); host= h.c_str(); } /* }}} */ /* {{{ MySQL_Uri::setSocket() -I- */ void MySQL_Uri::setSocket(const sql::SQLString &s) { setProtocol(NativeAPI::PROTOCOL_SOCKET); host= s.c_str(); } /* }}} */ /* {{{ MySQL_Uri::setPipe() -I- */ void MySQL_Uri::setPipe(const sql::SQLString &p) { setProtocol(NativeAPI::PROTOCOL_PIPE); host= p.c_str(); } /* }}} */ /* {{{ MySQL_Uri::setPort() -I- */ void MySQL_Uri::setPort(unsigned int p) { setProtocol(NativeAPI::PROTOCOL_TCP); port= p; } /* {{{ tcpProtocol() -I- */ bool tcpProtocol(MySQL_Uri& uri) { return uri.Protocol() == NativeAPI::PROTOCOL_TCP; } /* }}} */ /* {{{ Parse_Uri() -I- */ /* URI formats tcp://[host]:port/schema unix://socket pipe://named_pipe */ bool parseUri(const sql::SQLString & str, MySQL_Uri& uri) { if (!str.compare(0, sizeof(MYURI_SOCKET_PREFIX) - 1, MYURI_SOCKET_PREFIX)) { uri.setSocket(str.substr(sizeof(MYURI_SOCKET_PREFIX) - 1, sql::SQLString::npos)); return true; } if (!str.compare(0, sizeof(MYURI_PIPE_PREFIX) - 1 , MYURI_PIPE_PREFIX)) { uri.setPipe(str.substr(sizeof(MYURI_PIPE_PREFIX) - 1, sql::SQLString::npos)); return true; } sql::SQLString host; size_t start_sep, end_sep; /* i wonder how did it work with "- 1"*/ if (!str.compare(0, sizeof(MYURI_TCP_PREFIX) - 1, MYURI_TCP_PREFIX) ) { host= str.substr(sizeof(MYURI_TCP_PREFIX) - 1, sql::SQLString::npos); } else { /* allowing to have port and schema specified even w/out protocol specifier("tcp://") */ host= str.c_str(); } if (host[0] == MYURI_HOST_BEGIN) { end_sep= host.find(MYURI_HOST_END); /* No closing ] after [*/ if (end_sep == sql::SQLString::npos) { return false; } uri.setHost(host.substr(1, end_sep - 1)); /* Cutting host to continue w/ port and schema reading */ host= host.substr(end_sep + 1); } /* Looking where schema part begins */ start_sep = host.find('/'); if (start_sep != sql::SQLString::npos) { if ((host.length() - start_sep) > 1/*Slash*/) { uri.setSchema(host.substr(start_sep + 1, host.length() - start_sep - 1)); } host= host.substr(0, start_sep); } else { uri.setSchema(""); } /* Looking where port part begins*/ start_sep = host.find_last_of(':', sql::SQLString::npos); if (start_sep != sql::SQLString::npos) { uri.setPort(atoi(host.substr(start_sep + 1, sql::SQLString::npos).c_str())); host = host.substr(0, start_sep); } else { uri.setPort(DEFAULT_TCP_PORT); } /* If host was enclosed in [], it has been already set, and "host" variable is empty */ if (host.length() > 0) { uri.setHost(host); } return true; } } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_uri.h000644 015771 000012 00000004312 12645244436 021453 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_URI_H_ #define _MYSQL_URI_H_ #include "nativeapi/native_connection_wrapper.h" #include namespace sql { namespace mysql { class MySQL_Uri { private: NativeAPI::Protocol_Type protocol; unsigned int port; sql::SQLString host; sql::SQLString schema; public: MySQL_Uri(); const sql::SQLString & Host(); const sql::SQLString & SocketOrPipe(); inline int Port() {return port;} inline const sql::SQLString & Schema() {return schema;} inline NativeAPI::Protocol_Type Protocol() {return protocol;} void setHost (const sql::SQLString &h); void setSocket (const sql::SQLString &s); void setPipe (const sql::SQLString &p); void setPort (unsigned int p); inline void setSchema (const sql::SQLString &s) {schema= s.c_str();} inline void setProtocol(NativeAPI::Protocol_Type p){protocol= p;} }; bool tcpProtocol(MySQL_Uri& uri); bool parseUri(const sql::SQLString & str, MySQL_Uri& uri); } /* namespace mysql */ } /* namespace sql */ #endif /*_MYSQL_URI_H_*/ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_util.cpp000644 015771 000012 00000335716 12645244436 022203 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "mysql_util.h" #include "mysql_debug.h" #include "nativeapi/native_connection_wrapper.h" #include "nativeapi/native_statement_wrapper.h" namespace sql { namespace mysql { namespace util { /* just for cases when we need to return const empty string reference */ const char *EMPTYSTR= ""; const char *LOCALHOST= "localhost"; /* {{{ throwSQLException -I- */ void throwSQLException(::sql::mysql::NativeAPI::NativeConnectionWrapper & proxy) { throw sql::SQLException(proxy.error(), proxy.sqlstate(), proxy.errNo()); } /* }}} */ /* {{{ throwSQLException -I- */ void throwSQLException(::sql::mysql::NativeAPI::NativeStatementWrapper & proxy) { throw sql::SQLException(proxy.error(), proxy.sqlstate(), proxy.errNo()); } /* }}} */ #define cppconn_mbcharlen_big5 NULL #define check_mb_big5 NULL #define cppconn_mbcharlen_ujis NULL #define check_mb_ujis NULL #define cppconn_mbcharlen_sjis NULL #define check_mb_sjis NULL #define cppconn_mbcharlen_euckr NULL #define check_mb_euckr NULL #define cppconn_mbcharlen_gb2312 NULL #define check_mb_gb2312 NULL #define cppconn_mbcharlen_gbk NULL #define check_mb_gbk NULL #define cppconn_mbcharlen_utf8 NULL #define check_mb_utf8_valid NULL #define cppconn_mbcharlen_ucs2 NULL #define check_mb_ucs2 NULL #define cppconn_mbcharlen_cp932 NULL #define check_mb_cp932 NULL #define cppconn_mbcharlen_eucjpms NULL #define check_mb_eucjpms NULL #define cppconn_mbcharlen_utf8 NULL #define check_mb_utf8_valid NULL #define cppconn_mbcharlen_utf8mb4 cppconn_mbcharlen_utf8 #define check_mb_utf8mb4_valid check_mb_utf8_valid #define cppconn_mbcharlen_utf16 NULL #define check_mb_utf16_valid NULL #define cppconn_mbcharlen_utf32 NULL #define check_mb_utf32_valid NULL /* {{{ our_charsets60 */ const OUR_CHARSET our_charsets60[] = { { 1, "big5","big5_chinese_ci", 1, 2, "", cppconn_mbcharlen_big5, check_mb_big5}, { 3, "dec8", "dec8_swedisch_ci", 1, 1, "", NULL, NULL}, { 4, "cp850", "cp850_general_ci", 1, 1, "", NULL, NULL}, { 6, "hp8", "hp8_english_ci", 1, 1, "", NULL, NULL}, { 7, "koi8r", "koi8r_general_ci", 1, 1, "", NULL, NULL}, { 8, "latin1", "latin1_swedish_ci", 1, 1, "", NULL, NULL}, { 9, "latin2", "latin2_general_ci", 1, 1, "", NULL, NULL}, { 10, "swe7", "swe7_swedish_ci", 1, 1, "", NULL, NULL}, { 11, "ascii", "ascii_general_ci", 1, 1, "", NULL, NULL}, { 12, "ujis", "ujis_japanese_ci", 1, 3, "", cppconn_mbcharlen_ujis, check_mb_ujis}, { 13, "sjis", "sjis_japanese_ci", 1, 2, "", cppconn_mbcharlen_sjis, check_mb_sjis}, { 16, "hebrew", "hebrew_general_ci", 1, 1, "", NULL, NULL}, { 18, "tis620", "tis620_thai_ci", 1, 1, "", NULL, NULL}, { 19, "euckr", "euckr_korean_ci", 1, 2, "", cppconn_mbcharlen_euckr, check_mb_euckr}, { 22, "koi8u", "koi8u_general_ci", 1, 1, "", NULL, NULL}, { 24, "gb2312", "gb2312_chinese_ci", 1, 2, "", cppconn_mbcharlen_gb2312, check_mb_gb2312}, { 25, "greek", "greek_general_ci", 1, 1, "", NULL, NULL}, { 26, "cp1250", "cp1250_general_ci", 1, 1, "", NULL, NULL}, { 28, "gbk", "gbk_chinese_ci", 1, 2, "", cppconn_mbcharlen_gbk, check_mb_gbk}, { 30, "latin5", "latin5_turkish_ci", 1, 1, "", NULL, NULL}, { 32, "armscii8", "armscii8_general_ci", 1, 1, "", NULL, NULL}, { 33, "utf8", "utf8_general_ci", 1, 3, "UTF-8 Unicode", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 35, "ucs2", "ucs2_general_ci", 2, 2, "UCS-2 Unicode", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 36, "cp866", "cp866_general_ci", 1, 1, "", NULL, NULL}, { 37, "keybcs2", "keybcs2_general_ci", 1, 1, "", NULL, NULL}, { 38, "macce", "macce_general_ci", 1, 1, "", NULL, NULL}, { 39, "macroman", "macroman_general_ci", 1, 1, "", NULL, NULL}, { 40, "cp852", "cp852_general_ci", 1, 1, "", NULL, NULL}, { 41, "latin7", "latin7_general_ci", 1, 1, "", NULL, NULL}, { 51, "cp1251", "cp1251_general_ci", 1, 1, "", NULL, NULL}, { 57, "cp1256", "cp1256_general_ci", 1, 1, "", NULL, NULL}, { 59, "cp1257", "cp1257_general_ci", 1, 1, "", NULL, NULL}, { 63, "binary", "binary", 1, 1, "", NULL, NULL}, { 92, "geostd8", "geostd8_general_ci", 1, 1, "", NULL, NULL}, { 95, "cp932", "cp932_japanese_ci", 1, 2, "", cppconn_mbcharlen_cp932, check_mb_cp932}, { 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, "", cppconn_mbcharlen_eucjpms, check_mb_eucjpms}, { 2, "latin2", "latin2_czech_cs", 1, 1, "", NULL, NULL}, { 5, "latin1", "latin1_german_ci", 1, 1, "", NULL, NULL}, { 14, "cp1251", "cp1251_bulgarian_ci", 1, 1, "", NULL, NULL}, { 15, "latin1", "latin1_danish_ci", 1, 1, "", NULL, NULL}, { 17, "filename", "filename", 1, 5, "", NULL, NULL}, { 20, "latin7", "latin7_estonian_cs", 1, 1, "", NULL, NULL}, { 21, "latin2", "latin2_hungarian_ci", 1, 1, "", NULL, NULL}, { 23, "cp1251", "cp1251_ukrainian_ci", 1, 1, "", NULL, NULL}, { 27, "latin2", "latin2_croatian_ci", 1, 1, "", NULL, NULL}, { 29, "cp1257", "cp1257_lithunian_ci", 1, 1, "", NULL, NULL}, { 31, "latin1", "latin1_german2_ci", 1, 1, "", NULL, NULL}, { 34, "cp1250", "cp1250_czech_cs", 1, 1, "", NULL, NULL}, { 42, "latin7", "latin7_general_cs", 1, 1, "", NULL, NULL}, { 43, "macce", "macce_bin", 1, 1, "", NULL, NULL}, { 44, "cp1250", "cp1250_croatian_ci", 1, 1, "", NULL, NULL}, { 47, "latin1", "latin1_bin", 1, 1, "", NULL, NULL}, { 48, "latin1", "latin1_general_ci", 1, 1, "", NULL, NULL}, { 49, "latin1", "latin1_general_cs", 1, 1, "", NULL, NULL}, { 50, "cp1251", "cp1251_bin", 1, 1, "", NULL, NULL}, { 52, "cp1251", "cp1251_general_cs", 1, 1, "", NULL, NULL}, { 53, "macroman", "macroman_bin", 1, 1, "", NULL, NULL}, { 58, "cp1257", "cp1257_bin", 1, 1, "", NULL, NULL}, { 60, "armascii8", "armascii8_bin", 1, 1, "", NULL, NULL}, { 65, "ascii", "ascii_bin", 1, 1, "", NULL, NULL}, { 66, "cp1250", "cp1250_bin", 1, 1, "", NULL, NULL}, { 67, "cp1256", "cp1256_bin", 1, 1, "", NULL, NULL}, { 68, "cp866", "cp866_bin", 1, 1, "", NULL, NULL}, { 69, "dec8", "dec8_bin", 1, 1, "", NULL, NULL}, { 70, "greek", "greek_bin", 1, 1, "", NULL, NULL}, { 71, "hebrew", "hebrew_bin", 1, 1, "", NULL, NULL}, { 72, "hp8", "hp8_bin", 1, 1, "", NULL, NULL}, { 73, "keybcs2", "keybcs2_bin", 1, 1, "", NULL, NULL}, { 74, "koi8r", "koi8r_bin", 1, 1, "", NULL, NULL}, { 75, "koi8u", "koi8u_bin", 1, 1, "", NULL, NULL}, { 77, "latin2", "latin2_bin", 1, 1, "", NULL, NULL}, { 78, "latin5", "latin5_bin", 1, 1, "", NULL, NULL}, { 79, "latin7", "latin7_bin", 1, 1, "", NULL, NULL}, { 80, "cp850", "cp850_bin", 1, 1, "", NULL, NULL}, { 81, "cp852", "cp852_bin", 1, 1, "", NULL, NULL}, { 82, "swe7", "swe7_bin", 1, 1, "", NULL, NULL}, { 93, "geostd8", "geostd8_bin", 1, 1, "", NULL, NULL}, { 83, "utf8", "utf8_bin", 1, 3, "UTF-8 Unicode", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 84, "big5", "big5_bin", 1, 2, "", cppconn_mbcharlen_big5, check_mb_big5}, { 85, "euckr", "euckr_bin", 1, 2, "", cppconn_mbcharlen_euckr, check_mb_euckr}, { 86, "gb2312", "gb2312_bin", 1, 2, "", cppconn_mbcharlen_gb2312, check_mb_gb2312}, { 87, "gbk", "gbk_bin", 1, 2, "", cppconn_mbcharlen_gbk, check_mb_gbk}, { 88, "sjis", "sjis_bin", 1, 2, "", cppconn_mbcharlen_sjis, check_mb_sjis}, { 89, "tis620", "tis620_bin", 1, 1, "", NULL, NULL}, { 90, "ucs2", "ucs2_bin", 2, 2, "UCS-2 Unicode", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 91, "ujis", "ujis_bin", 1, 3, "", cppconn_mbcharlen_ujis, check_mb_ujis}, { 94, "latin1", "latin1_spanish_ci", 1, 1, "", NULL, NULL}, { 96, "cp932", "cp932_bin", 1, 2, "", cppconn_mbcharlen_cp932, check_mb_cp932}, { 99, "cp1250", "cp1250_polish_ci", 1, 1, "", NULL, NULL}, { 98, "eucjpms", "eucjpms_bin", 1, 3, "", cppconn_mbcharlen_eucjpms, check_mb_eucjpms}, { 128, "ucs2", "ucs2_unicode_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 129, "ucs2", "ucs2_icelandic_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 130, "ucs2", "ucs2_latvian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 131, "ucs2", "ucs2_romanian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 132, "ucs2", "ucs2_slovenian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 133, "ucs2", "ucs2_polish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 134, "ucs2", "ucs2_estonian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 135, "ucs2", "ucs2_spanish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 136, "ucs2", "ucs2_swedish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 137, "ucs2", "ucs2_turkish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 138, "ucs2", "ucs2_czech_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 139, "ucs2", "ucs2_danish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 140, "ucs2", "ucs2_lithunian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 141, "ucs2", "ucs2_slovak_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 142, "ucs2", "ucs2_spanish2_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 143, "ucs2", "ucs2_roman_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 144, "ucs2", "ucs2_persian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 145, "ucs2", "ucs2_esperanto_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 146, "ucs2", "ucs2_hungarian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 147, "ucs2", "ucs2_sinhala_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 148, "ucs2", "ucs2_german2_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 149, "ucs2", "ucs2_croatian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 150, "ucs2", "ucs2_unicode_520_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2}, { 192, "utf8", "utf8_unicode_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 193, "utf8", "utf8_icelandic_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 194, "utf8", "utf8_latvian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 195, "utf8", "utf8_romanian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 196, "utf8", "utf8_slovenian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 197, "utf8", "utf8_polish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 198, "utf8", "utf8_estonian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 199, "utf8", "utf8_spanish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 200, "utf8", "utf8_swedish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 201, "utf8", "utf8_turkish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 202, "utf8", "utf8_czech_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 203, "utf8", "utf8_danish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid }, { 204, "utf8", "utf8_lithunian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid }, { 205, "utf8", "utf8_slovak_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 206, "utf8", "utf8_spanish2_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 207, "utf8", "utf8_roman_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 208, "utf8", "utf8_persian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 209, "utf8", "utf8_esperanto_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 210, "utf8", "utf8_hungarian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 211, "utf8", "utf8_sinhala_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 212, "utf8", "utf8_german2_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 213, "utf8", "utf8_croatian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 214, "utf8", "utf8_unicode_520_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 215, "utf8", "utf8_vietnamese_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 223, "utf8", "utf8_general_mysql500_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 45, "utf8mb4", "utf8mb4_general_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 46, "utf8mb4", "utf8mb4_bin", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 224, "utf8mb4", "utf8mb4_unicode_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 225, "utf8mb4", "utf8mb4_icelandic_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 226, "utf8mb4", "utf8mb4_latvian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 227, "utf8mb4", "utf8mb4_romanian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 228, "utf8mb4", "utf8mb4_slovenian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 229, "utf8mb4", "utf8mb4_polish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 230, "utf8mb4", "utf8mb4_estonian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 231, "utf8mb4", "utf8mb4_spanish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 232, "utf8mb4", "utf8mb4_swedish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 233, "utf8mb4", "utf8mb4_turkish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 234, "utf8mb4", "utf8mb4_czech_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 235, "utf8mb4", "utf8mb4_danish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 236, "utf8mb4", "utf8mb4_lithuanian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 237, "utf8mb4", "utf8mb4_slovak_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 238, "utf8mb4", "utf8mb4_spanish2_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 239, "utf8mb4", "utf8mb4_roman_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 240, "utf8mb4", "utf8mb4_persian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 241, "utf8mb4", "utf8mb4_esperanto_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 242, "utf8mb4", "utf8mb4_hungarian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 243, "utf8mb4", "utf8mb4_sinhala_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 244, "utf8mb4", "utf8mb4_german2_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 245, "utf8mb4", "utf8mb4_croatian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 246, "utf8mb4", "utf8mb4_unicode_520_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, { 247, "utf8mb4", "utf8mb4_vietnamese_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid}, /*Should not really happen, but adding them */ { 254, "utf8", "utf8_general_cs", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid}, { 101, "utf16", "utf16_unicode_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 102, "utf16", "utf16_icelandic_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 103, "utf16", "utf16_latvian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 104, "utf16", "utf16_romanian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 105, "utf16", "utf16_slovenian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 106, "utf16", "utf16_polish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 107, "utf16", "utf16_estonian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 108, "utf16", "utf16_spanish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 109, "utf16", "utf16_swedish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 110, "utf16", "utf16_turkish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 111, "utf16", "utf16_czech_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 112, "utf16", "utf16_danish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 113, "utf16", "utf16_lithuanian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 114, "utf16", "utf16_slovak_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 115, "utf16", "utf16_spanish2_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 116, "utf16", "utf16_roman_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 117, "utf16", "utf16_persian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 118, "utf16", "utf16_esperanto_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 119, "utf16", "utf16_hungarian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 120, "utf16", "utf16_sinhala_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 121, "utf16", "utf16_german2_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 122, "utf16", "utf16_croatian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 123, "utf16", "utf16_unicode_520_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 124, "utf16", "utf16_vietnamese_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid}, { 160, "utf32", "utf32_unicode_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 161, "utf32", "utf32_icelandic_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 162, "utf32", "utf32_latvian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 163, "utf32", "utf32_romanian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 164, "utf32", "utf32_slovenian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 165, "utf32", "utf32_polish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 166, "utf32", "utf32_estonian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 167, "utf32", "utf32_spanish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 168, "utf32", "utf32_swedish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 169, "utf32", "utf32_turkish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 170, "utf32", "utf32_czech_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 171, "utf32", "utf32_danish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 172, "utf32", "utf32_lithuanian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 173, "utf32", "utf32_slovak_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 174, "utf32", "utf32_spanish2_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 175, "utf32", "utf32_roman_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 176, "utf32", "utf32_persian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 177, "utf32", "utf32_esperanto_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 178, "utf32", "utf32_hungarian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 179, "utf32", "utf32_sinhala_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 180, "utf32", "utf32_german2_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 181, "utf32", "utf32_croatian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 182, "utf32", "utf32_unicode_520_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 183, "utf32", "utf32_vietnamese_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid}, { 0, NULL, NULL, 0, 0, NULL, NULL, NULL} }; /* }}} */ /* {{{ find_charset */ const OUR_CHARSET * find_charset(unsigned int charsetnr) { const OUR_CHARSET * c = our_charsets60; do { if (c->nr == charsetnr) { return c; } ++c; } while (c[0].nr != 0); return NULL; } /* }}} */ #define MAGIC_BINARY_CHARSET_NR 63 /* {{{ mysql_to_datatype() -I- */ int mysql_type_to_datatype(const MYSQL_FIELD * const field) { switch (field->type) { case MYSQL_TYPE_BIT: if (field->flags !=(BINARY_FLAG|UNSIGNED_FLAG)) return sql::DataType::BIT; return sql::DataType::BINARY; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: return sql::DataType::DECIMAL; case MYSQL_TYPE_TINY: return sql::DataType::TINYINT; case MYSQL_TYPE_SHORT: return sql::DataType::SMALLINT; case MYSQL_TYPE_INT24: return sql::DataType::MEDIUMINT; case MYSQL_TYPE_LONG: return sql::DataType::INTEGER; case MYSQL_TYPE_LONGLONG: return sql::DataType::BIGINT; case MYSQL_TYPE_FLOAT: return sql::DataType::REAL; case MYSQL_TYPE_DOUBLE: return sql::DataType::DOUBLE; case MYSQL_TYPE_NULL: return sql::DataType::SQLNULL; case MYSQL_TYPE_TIMESTAMP: return sql::DataType::TIMESTAMP; case MYSQL_TYPE_DATE: return sql::DataType::DATE; case MYSQL_TYPE_TIME: return sql::DataType::TIME; case MYSQL_TYPE_YEAR: return sql::DataType::YEAR; case MYSQL_TYPE_DATETIME: return sql::DataType::TIMESTAMP; case MYSQL_TYPE_TINY_BLOB:// should no appear over the wire { bool isBinary = (field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR; const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return isBinary ? sql::DataType::VARBINARY : sql::DataType::VARCHAR; } case MYSQL_TYPE_MEDIUM_BLOB:// should no appear over the wire case MYSQL_TYPE_LONG_BLOB:// should no appear over the wire case MYSQL_TYPE_BLOB: { bool isBinary = (field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR; const sql::mysql::util::OUR_CHARSET * const cs = sql::mysql::util::find_charset(field->charsetnr); if (!cs) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } return isBinary ? sql::DataType::LONGVARBINARY : sql::DataType::LONGVARCHAR; } case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: if (field->flags & SET_FLAG) { return sql::DataType::SET; } if (field->flags & ENUM_FLAG) { return sql::DataType::ENUM; } if ((field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR) { return sql::DataType::VARBINARY; } return sql::DataType::VARCHAR; case MYSQL_TYPE_STRING: if (field->flags & SET_FLAG) { return sql::DataType::SET; } if (field->flags & ENUM_FLAG) { return sql::DataType::ENUM; } if ((field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR) { return sql::DataType::BINARY; } return sql::DataType::CHAR; case MYSQL_TYPE_ENUM: /* This hould never happen - MYSQL_TYPE_ENUM is not sent over the wire, just used in the server */ return sql::DataType::ENUM; case MYSQL_TYPE_SET: /* This hould never happen - MYSQL_TYPE_SET is not sent over the wire, just used in the server */ return sql::DataType::SET; case MYSQL_TYPE_GEOMETRY: return sql::DataType::GEOMETRY; case MYSQL_TYPE_JSON: return sql::DataType::JSON; default: return sql::DataType::UNKNOWN; } } /* }}} */ /* {{{ mysql_to_datatype() -I- */ int mysql_string_type_to_datatype(const sql::SQLString & name) { /* I_S.COLUMNS is buggy, because it deflivers (float|double) unsigned but not (tinyint|smallint|mediumint|int|bigint) unsigned */ if (!name.compare("bit")) { return sql::DataType::BIT; } else if (!name.compare("decimal") || !name.compare("decimal unsigned")) { return sql::DataType::DECIMAL; } else if (!name.compare("tinyint") || !name.compare("tinyint unsigned")) { return sql::DataType::TINYINT; } else if (!name.compare("smallint") || !name.compare("smallint unsigned")) { return sql::DataType::SMALLINT; } else if (!name.compare("mediumint") || !name.compare("mediumint unsigned")) { return sql::DataType::MEDIUMINT; } else if (!name.compare("int") || !name.compare("int unsigned")) { return sql::DataType::INTEGER; } else if (!name.compare("bigint") || !name.compare("bigint unsigned")) { return sql::DataType::BIGINT; } else if (!name.compare("float") || !name.compare("float unsigned")) { return sql::DataType::REAL; } else if (!name.compare("double") || !name.compare("double unsigned")) { return sql::DataType::DOUBLE; } else if (!name.compare("timestamp")) { return sql::DataType::TIMESTAMP; } else if (!name.compare("date")) { return sql::DataType::DATE; } else if (!name.compare("time")) { return sql::DataType::TIME; } else if (!name.compare("year")) { return sql::DataType::YEAR; } else if (!name.compare("datetime")) { return sql::DataType::TIMESTAMP; } else if (!name.compare("tinytext")) { return sql::DataType::VARCHAR; } else if (!name.compare("mediumtext") || !name.compare("text") || !name.compare("longtext")) { return sql::DataType::LONGVARCHAR; } else if (!name.compare("tinyblob")) { return sql::DataType::VARBINARY; } else if (!name.compare("mediumblob") || !name.compare("blob") || !name.compare("longblob")) { return sql::DataType::LONGVARBINARY; } else if (!name.compare("char")) { return sql::DataType::CHAR; } else if (!name.compare("binary")) { return sql::DataType::BINARY; } else if (!name.compare("varchar")) { return sql::DataType::VARCHAR; } else if (!name.compare("varbinary")) { return sql::DataType::VARBINARY; } else if (!name.compare("enum")) { return sql::DataType::ENUM; } else if (!name.compare("set")) { return sql::DataType::SET; } else if (!name.compare("geometry")) { return sql::DataType::GEOMETRY; } else if (!name.compare("json")) { return sql::DataType::JSON; } else { return sql::DataType::UNKNOWN; } } /* }}} */ /* {{{ mysql_to_datatype() -I- */ const char * mysql_type_to_string(const MYSQL_FIELD * const field, boost::shared_ptr< sql::mysql::MySQL_DebugLogger > & l) { CPP_ENTER_WL(l, "mysql_type_to_string"); bool isUnsigned = (field->flags & UNSIGNED_FLAG) != 0; bool isZerofill = (field->flags & ZEROFILL_FLAG) != 0; switch (field->type) { case MYSQL_TYPE_BIT: return "BIT"; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: return isUnsigned ? (isZerofill? "DECIMAL UNSIGNED ZEROFILL" : "DECIMAL UNSIGNED"): "DECIMAL"; case MYSQL_TYPE_TINY: return isUnsigned ? (isZerofill? "TINYINT UNSIGNED ZEROFILL" : "TINYINT UNSIGNED"): "TINYINT"; case MYSQL_TYPE_SHORT: return isUnsigned ? (isZerofill? "SMALLINT UNSIGNED ZEROFILL" : "SMALLINT UNSIGNED"): "SMALLINT"; case MYSQL_TYPE_LONG: return isUnsigned ? (isZerofill? "INT UNSIGNED ZEROFILL" : "INT UNSIGNED"): "INT"; case MYSQL_TYPE_FLOAT: return isUnsigned ? (isZerofill? "FLOAT UNSIGNED ZEROFILL" : "FLOAT UNSIGNED"): "FLOAT"; case MYSQL_TYPE_DOUBLE: return isUnsigned ? (isZerofill? "DOUBLE UNSIGNED ZEROFILL" : "DOUBLE UNSIGNED"): "DOUBLE"; case MYSQL_TYPE_NULL: return "NULL"; case MYSQL_TYPE_TIMESTAMP: return "TIMESTAMP"; case MYSQL_TYPE_LONGLONG: return isUnsigned ? (isZerofill? "BIGINT UNSIGNED ZEROFILL" : "BIGINT UNSIGNED") : "BIGINT"; case MYSQL_TYPE_INT24: return isUnsigned ? (isZerofill? "MEDIUMINT UNSIGNED ZEROFILL" : "MEDIUMINT UNSIGNED") : "MEDIUMINT"; case MYSQL_TYPE_DATE: return "DATE"; case MYSQL_TYPE_TIME: return "TIME"; case MYSQL_TYPE_DATETIME: return "DATETIME"; case MYSQL_TYPE_TINY_BLOB:// should no appear over the wire { bool isBinary = field->charsetnr == MAGIC_BINARY_CHARSET_NR; unsigned int char_maxlen = 1; if (!isBinary) { const sql::mysql::util::OUR_CHARSET * cset = find_charset(field->charsetnr); if (!cset) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } char_maxlen = cset->char_maxlen; } CPP_INFO_FMT("char_maxlen=%u field->length=%lu", char_maxlen, field->length); return isBinary? "TINYBLOB":"TINYTEXT"; } case MYSQL_TYPE_MEDIUM_BLOB:// should no appear over the wire { bool isBinary = field->charsetnr == MAGIC_BINARY_CHARSET_NR; unsigned int char_maxlen = 1; if (!isBinary) { const sql::mysql::util::OUR_CHARSET * cset = find_charset(field->charsetnr); if (!cset) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } char_maxlen = cset->char_maxlen; } CPP_INFO_FMT("char_maxlen=%u field->length=%lu", char_maxlen, field->length); return isBinary? "MEDIUMBLOB":"MEDIUMTEXT"; } case MYSQL_TYPE_LONG_BLOB:// should no appear over the wire { bool isBinary = field->charsetnr == MAGIC_BINARY_CHARSET_NR; unsigned int char_maxlen = 1; if (!isBinary) { const sql::mysql::util::OUR_CHARSET * cset = find_charset(field->charsetnr); if (!cset) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } char_maxlen = cset->char_maxlen; } CPP_INFO_FMT("char_maxlen=%u field->length=%lu", char_maxlen, field->length); return isBinary? "LONGBLOB":"LONGTEXT"; } case MYSQL_TYPE_BLOB: { bool isBinary= field->charsetnr == MAGIC_BINARY_CHARSET_NR; unsigned int char_maxlen = 1; if (!isBinary) { const sql::mysql::util::OUR_CHARSET * cset = find_charset(field->charsetnr); if (!cset) { std::ostringstream msg("Server sent unknown charsetnr ("); msg << field->charsetnr << ") . Please report"; throw SQLException(msg.str()); } char_maxlen = cset->char_maxlen; } CPP_INFO_FMT("char_maxlen=%u field->length=%lu", char_maxlen, field->length); return isBinary? "BLOB":"TEXT"; } case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: if (field->flags & ENUM_FLAG) { return "ENUM"; } if (field->flags & SET_FLAG) { return "SET"; } if (field->charsetnr == MAGIC_BINARY_CHARSET_NR) { return "VARBINARY"; } return "VARCHAR"; case MYSQL_TYPE_STRING: if (field->flags & ENUM_FLAG) { return "ENUM"; } if (field->flags & SET_FLAG) { return "SET"; } if ((field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR) { return "BINARY"; } return "CHAR"; case MYSQL_TYPE_ENUM: /* This should never happen */ return "ENUM"; case MYSQL_TYPE_YEAR: return "YEAR"; case MYSQL_TYPE_SET: /* This should never happen */ return "SET"; case MYSQL_TYPE_GEOMETRY: return "GEOMETRY"; case MYSQL_TYPE_JSON: return "JSON"; default: return "UNKNOWN"; } } /* }}} */ /* The following code is from libmysql and is under the following license */ /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* UTF8 according RFC 2279 */ /* Written by Alexander Barkov */ typedef struct unicase_info_st { uint16_t toupper; uint16_t tolower; uint16_t sort; } MY_UNICASE_INFO; static MY_UNICASE_INFO plane00[]={ {0x0000,0x0000,0x0000}, {0x0001,0x0001,0x0001}, {0x0002,0x0002,0x0002}, {0x0003,0x0003,0x0003}, {0x0004,0x0004,0x0004}, {0x0005,0x0005,0x0005}, {0x0006,0x0006,0x0006}, {0x0007,0x0007,0x0007}, {0x0008,0x0008,0x0008}, {0x0009,0x0009,0x0009}, {0x000A,0x000A,0x000A}, {0x000B,0x000B,0x000B}, {0x000C,0x000C,0x000C}, {0x000D,0x000D,0x000D}, {0x000E,0x000E,0x000E}, {0x000F,0x000F,0x000F}, {0x0010,0x0010,0x0010}, {0x0011,0x0011,0x0011}, {0x0012,0x0012,0x0012}, {0x0013,0x0013,0x0013}, {0x0014,0x0014,0x0014}, {0x0015,0x0015,0x0015}, {0x0016,0x0016,0x0016}, {0x0017,0x0017,0x0017}, {0x0018,0x0018,0x0018}, {0x0019,0x0019,0x0019}, {0x001A,0x001A,0x001A}, {0x001B,0x001B,0x001B}, {0x001C,0x001C,0x001C}, {0x001D,0x001D,0x001D}, {0x001E,0x001E,0x001E}, {0x001F,0x001F,0x001F}, {0x0020,0x0020,0x0020}, {0x0021,0x0021,0x0021}, {0x0022,0x0022,0x0022}, {0x0023,0x0023,0x0023}, {0x0024,0x0024,0x0024}, {0x0025,0x0025,0x0025}, {0x0026,0x0026,0x0026}, {0x0027,0x0027,0x0027}, {0x0028,0x0028,0x0028}, {0x0029,0x0029,0x0029}, {0x002A,0x002A,0x002A}, {0x002B,0x002B,0x002B}, {0x002C,0x002C,0x002C}, {0x002D,0x002D,0x002D}, {0x002E,0x002E,0x002E}, {0x002F,0x002F,0x002F}, {0x0030,0x0030,0x0030}, {0x0031,0x0031,0x0031}, {0x0032,0x0032,0x0032}, {0x0033,0x0033,0x0033}, {0x0034,0x0034,0x0034}, {0x0035,0x0035,0x0035}, {0x0036,0x0036,0x0036}, {0x0037,0x0037,0x0037}, {0x0038,0x0038,0x0038}, {0x0039,0x0039,0x0039}, {0x003A,0x003A,0x003A}, {0x003B,0x003B,0x003B}, {0x003C,0x003C,0x003C}, {0x003D,0x003D,0x003D}, {0x003E,0x003E,0x003E}, {0x003F,0x003F,0x003F}, {0x0040,0x0040,0x0040}, {0x0041,0x0061,0x0041}, {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049}, {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, {0x005A,0x007A,0x005A}, {0x005B,0x005B,0x005B}, {0x005C,0x005C,0x005C}, {0x005D,0x005D,0x005D}, {0x005E,0x005E,0x005E}, {0x005F,0x005F,0x005F}, {0x0060,0x0060,0x0060}, {0x0041,0x0061,0x0041}, {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049}, {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, {0x005A,0x007A,0x005A}, {0x007B,0x007B,0x007B}, {0x007C,0x007C,0x007C}, {0x007D,0x007D,0x007D}, {0x007E,0x007E,0x007E}, {0x007F,0x007F,0x007F}, {0x0080,0x0080,0x0080}, {0x0081,0x0081,0x0081}, {0x0082,0x0082,0x0082}, {0x0083,0x0083,0x0083}, {0x0084,0x0084,0x0084}, {0x0085,0x0085,0x0085}, {0x0086,0x0086,0x0086}, {0x0087,0x0087,0x0087}, {0x0088,0x0088,0x0088}, {0x0089,0x0089,0x0089}, {0x008A,0x008A,0x008A}, {0x008B,0x008B,0x008B}, {0x008C,0x008C,0x008C}, {0x008D,0x008D,0x008D}, {0x008E,0x008E,0x008E}, {0x008F,0x008F,0x008F}, {0x0090,0x0090,0x0090}, {0x0091,0x0091,0x0091}, {0x0092,0x0092,0x0092}, {0x0093,0x0093,0x0093}, {0x0094,0x0094,0x0094}, {0x0095,0x0095,0x0095}, {0x0096,0x0096,0x0096}, {0x0097,0x0097,0x0097}, {0x0098,0x0098,0x0098}, {0x0099,0x0099,0x0099}, {0x009A,0x009A,0x009A}, {0x009B,0x009B,0x009B}, {0x009C,0x009C,0x009C}, {0x009D,0x009D,0x009D}, {0x009E,0x009E,0x009E}, {0x009F,0x009F,0x009F}, {0x00A0,0x00A0,0x00A0}, {0x00A1,0x00A1,0x00A1}, {0x00A2,0x00A2,0x00A2}, {0x00A3,0x00A3,0x00A3}, {0x00A4,0x00A4,0x00A4}, {0x00A5,0x00A5,0x00A5}, {0x00A6,0x00A6,0x00A6}, {0x00A7,0x00A7,0x00A7}, {0x00A8,0x00A8,0x00A8}, {0x00A9,0x00A9,0x00A9}, {0x00AA,0x00AA,0x00AA}, {0x00AB,0x00AB,0x00AB}, {0x00AC,0x00AC,0x00AC}, {0x00AD,0x00AD,0x00AD}, {0x00AE,0x00AE,0x00AE}, {0x00AF,0x00AF,0x00AF}, {0x00B0,0x00B0,0x00B0}, {0x00B1,0x00B1,0x00B1}, {0x00B2,0x00B2,0x00B2}, {0x00B3,0x00B3,0x00B3}, {0x00B4,0x00B4,0x00B4}, {0x039C,0x00B5,0x039C}, {0x00B6,0x00B6,0x00B6}, {0x00B7,0x00B7,0x00B7}, {0x00B8,0x00B8,0x00B8}, {0x00B9,0x00B9,0x00B9}, {0x00BA,0x00BA,0x00BA}, {0x00BB,0x00BB,0x00BB}, {0x00BC,0x00BC,0x00BC}, {0x00BD,0x00BD,0x00BD}, {0x00BE,0x00BE,0x00BE}, {0x00BF,0x00BF,0x00BF}, {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, {0x00D6,0x00F6,0x004F}, {0x00D7,0x00D7,0x00D7}, {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, {0x00DE,0x00FE,0x00DE}, {0x00DF,0x00DF,0x00DF}, {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, {0x00D6,0x00F6,0x004F}, {0x00F7,0x00F7,0x00F7}, {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, {0x00DE,0x00FE,0x00DE}, {0x0178,0x00FF,0x0059} }; static MY_UNICASE_INFO plane01[]={ {0x0100,0x0101,0x0041}, {0x0100,0x0101,0x0041}, {0x0102,0x0103,0x0041}, {0x0102,0x0103,0x0041}, {0x0104,0x0105,0x0041}, {0x0104,0x0105,0x0041}, {0x0106,0x0107,0x0043}, {0x0106,0x0107,0x0043}, {0x0108,0x0109,0x0043}, {0x0108,0x0109,0x0043}, {0x010A,0x010B,0x0043}, {0x010A,0x010B,0x0043}, {0x010C,0x010D,0x0043}, {0x010C,0x010D,0x0043}, {0x010E,0x010F,0x0044}, {0x010E,0x010F,0x0044}, {0x0110,0x0111,0x0110}, {0x0110,0x0111,0x0110}, {0x0112,0x0113,0x0045}, {0x0112,0x0113,0x0045}, {0x0114,0x0115,0x0045}, {0x0114,0x0115,0x0045}, {0x0116,0x0117,0x0045}, {0x0116,0x0117,0x0045}, {0x0118,0x0119,0x0045}, {0x0118,0x0119,0x0045}, {0x011A,0x011B,0x0045}, {0x011A,0x011B,0x0045}, {0x011C,0x011D,0x0047}, {0x011C,0x011D,0x0047}, {0x011E,0x011F,0x0047}, {0x011E,0x011F,0x0047}, {0x0120,0x0121,0x0047}, {0x0120,0x0121,0x0047}, {0x0122,0x0123,0x0047}, {0x0122,0x0123,0x0047}, {0x0124,0x0125,0x0048}, {0x0124,0x0125,0x0048}, {0x0126,0x0127,0x0126}, {0x0126,0x0127,0x0126}, {0x0128,0x0129,0x0049}, {0x0128,0x0129,0x0049}, {0x012A,0x012B,0x0049}, {0x012A,0x012B,0x0049}, {0x012C,0x012D,0x0049}, {0x012C,0x012D,0x0049}, {0x012E,0x012F,0x0049}, {0x012E,0x012F,0x0049}, {0x0130,0x0069,0x0049}, {0x0049,0x0131,0x0049}, {0x0132,0x0133,0x0132}, {0x0132,0x0133,0x0132}, {0x0134,0x0135,0x004A}, {0x0134,0x0135,0x004A}, {0x0136,0x0137,0x004B}, {0x0136,0x0137,0x004B}, {0x0138,0x0138,0x0138}, {0x0139,0x013A,0x004C}, {0x0139,0x013A,0x004C}, {0x013B,0x013C,0x004C}, {0x013B,0x013C,0x004C}, {0x013D,0x013E,0x004C}, {0x013D,0x013E,0x004C}, {0x013F,0x0140,0x013F}, {0x013F,0x0140,0x013F}, {0x0141,0x0142,0x0141}, {0x0141,0x0142,0x0141}, {0x0143,0x0144,0x004E}, {0x0143,0x0144,0x004E}, {0x0145,0x0146,0x004E}, {0x0145,0x0146,0x004E}, {0x0147,0x0148,0x004E}, {0x0147,0x0148,0x004E}, {0x0149,0x0149,0x0149}, {0x014A,0x014B,0x014A}, {0x014A,0x014B,0x014A}, {0x014C,0x014D,0x004F}, {0x014C,0x014D,0x004F}, {0x014E,0x014F,0x004F}, {0x014E,0x014F,0x004F}, {0x0150,0x0151,0x004F}, {0x0150,0x0151,0x004F}, {0x0152,0x0153,0x0152}, {0x0152,0x0153,0x0152}, {0x0154,0x0155,0x0052}, {0x0154,0x0155,0x0052}, {0x0156,0x0157,0x0052}, {0x0156,0x0157,0x0052}, {0x0158,0x0159,0x0052}, {0x0158,0x0159,0x0052}, {0x015A,0x015B,0x0053}, {0x015A,0x015B,0x0053}, {0x015C,0x015D,0x0053}, {0x015C,0x015D,0x0053}, {0x015E,0x015F,0x0053}, {0x015E,0x015F,0x0053}, {0x0160,0x0161,0x0053}, {0x0160,0x0161,0x0053}, {0x0162,0x0163,0x0054}, {0x0162,0x0163,0x0054}, {0x0164,0x0165,0x0054}, {0x0164,0x0165,0x0054}, {0x0166,0x0167,0x0166}, {0x0166,0x0167,0x0166}, {0x0168,0x0169,0x0055}, {0x0168,0x0169,0x0055}, {0x016A,0x016B,0x0055}, {0x016A,0x016B,0x0055}, {0x016C,0x016D,0x0055}, {0x016C,0x016D,0x0055}, {0x016E,0x016F,0x0055}, {0x016E,0x016F,0x0055}, {0x0170,0x0171,0x0055}, {0x0170,0x0171,0x0055}, {0x0172,0x0173,0x0055}, {0x0172,0x0173,0x0055}, {0x0174,0x0175,0x0057}, {0x0174,0x0175,0x0057}, {0x0176,0x0177,0x0059}, {0x0176,0x0177,0x0059}, {0x0178,0x00FF,0x0059}, {0x0179,0x017A,0x005A}, {0x0179,0x017A,0x005A}, {0x017B,0x017C,0x005A}, {0x017B,0x017C,0x005A}, {0x017D,0x017E,0x005A}, {0x017D,0x017E,0x005A}, {0x0053,0x017F,0x0053}, {0x0180,0x0180,0x0180}, {0x0181,0x0253,0x0181}, {0x0182,0x0183,0x0182}, {0x0182,0x0183,0x0182}, {0x0184,0x0185,0x0184}, {0x0184,0x0185,0x0184}, {0x0186,0x0254,0x0186}, {0x0187,0x0188,0x0187}, {0x0187,0x0188,0x0187}, {0x0189,0x0256,0x0189}, {0x018A,0x0257,0x018A}, {0x018B,0x018C,0x018B}, {0x018B,0x018C,0x018B}, {0x018D,0x018D,0x018D}, {0x018E,0x01DD,0x018E}, {0x018F,0x0259,0x018F}, {0x0190,0x025B,0x0190}, {0x0191,0x0192,0x0191}, {0x0191,0x0192,0x0191}, {0x0193,0x0260,0x0193}, {0x0194,0x0263,0x0194}, {0x01F6,0x0195,0x01F6}, {0x0196,0x0269,0x0196}, {0x0197,0x0268,0x0197}, {0x0198,0x0199,0x0198}, {0x0198,0x0199,0x0198}, {0x019A,0x019A,0x019A}, {0x019B,0x019B,0x019B}, {0x019C,0x026F,0x019C}, {0x019D,0x0272,0x019D}, {0x019E,0x019E,0x019E}, {0x019F,0x0275,0x019F}, {0x01A0,0x01A1,0x004F}, {0x01A0,0x01A1,0x004F}, {0x01A2,0x01A3,0x01A2}, {0x01A2,0x01A3,0x01A2}, {0x01A4,0x01A5,0x01A4}, {0x01A4,0x01A5,0x01A4}, {0x01A6,0x0280,0x01A6}, {0x01A7,0x01A8,0x01A7}, {0x01A7,0x01A8,0x01A7}, {0x01A9,0x0283,0x01A9}, {0x01AA,0x01AA,0x01AA}, {0x01AB,0x01AB,0x01AB}, {0x01AC,0x01AD,0x01AC}, {0x01AC,0x01AD,0x01AC}, {0x01AE,0x0288,0x01AE}, {0x01AF,0x01B0,0x0055}, {0x01AF,0x01B0,0x0055}, {0x01B1,0x028A,0x01B1}, {0x01B2,0x028B,0x01B2}, {0x01B3,0x01B4,0x01B3}, {0x01B3,0x01B4,0x01B3}, {0x01B5,0x01B6,0x01B5}, {0x01B5,0x01B6,0x01B5}, {0x01B7,0x0292,0x01B7}, {0x01B8,0x01B9,0x01B8}, {0x01B8,0x01B9,0x01B8}, {0x01BA,0x01BA,0x01BA}, {0x01BB,0x01BB,0x01BB}, {0x01BC,0x01BD,0x01BC}, {0x01BC,0x01BD,0x01BC}, {0x01BE,0x01BE,0x01BE}, {0x01F7,0x01BF,0x01F7}, {0x01C0,0x01C0,0x01C0}, {0x01C1,0x01C1,0x01C1}, {0x01C2,0x01C2,0x01C2}, {0x01C3,0x01C3,0x01C3}, {0x01C4,0x01C6,0x01C4}, {0x01C4,0x01C6,0x01C4}, {0x01C4,0x01C6,0x01C4}, {0x01C7,0x01C9,0x01C7}, {0x01C7,0x01C9,0x01C7}, {0x01C7,0x01C9,0x01C7}, {0x01CA,0x01CC,0x01CA}, {0x01CA,0x01CC,0x01CA}, {0x01CA,0x01CC,0x01CA}, {0x01CD,0x01CE,0x0041}, {0x01CD,0x01CE,0x0041}, {0x01CF,0x01D0,0x0049}, {0x01CF,0x01D0,0x0049}, {0x01D1,0x01D2,0x004F}, {0x01D1,0x01D2,0x004F}, {0x01D3,0x01D4,0x0055}, {0x01D3,0x01D4,0x0055}, {0x01D5,0x01D6,0x0055}, {0x01D5,0x01D6,0x0055}, {0x01D7,0x01D8,0x0055}, {0x01D7,0x01D8,0x0055}, {0x01D9,0x01DA,0x0055}, {0x01D9,0x01DA,0x0055}, {0x01DB,0x01DC,0x0055}, {0x01DB,0x01DC,0x0055}, {0x018E,0x01DD,0x018E}, {0x01DE,0x01DF,0x0041}, {0x01DE,0x01DF,0x0041}, {0x01E0,0x01E1,0x0041}, {0x01E0,0x01E1,0x0041}, {0x01E2,0x01E3,0x00C6}, {0x01E2,0x01E3,0x00C6}, {0x01E4,0x01E5,0x01E4}, {0x01E4,0x01E5,0x01E4}, {0x01E6,0x01E7,0x0047}, {0x01E6,0x01E7,0x0047}, {0x01E8,0x01E9,0x004B}, {0x01E8,0x01E9,0x004B}, {0x01EA,0x01EB,0x004F}, {0x01EA,0x01EB,0x004F}, {0x01EC,0x01ED,0x004F}, {0x01EC,0x01ED,0x004F}, {0x01EE,0x01EF,0x01B7}, {0x01EE,0x01EF,0x01B7}, {0x01F0,0x01F0,0x004A}, {0x01F1,0x01F3,0x01F1}, {0x01F1,0x01F3,0x01F1}, {0x01F1,0x01F3,0x01F1}, {0x01F4,0x01F5,0x0047}, {0x01F4,0x01F5,0x0047}, {0x01F6,0x0195,0x01F6}, {0x01F7,0x01BF,0x01F7}, {0x01F8,0x01F9,0x004E}, {0x01F8,0x01F9,0x004E}, {0x01FA,0x01FB,0x0041}, {0x01FA,0x01FB,0x0041}, {0x01FC,0x01FD,0x00C6}, {0x01FC,0x01FD,0x00C6}, {0x01FE,0x01FF,0x00D8}, {0x01FE,0x01FF,0x00D8} }; static MY_UNICASE_INFO plane02[]={ {0x0200,0x0201,0x0041}, {0x0200,0x0201,0x0041}, {0x0202,0x0203,0x0041}, {0x0202,0x0203,0x0041}, {0x0204,0x0205,0x0045}, {0x0204,0x0205,0x0045}, {0x0206,0x0207,0x0045}, {0x0206,0x0207,0x0045}, {0x0208,0x0209,0x0049}, {0x0208,0x0209,0x0049}, {0x020A,0x020B,0x0049}, {0x020A,0x020B,0x0049}, {0x020C,0x020D,0x004F}, {0x020C,0x020D,0x004F}, {0x020E,0x020F,0x004F}, {0x020E,0x020F,0x004F}, {0x0210,0x0211,0x0052}, {0x0210,0x0211,0x0052}, {0x0212,0x0213,0x0052}, {0x0212,0x0213,0x0052}, {0x0214,0x0215,0x0055}, {0x0214,0x0215,0x0055}, {0x0216,0x0217,0x0055}, {0x0216,0x0217,0x0055}, {0x0218,0x0219,0x0053}, {0x0218,0x0219,0x0053}, {0x021A,0x021B,0x0054}, {0x021A,0x021B,0x0054}, {0x021C,0x021D,0x021C}, {0x021C,0x021D,0x021C}, {0x021E,0x021F,0x0048}, {0x021E,0x021F,0x0048}, {0x0220,0x0220,0x0220}, {0x0221,0x0221,0x0221}, {0x0222,0x0223,0x0222}, {0x0222,0x0223,0x0222}, {0x0224,0x0225,0x0224}, {0x0224,0x0225,0x0224}, {0x0226,0x0227,0x0041}, {0x0226,0x0227,0x0041}, {0x0228,0x0229,0x0045}, {0x0228,0x0229,0x0045}, {0x022A,0x022B,0x004F}, {0x022A,0x022B,0x004F}, {0x022C,0x022D,0x004F}, {0x022C,0x022D,0x004F}, {0x022E,0x022F,0x004F}, {0x022E,0x022F,0x004F}, {0x0230,0x0231,0x004F}, {0x0230,0x0231,0x004F}, {0x0232,0x0233,0x0059}, {0x0232,0x0233,0x0059}, {0x0234,0x0234,0x0234}, {0x0235,0x0235,0x0235}, {0x0236,0x0236,0x0236}, {0x0237,0x0237,0x0237}, {0x0238,0x0238,0x0238}, {0x0239,0x0239,0x0239}, {0x023A,0x023A,0x023A}, {0x023B,0x023B,0x023B}, {0x023C,0x023C,0x023C}, {0x023D,0x023D,0x023D}, {0x023E,0x023E,0x023E}, {0x023F,0x023F,0x023F}, {0x0240,0x0240,0x0240}, {0x0241,0x0241,0x0241}, {0x0242,0x0242,0x0242}, {0x0243,0x0243,0x0243}, {0x0244,0x0244,0x0244}, {0x0245,0x0245,0x0245}, {0x0246,0x0246,0x0246}, {0x0247,0x0247,0x0247}, {0x0248,0x0248,0x0248}, {0x0249,0x0249,0x0249}, {0x024A,0x024A,0x024A}, {0x024B,0x024B,0x024B}, {0x024C,0x024C,0x024C}, {0x024D,0x024D,0x024D}, {0x024E,0x024E,0x024E}, {0x024F,0x024F,0x024F}, {0x0250,0x0250,0x0250}, {0x0251,0x0251,0x0251}, {0x0252,0x0252,0x0252}, {0x0181,0x0253,0x0181}, {0x0186,0x0254,0x0186}, {0x0255,0x0255,0x0255}, {0x0189,0x0256,0x0189}, {0x018A,0x0257,0x018A}, {0x0258,0x0258,0x0258}, {0x018F,0x0259,0x018F}, {0x025A,0x025A,0x025A}, {0x0190,0x025B,0x0190}, {0x025C,0x025C,0x025C}, {0x025D,0x025D,0x025D}, {0x025E,0x025E,0x025E}, {0x025F,0x025F,0x025F}, {0x0193,0x0260,0x0193}, {0x0261,0x0261,0x0261}, {0x0262,0x0262,0x0262}, {0x0194,0x0263,0x0194}, {0x0264,0x0264,0x0264}, {0x0265,0x0265,0x0265}, {0x0266,0x0266,0x0266}, {0x0267,0x0267,0x0267}, {0x0197,0x0268,0x0197}, {0x0196,0x0269,0x0196}, {0x026A,0x026A,0x026A}, {0x026B,0x026B,0x026B}, {0x026C,0x026C,0x026C}, {0x026D,0x026D,0x026D}, {0x026E,0x026E,0x026E}, {0x019C,0x026F,0x019C}, {0x0270,0x0270,0x0270}, {0x0271,0x0271,0x0271}, {0x019D,0x0272,0x019D}, {0x0273,0x0273,0x0273}, {0x0274,0x0274,0x0274}, {0x019F,0x0275,0x019F}, {0x0276,0x0276,0x0276}, {0x0277,0x0277,0x0277}, {0x0278,0x0278,0x0278}, {0x0279,0x0279,0x0279}, {0x027A,0x027A,0x027A}, {0x027B,0x027B,0x027B}, {0x027C,0x027C,0x027C}, {0x027D,0x027D,0x027D}, {0x027E,0x027E,0x027E}, {0x027F,0x027F,0x027F}, {0x01A6,0x0280,0x01A6}, {0x0281,0x0281,0x0281}, {0x0282,0x0282,0x0282}, {0x01A9,0x0283,0x01A9}, {0x0284,0x0284,0x0284}, {0x0285,0x0285,0x0285}, {0x0286,0x0286,0x0286}, {0x0287,0x0287,0x0287}, {0x01AE,0x0288,0x01AE}, {0x0289,0x0289,0x0289}, {0x01B1,0x028A,0x01B1}, {0x01B2,0x028B,0x01B2}, {0x028C,0x028C,0x028C}, {0x028D,0x028D,0x028D}, {0x028E,0x028E,0x028E}, {0x028F,0x028F,0x028F}, {0x0290,0x0290,0x0290}, {0x0291,0x0291,0x0291}, {0x01B7,0x0292,0x01B7}, {0x0293,0x0293,0x0293}, {0x0294,0x0294,0x0294}, {0x0295,0x0295,0x0295}, {0x0296,0x0296,0x0296}, {0x0297,0x0297,0x0297}, {0x0298,0x0298,0x0298}, {0x0299,0x0299,0x0299}, {0x029A,0x029A,0x029A}, {0x029B,0x029B,0x029B}, {0x029C,0x029C,0x029C}, {0x029D,0x029D,0x029D}, {0x029E,0x029E,0x029E}, {0x029F,0x029F,0x029F}, {0x02A0,0x02A0,0x02A0}, {0x02A1,0x02A1,0x02A1}, {0x02A2,0x02A2,0x02A2}, {0x02A3,0x02A3,0x02A3}, {0x02A4,0x02A4,0x02A4}, {0x02A5,0x02A5,0x02A5}, {0x02A6,0x02A6,0x02A6}, {0x02A7,0x02A7,0x02A7}, {0x02A8,0x02A8,0x02A8}, {0x02A9,0x02A9,0x02A9}, {0x02AA,0x02AA,0x02AA}, {0x02AB,0x02AB,0x02AB}, {0x02AC,0x02AC,0x02AC}, {0x02AD,0x02AD,0x02AD}, {0x02AE,0x02AE,0x02AE}, {0x02AF,0x02AF,0x02AF}, {0x02B0,0x02B0,0x02B0}, {0x02B1,0x02B1,0x02B1}, {0x02B2,0x02B2,0x02B2}, {0x02B3,0x02B3,0x02B3}, {0x02B4,0x02B4,0x02B4}, {0x02B5,0x02B5,0x02B5}, {0x02B6,0x02B6,0x02B6}, {0x02B7,0x02B7,0x02B7}, {0x02B8,0x02B8,0x02B8}, {0x02B9,0x02B9,0x02B9}, {0x02BA,0x02BA,0x02BA}, {0x02BB,0x02BB,0x02BB}, {0x02BC,0x02BC,0x02BC}, {0x02BD,0x02BD,0x02BD}, {0x02BE,0x02BE,0x02BE}, {0x02BF,0x02BF,0x02BF}, {0x02C0,0x02C0,0x02C0}, {0x02C1,0x02C1,0x02C1}, {0x02C2,0x02C2,0x02C2}, {0x02C3,0x02C3,0x02C3}, {0x02C4,0x02C4,0x02C4}, {0x02C5,0x02C5,0x02C5}, {0x02C6,0x02C6,0x02C6}, {0x02C7,0x02C7,0x02C7}, {0x02C8,0x02C8,0x02C8}, {0x02C9,0x02C9,0x02C9}, {0x02CA,0x02CA,0x02CA}, {0x02CB,0x02CB,0x02CB}, {0x02CC,0x02CC,0x02CC}, {0x02CD,0x02CD,0x02CD}, {0x02CE,0x02CE,0x02CE}, {0x02CF,0x02CF,0x02CF}, {0x02D0,0x02D0,0x02D0}, {0x02D1,0x02D1,0x02D1}, {0x02D2,0x02D2,0x02D2}, {0x02D3,0x02D3,0x02D3}, {0x02D4,0x02D4,0x02D4}, {0x02D5,0x02D5,0x02D5}, {0x02D6,0x02D6,0x02D6}, {0x02D7,0x02D7,0x02D7}, {0x02D8,0x02D8,0x02D8}, {0x02D9,0x02D9,0x02D9}, {0x02DA,0x02DA,0x02DA}, {0x02DB,0x02DB,0x02DB}, {0x02DC,0x02DC,0x02DC}, {0x02DD,0x02DD,0x02DD}, {0x02DE,0x02DE,0x02DE}, {0x02DF,0x02DF,0x02DF}, {0x02E0,0x02E0,0x02E0}, {0x02E1,0x02E1,0x02E1}, {0x02E2,0x02E2,0x02E2}, {0x02E3,0x02E3,0x02E3}, {0x02E4,0x02E4,0x02E4}, {0x02E5,0x02E5,0x02E5}, {0x02E6,0x02E6,0x02E6}, {0x02E7,0x02E7,0x02E7}, {0x02E8,0x02E8,0x02E8}, {0x02E9,0x02E9,0x02E9}, {0x02EA,0x02EA,0x02EA}, {0x02EB,0x02EB,0x02EB}, {0x02EC,0x02EC,0x02EC}, {0x02ED,0x02ED,0x02ED}, {0x02EE,0x02EE,0x02EE}, {0x02EF,0x02EF,0x02EF}, {0x02F0,0x02F0,0x02F0}, {0x02F1,0x02F1,0x02F1}, {0x02F2,0x02F2,0x02F2}, {0x02F3,0x02F3,0x02F3}, {0x02F4,0x02F4,0x02F4}, {0x02F5,0x02F5,0x02F5}, {0x02F6,0x02F6,0x02F6}, {0x02F7,0x02F7,0x02F7}, {0x02F8,0x02F8,0x02F8}, {0x02F9,0x02F9,0x02F9}, {0x02FA,0x02FA,0x02FA}, {0x02FB,0x02FB,0x02FB}, {0x02FC,0x02FC,0x02FC}, {0x02FD,0x02FD,0x02FD}, {0x02FE,0x02FE,0x02FE}, {0x02FF,0x02FF,0x02FF} }; static MY_UNICASE_INFO plane03[]={ {0x0300,0x0300,0x0300}, {0x0301,0x0301,0x0301}, {0x0302,0x0302,0x0302}, {0x0303,0x0303,0x0303}, {0x0304,0x0304,0x0304}, {0x0305,0x0305,0x0305}, {0x0306,0x0306,0x0306}, {0x0307,0x0307,0x0307}, {0x0308,0x0308,0x0308}, {0x0309,0x0309,0x0309}, {0x030A,0x030A,0x030A}, {0x030B,0x030B,0x030B}, {0x030C,0x030C,0x030C}, {0x030D,0x030D,0x030D}, {0x030E,0x030E,0x030E}, {0x030F,0x030F,0x030F}, {0x0310,0x0310,0x0310}, {0x0311,0x0311,0x0311}, {0x0312,0x0312,0x0312}, {0x0313,0x0313,0x0313}, {0x0314,0x0314,0x0314}, {0x0315,0x0315,0x0315}, {0x0316,0x0316,0x0316}, {0x0317,0x0317,0x0317}, {0x0318,0x0318,0x0318}, {0x0319,0x0319,0x0319}, {0x031A,0x031A,0x031A}, {0x031B,0x031B,0x031B}, {0x031C,0x031C,0x031C}, {0x031D,0x031D,0x031D}, {0x031E,0x031E,0x031E}, {0x031F,0x031F,0x031F}, {0x0320,0x0320,0x0320}, {0x0321,0x0321,0x0321}, {0x0322,0x0322,0x0322}, {0x0323,0x0323,0x0323}, {0x0324,0x0324,0x0324}, {0x0325,0x0325,0x0325}, {0x0326,0x0326,0x0326}, {0x0327,0x0327,0x0327}, {0x0328,0x0328,0x0328}, {0x0329,0x0329,0x0329}, {0x032A,0x032A,0x032A}, {0x032B,0x032B,0x032B}, {0x032C,0x032C,0x032C}, {0x032D,0x032D,0x032D}, {0x032E,0x032E,0x032E}, {0x032F,0x032F,0x032F}, {0x0330,0x0330,0x0330}, {0x0331,0x0331,0x0331}, {0x0332,0x0332,0x0332}, {0x0333,0x0333,0x0333}, {0x0334,0x0334,0x0334}, {0x0335,0x0335,0x0335}, {0x0336,0x0336,0x0336}, {0x0337,0x0337,0x0337}, {0x0338,0x0338,0x0338}, {0x0339,0x0339,0x0339}, {0x033A,0x033A,0x033A}, {0x033B,0x033B,0x033B}, {0x033C,0x033C,0x033C}, {0x033D,0x033D,0x033D}, {0x033E,0x033E,0x033E}, {0x033F,0x033F,0x033F}, {0x0340,0x0340,0x0340}, {0x0341,0x0341,0x0341}, {0x0342,0x0342,0x0342}, {0x0343,0x0343,0x0343}, {0x0344,0x0344,0x0344}, {0x0399,0x0345,0x0399}, {0x0346,0x0346,0x0346}, {0x0347,0x0347,0x0347}, {0x0348,0x0348,0x0348}, {0x0349,0x0349,0x0349}, {0x034A,0x034A,0x034A}, {0x034B,0x034B,0x034B}, {0x034C,0x034C,0x034C}, {0x034D,0x034D,0x034D}, {0x034E,0x034E,0x034E}, {0x034F,0x034F,0x034F}, {0x0350,0x0350,0x0350}, {0x0351,0x0351,0x0351}, {0x0352,0x0352,0x0352}, {0x0353,0x0353,0x0353}, {0x0354,0x0354,0x0354}, {0x0355,0x0355,0x0355}, {0x0356,0x0356,0x0356}, {0x0357,0x0357,0x0357}, {0x0358,0x0358,0x0358}, {0x0359,0x0359,0x0359}, {0x035A,0x035A,0x035A}, {0x035B,0x035B,0x035B}, {0x035C,0x035C,0x035C}, {0x035D,0x035D,0x035D}, {0x035E,0x035E,0x035E}, {0x035F,0x035F,0x035F}, {0x0360,0x0360,0x0360}, {0x0361,0x0361,0x0361}, {0x0362,0x0362,0x0362}, {0x0363,0x0363,0x0363}, {0x0364,0x0364,0x0364}, {0x0365,0x0365,0x0365}, {0x0366,0x0366,0x0366}, {0x0367,0x0367,0x0367}, {0x0368,0x0368,0x0368}, {0x0369,0x0369,0x0369}, {0x036A,0x036A,0x036A}, {0x036B,0x036B,0x036B}, {0x036C,0x036C,0x036C}, {0x036D,0x036D,0x036D}, {0x036E,0x036E,0x036E}, {0x036F,0x036F,0x036F}, {0x0370,0x0370,0x0370}, {0x0371,0x0371,0x0371}, {0x0372,0x0372,0x0372}, {0x0373,0x0373,0x0373}, {0x0374,0x0374,0x0374}, {0x0375,0x0375,0x0375}, {0x0376,0x0376,0x0376}, {0x0377,0x0377,0x0377}, {0x0378,0x0378,0x0378}, {0x0379,0x0379,0x0379}, {0x037A,0x037A,0x037A}, {0x037B,0x037B,0x037B}, {0x037C,0x037C,0x037C}, {0x037D,0x037D,0x037D}, {0x037E,0x037E,0x037E}, {0x037F,0x037F,0x037F}, {0x0380,0x0380,0x0380}, {0x0381,0x0381,0x0381}, {0x0382,0x0382,0x0382}, {0x0383,0x0383,0x0383}, {0x0384,0x0384,0x0384}, {0x0385,0x0385,0x0385}, {0x0386,0x03AC,0x0391}, {0x0387,0x0387,0x0387}, {0x0388,0x03AD,0x0395}, {0x0389,0x03AE,0x0397}, {0x038A,0x03AF,0x0399}, {0x038B,0x038B,0x038B}, {0x038C,0x03CC,0x039F}, {0x038D,0x038D,0x038D}, {0x038E,0x03CD,0x03A5}, {0x038F,0x03CE,0x03A9}, {0x0390,0x0390,0x0399}, {0x0391,0x03B1,0x0391}, {0x0392,0x03B2,0x0392}, {0x0393,0x03B3,0x0393}, {0x0394,0x03B4,0x0394}, {0x0395,0x03B5,0x0395}, {0x0396,0x03B6,0x0396}, {0x0397,0x03B7,0x0397}, {0x0398,0x03B8,0x0398}, {0x0399,0x03B9,0x0399}, {0x039A,0x03BA,0x039A}, {0x039B,0x03BB,0x039B}, {0x039C,0x03BC,0x039C}, {0x039D,0x03BD,0x039D}, {0x039E,0x03BE,0x039E}, {0x039F,0x03BF,0x039F}, {0x03A0,0x03C0,0x03A0}, {0x03A1,0x03C1,0x03A1}, {0x03A2,0x03A2,0x03A2}, {0x03A3,0x03C3,0x03A3}, {0x03A4,0x03C4,0x03A4}, {0x03A5,0x03C5,0x03A5}, {0x03A6,0x03C6,0x03A6}, {0x03A7,0x03C7,0x03A7}, {0x03A8,0x03C8,0x03A8}, {0x03A9,0x03C9,0x03A9}, {0x03AA,0x03CA,0x0399}, {0x03AB,0x03CB,0x03A5}, {0x0386,0x03AC,0x0391}, {0x0388,0x03AD,0x0395}, {0x0389,0x03AE,0x0397}, {0x038A,0x03AF,0x0399}, {0x03B0,0x03B0,0x03A5}, {0x0391,0x03B1,0x0391}, {0x0392,0x03B2,0x0392}, {0x0393,0x03B3,0x0393}, {0x0394,0x03B4,0x0394}, {0x0395,0x03B5,0x0395}, {0x0396,0x03B6,0x0396}, {0x0397,0x03B7,0x0397}, {0x0398,0x03B8,0x0398}, {0x0399,0x03B9,0x0399}, {0x039A,0x03BA,0x039A}, {0x039B,0x03BB,0x039B}, {0x039C,0x03BC,0x039C}, {0x039D,0x03BD,0x039D}, {0x039E,0x03BE,0x039E}, {0x039F,0x03BF,0x039F}, {0x03A0,0x03C0,0x03A0}, {0x03A1,0x03C1,0x03A1}, {0x03A3,0x03C2,0x03A3}, {0x03A3,0x03C3,0x03A3}, {0x03A4,0x03C4,0x03A4}, {0x03A5,0x03C5,0x03A5}, {0x03A6,0x03C6,0x03A6}, {0x03A7,0x03C7,0x03A7}, {0x03A8,0x03C8,0x03A8}, {0x03A9,0x03C9,0x03A9}, {0x03AA,0x03CA,0x0399}, {0x03AB,0x03CB,0x03A5}, {0x038C,0x03CC,0x039F}, {0x038E,0x03CD,0x03A5}, {0x038F,0x03CE,0x03A9}, {0x03CF,0x03CF,0x03CF}, {0x0392,0x03D0,0x0392}, {0x0398,0x03D1,0x0398}, {0x03D2,0x03D2,0x03D2}, {0x03D3,0x03D3,0x03D2}, {0x03D4,0x03D4,0x03D2}, {0x03A6,0x03D5,0x03A6}, {0x03A0,0x03D6,0x03A0}, {0x03D7,0x03D7,0x03D7}, {0x03D8,0x03D8,0x03D8}, {0x03D9,0x03D9,0x03D9}, {0x03DA,0x03DB,0x03DA}, {0x03DA,0x03DB,0x03DA}, {0x03DC,0x03DD,0x03DC}, {0x03DC,0x03DD,0x03DC}, {0x03DE,0x03DF,0x03DE}, {0x03DE,0x03DF,0x03DE}, {0x03E0,0x03E1,0x03E0}, {0x03E0,0x03E1,0x03E0}, {0x03E2,0x03E3,0x03E2}, {0x03E2,0x03E3,0x03E2}, {0x03E4,0x03E5,0x03E4}, {0x03E4,0x03E5,0x03E4}, {0x03E6,0x03E7,0x03E6}, {0x03E6,0x03E7,0x03E6}, {0x03E8,0x03E9,0x03E8}, {0x03E8,0x03E9,0x03E8}, {0x03EA,0x03EB,0x03EA}, {0x03EA,0x03EB,0x03EA}, {0x03EC,0x03ED,0x03EC}, {0x03EC,0x03ED,0x03EC}, {0x03EE,0x03EF,0x03EE}, {0x03EE,0x03EF,0x03EE}, {0x039A,0x03F0,0x039A}, {0x03A1,0x03F1,0x03A1}, {0x03A3,0x03F2,0x03A3}, {0x03F3,0x03F3,0x03F3}, {0x03F4,0x03F4,0x03F4}, {0x03F5,0x03F5,0x03F5}, {0x03F6,0x03F6,0x03F6}, {0x03F7,0x03F7,0x03F7}, {0x03F8,0x03F8,0x03F8}, {0x03F9,0x03F9,0x03F9}, {0x03FA,0x03FA,0x03FA}, {0x03FB,0x03FB,0x03FB}, {0x03FC,0x03FC,0x03FC}, {0x03FD,0x03FD,0x03FD}, {0x03FE,0x03FE,0x03FE}, {0x03FF,0x03FF,0x03FF} }; static MY_UNICASE_INFO plane04[]={ {0x0400,0x0450,0x0415}, {0x0401,0x0451,0x0415}, {0x0402,0x0452,0x0402}, {0x0403,0x0453,0x0413}, {0x0404,0x0454,0x0404}, {0x0405,0x0455,0x0405}, {0x0406,0x0456,0x0406}, {0x0407,0x0457,0x0406}, {0x0408,0x0458,0x0408}, {0x0409,0x0459,0x0409}, {0x040A,0x045A,0x040A}, {0x040B,0x045B,0x040B}, {0x040C,0x045C,0x041A}, {0x040D,0x045D,0x0418}, {0x040E,0x045E,0x0423}, {0x040F,0x045F,0x040F}, {0x0410,0x0430,0x0410}, {0x0411,0x0431,0x0411}, {0x0412,0x0432,0x0412}, {0x0413,0x0433,0x0413}, {0x0414,0x0434,0x0414}, {0x0415,0x0435,0x0415}, {0x0416,0x0436,0x0416}, {0x0417,0x0437,0x0417}, {0x0418,0x0438,0x0418}, {0x0419,0x0439,0x0419}, {0x041A,0x043A,0x041A}, {0x041B,0x043B,0x041B}, {0x041C,0x043C,0x041C}, {0x041D,0x043D,0x041D}, {0x041E,0x043E,0x041E}, {0x041F,0x043F,0x041F}, {0x0420,0x0440,0x0420}, {0x0421,0x0441,0x0421}, {0x0422,0x0442,0x0422}, {0x0423,0x0443,0x0423}, {0x0424,0x0444,0x0424}, {0x0425,0x0445,0x0425}, {0x0426,0x0446,0x0426}, {0x0427,0x0447,0x0427}, {0x0428,0x0448,0x0428}, {0x0429,0x0449,0x0429}, {0x042A,0x044A,0x042A}, {0x042B,0x044B,0x042B}, {0x042C,0x044C,0x042C}, {0x042D,0x044D,0x042D}, {0x042E,0x044E,0x042E}, {0x042F,0x044F,0x042F}, {0x0410,0x0430,0x0410}, {0x0411,0x0431,0x0411}, {0x0412,0x0432,0x0412}, {0x0413,0x0433,0x0413}, {0x0414,0x0434,0x0414}, {0x0415,0x0435,0x0415}, {0x0416,0x0436,0x0416}, {0x0417,0x0437,0x0417}, {0x0418,0x0438,0x0418}, {0x0419,0x0439,0x0419}, {0x041A,0x043A,0x041A}, {0x041B,0x043B,0x041B}, {0x041C,0x043C,0x041C}, {0x041D,0x043D,0x041D}, {0x041E,0x043E,0x041E}, {0x041F,0x043F,0x041F}, {0x0420,0x0440,0x0420}, {0x0421,0x0441,0x0421}, {0x0422,0x0442,0x0422}, {0x0423,0x0443,0x0423}, {0x0424,0x0444,0x0424}, {0x0425,0x0445,0x0425}, {0x0426,0x0446,0x0426}, {0x0427,0x0447,0x0427}, {0x0428,0x0448,0x0428}, {0x0429,0x0449,0x0429}, {0x042A,0x044A,0x042A}, {0x042B,0x044B,0x042B}, {0x042C,0x044C,0x042C}, {0x042D,0x044D,0x042D}, {0x042E,0x044E,0x042E}, {0x042F,0x044F,0x042F}, {0x0400,0x0450,0x0415}, {0x0401,0x0451,0x0415}, {0x0402,0x0452,0x0402}, {0x0403,0x0453,0x0413}, {0x0404,0x0454,0x0404}, {0x0405,0x0455,0x0405}, {0x0406,0x0456,0x0406}, {0x0407,0x0457,0x0406}, {0x0408,0x0458,0x0408}, {0x0409,0x0459,0x0409}, {0x040A,0x045A,0x040A}, {0x040B,0x045B,0x040B}, {0x040C,0x045C,0x041A}, {0x040D,0x045D,0x0418}, {0x040E,0x045E,0x0423}, {0x040F,0x045F,0x040F}, {0x0460,0x0461,0x0460}, {0x0460,0x0461,0x0460}, {0x0462,0x0463,0x0462}, {0x0462,0x0463,0x0462}, {0x0464,0x0465,0x0464}, {0x0464,0x0465,0x0464}, {0x0466,0x0467,0x0466}, {0x0466,0x0467,0x0466}, {0x0468,0x0469,0x0468}, {0x0468,0x0469,0x0468}, {0x046A,0x046B,0x046A}, {0x046A,0x046B,0x046A}, {0x046C,0x046D,0x046C}, {0x046C,0x046D,0x046C}, {0x046E,0x046F,0x046E}, {0x046E,0x046F,0x046E}, {0x0470,0x0471,0x0470}, {0x0470,0x0471,0x0470}, {0x0472,0x0473,0x0472}, {0x0472,0x0473,0x0472}, {0x0474,0x0475,0x0474}, {0x0474,0x0475,0x0474}, {0x0476,0x0477,0x0474}, {0x0476,0x0477,0x0474}, {0x0478,0x0479,0x0478}, {0x0478,0x0479,0x0478}, {0x047A,0x047B,0x047A}, {0x047A,0x047B,0x047A}, {0x047C,0x047D,0x047C}, {0x047C,0x047D,0x047C}, {0x047E,0x047F,0x047E}, {0x047E,0x047F,0x047E}, {0x0480,0x0481,0x0480}, {0x0480,0x0481,0x0480}, {0x0482,0x0482,0x0482}, {0x0483,0x0483,0x0483}, {0x0484,0x0484,0x0484}, {0x0485,0x0485,0x0485}, {0x0486,0x0486,0x0486}, {0x0487,0x0487,0x0487}, {0x0488,0x0488,0x0488}, {0x0489,0x0489,0x0489}, {0x048A,0x048A,0x048A}, {0x048B,0x048B,0x048B}, {0x048C,0x048D,0x048C}, {0x048C,0x048D,0x048C}, {0x048E,0x048F,0x048E}, {0x048E,0x048F,0x048E}, {0x0490,0x0491,0x0490}, {0x0490,0x0491,0x0490}, {0x0492,0x0493,0x0492}, {0x0492,0x0493,0x0492}, {0x0494,0x0495,0x0494}, {0x0494,0x0495,0x0494}, {0x0496,0x0497,0x0496}, {0x0496,0x0497,0x0496}, {0x0498,0x0499,0x0498}, {0x0498,0x0499,0x0498}, {0x049A,0x049B,0x049A}, {0x049A,0x049B,0x049A}, {0x049C,0x049D,0x049C}, {0x049C,0x049D,0x049C}, {0x049E,0x049F,0x049E}, {0x049E,0x049F,0x049E}, {0x04A0,0x04A1,0x04A0}, {0x04A0,0x04A1,0x04A0}, {0x04A2,0x04A3,0x04A2}, {0x04A2,0x04A3,0x04A2}, {0x04A4,0x04A5,0x04A4}, {0x04A4,0x04A5,0x04A4}, {0x04A6,0x04A7,0x04A6}, {0x04A6,0x04A7,0x04A6}, {0x04A8,0x04A9,0x04A8}, {0x04A8,0x04A9,0x04A8}, {0x04AA,0x04AB,0x04AA}, {0x04AA,0x04AB,0x04AA}, {0x04AC,0x04AD,0x04AC}, {0x04AC,0x04AD,0x04AC}, {0x04AE,0x04AF,0x04AE}, {0x04AE,0x04AF,0x04AE}, {0x04B0,0x04B1,0x04B0}, {0x04B0,0x04B1,0x04B0}, {0x04B2,0x04B3,0x04B2}, {0x04B2,0x04B3,0x04B2}, {0x04B4,0x04B5,0x04B4}, {0x04B4,0x04B5,0x04B4}, {0x04B6,0x04B7,0x04B6}, {0x04B6,0x04B7,0x04B6}, {0x04B8,0x04B9,0x04B8}, {0x04B8,0x04B9,0x04B8}, {0x04BA,0x04BB,0x04BA}, {0x04BA,0x04BB,0x04BA}, {0x04BC,0x04BD,0x04BC}, {0x04BC,0x04BD,0x04BC}, {0x04BE,0x04BF,0x04BE}, {0x04BE,0x04BF,0x04BE}, {0x04C0,0x04C0,0x04C0}, {0x04C1,0x04C2,0x0416}, {0x04C1,0x04C2,0x0416}, {0x04C3,0x04C4,0x04C3}, {0x04C3,0x04C4,0x04C3}, {0x04C5,0x04C5,0x04C5}, {0x04C6,0x04C6,0x04C6}, {0x04C7,0x04C8,0x04C7}, {0x04C7,0x04C8,0x04C7}, {0x04C9,0x04C9,0x04C9}, {0x04CA,0x04CA,0x04CA}, {0x04CB,0x04CC,0x04CB}, {0x04CB,0x04CC,0x04CB}, {0x04CD,0x04CD,0x04CD}, {0x04CE,0x04CE,0x04CE}, {0x04CF,0x04CF,0x04CF}, {0x04D0,0x04D1,0x0410}, {0x04D0,0x04D1,0x0410}, {0x04D2,0x04D3,0x0410}, {0x04D2,0x04D3,0x0410}, {0x04D4,0x04D5,0x04D4}, {0x04D4,0x04D5,0x04D4}, {0x04D6,0x04D7,0x0415}, {0x04D6,0x04D7,0x0415}, {0x04D8,0x04D9,0x04D8}, {0x04D8,0x04D9,0x04D8}, {0x04DA,0x04DB,0x04D8}, {0x04DA,0x04DB,0x04D8}, {0x04DC,0x04DD,0x0416}, {0x04DC,0x04DD,0x0416}, {0x04DE,0x04DF,0x0417}, {0x04DE,0x04DF,0x0417}, {0x04E0,0x04E1,0x04E0}, {0x04E0,0x04E1,0x04E0}, {0x04E2,0x04E3,0x0418}, {0x04E2,0x04E3,0x0418}, {0x04E4,0x04E5,0x0418}, {0x04E4,0x04E5,0x0418}, {0x04E6,0x04E7,0x041E}, {0x04E6,0x04E7,0x041E}, {0x04E8,0x04E9,0x04E8}, {0x04E8,0x04E9,0x04E8}, {0x04EA,0x04EB,0x04E8}, {0x04EA,0x04EB,0x04E8}, {0x04EC,0x04ED,0x042D}, {0x04EC,0x04ED,0x042D}, {0x04EE,0x04EF,0x0423}, {0x04EE,0x04EF,0x0423}, {0x04F0,0x04F1,0x0423}, {0x04F0,0x04F1,0x0423}, {0x04F2,0x04F3,0x0423}, {0x04F2,0x04F3,0x0423}, {0x04F4,0x04F5,0x0427}, {0x04F4,0x04F5,0x0427}, {0x04F6,0x04F6,0x04F6}, {0x04F7,0x04F7,0x04F7}, {0x04F8,0x04F9,0x042B}, {0x04F8,0x04F9,0x042B}, {0x04FA,0x04FA,0x04FA}, {0x04FB,0x04FB,0x04FB}, {0x04FC,0x04FC,0x04FC}, {0x04FD,0x04FD,0x04FD}, {0x04FE,0x04FE,0x04FE}, {0x04FF,0x04FF,0x04FF} }; static MY_UNICASE_INFO plane05[]={ {0x0500,0x0500,0x0500}, {0x0501,0x0501,0x0501}, {0x0502,0x0502,0x0502}, {0x0503,0x0503,0x0503}, {0x0504,0x0504,0x0504}, {0x0505,0x0505,0x0505}, {0x0506,0x0506,0x0506}, {0x0507,0x0507,0x0507}, {0x0508,0x0508,0x0508}, {0x0509,0x0509,0x0509}, {0x050A,0x050A,0x050A}, {0x050B,0x050B,0x050B}, {0x050C,0x050C,0x050C}, {0x050D,0x050D,0x050D}, {0x050E,0x050E,0x050E}, {0x050F,0x050F,0x050F}, {0x0510,0x0510,0x0510}, {0x0511,0x0511,0x0511}, {0x0512,0x0512,0x0512}, {0x0513,0x0513,0x0513}, {0x0514,0x0514,0x0514}, {0x0515,0x0515,0x0515}, {0x0516,0x0516,0x0516}, {0x0517,0x0517,0x0517}, {0x0518,0x0518,0x0518}, {0x0519,0x0519,0x0519}, {0x051A,0x051A,0x051A}, {0x051B,0x051B,0x051B}, {0x051C,0x051C,0x051C}, {0x051D,0x051D,0x051D}, {0x051E,0x051E,0x051E}, {0x051F,0x051F,0x051F}, {0x0520,0x0520,0x0520}, {0x0521,0x0521,0x0521}, {0x0522,0x0522,0x0522}, {0x0523,0x0523,0x0523}, {0x0524,0x0524,0x0524}, {0x0525,0x0525,0x0525}, {0x0526,0x0526,0x0526}, {0x0527,0x0527,0x0527}, {0x0528,0x0528,0x0528}, {0x0529,0x0529,0x0529}, {0x052A,0x052A,0x052A}, {0x052B,0x052B,0x052B}, {0x052C,0x052C,0x052C}, {0x052D,0x052D,0x052D}, {0x052E,0x052E,0x052E}, {0x052F,0x052F,0x052F}, {0x0530,0x0530,0x0530}, {0x0531,0x0561,0x0531}, {0x0532,0x0562,0x0532}, {0x0533,0x0563,0x0533}, {0x0534,0x0564,0x0534}, {0x0535,0x0565,0x0535}, {0x0536,0x0566,0x0536}, {0x0537,0x0567,0x0537}, {0x0538,0x0568,0x0538}, {0x0539,0x0569,0x0539}, {0x053A,0x056A,0x053A}, {0x053B,0x056B,0x053B}, {0x053C,0x056C,0x053C}, {0x053D,0x056D,0x053D}, {0x053E,0x056E,0x053E}, {0x053F,0x056F,0x053F}, {0x0540,0x0570,0x0540}, {0x0541,0x0571,0x0541}, {0x0542,0x0572,0x0542}, {0x0543,0x0573,0x0543}, {0x0544,0x0574,0x0544}, {0x0545,0x0575,0x0545}, {0x0546,0x0576,0x0546}, {0x0547,0x0577,0x0547}, {0x0548,0x0578,0x0548}, {0x0549,0x0579,0x0549}, {0x054A,0x057A,0x054A}, {0x054B,0x057B,0x054B}, {0x054C,0x057C,0x054C}, {0x054D,0x057D,0x054D}, {0x054E,0x057E,0x054E}, {0x054F,0x057F,0x054F}, {0x0550,0x0580,0x0550}, {0x0551,0x0581,0x0551}, {0x0552,0x0582,0x0552}, {0x0553,0x0583,0x0553}, {0x0554,0x0584,0x0554}, {0x0555,0x0585,0x0555}, {0x0556,0x0586,0x0556}, {0x0557,0x0557,0x0557}, {0x0558,0x0558,0x0558}, {0x0559,0x0559,0x0559}, {0x055A,0x055A,0x055A}, {0x055B,0x055B,0x055B}, {0x055C,0x055C,0x055C}, {0x055D,0x055D,0x055D}, {0x055E,0x055E,0x055E}, {0x055F,0x055F,0x055F}, {0x0560,0x0560,0x0560}, {0x0531,0x0561,0x0531}, {0x0532,0x0562,0x0532}, {0x0533,0x0563,0x0533}, {0x0534,0x0564,0x0534}, {0x0535,0x0565,0x0535}, {0x0536,0x0566,0x0536}, {0x0537,0x0567,0x0537}, {0x0538,0x0568,0x0538}, {0x0539,0x0569,0x0539}, {0x053A,0x056A,0x053A}, {0x053B,0x056B,0x053B}, {0x053C,0x056C,0x053C}, {0x053D,0x056D,0x053D}, {0x053E,0x056E,0x053E}, {0x053F,0x056F,0x053F}, {0x0540,0x0570,0x0540}, {0x0541,0x0571,0x0541}, {0x0542,0x0572,0x0542}, {0x0543,0x0573,0x0543}, {0x0544,0x0574,0x0544}, {0x0545,0x0575,0x0545}, {0x0546,0x0576,0x0546}, {0x0547,0x0577,0x0547}, {0x0548,0x0578,0x0548}, {0x0549,0x0579,0x0549}, {0x054A,0x057A,0x054A}, {0x054B,0x057B,0x054B}, {0x054C,0x057C,0x054C}, {0x054D,0x057D,0x054D}, {0x054E,0x057E,0x054E}, {0x054F,0x057F,0x054F}, {0x0550,0x0580,0x0550}, {0x0551,0x0581,0x0551}, {0x0552,0x0582,0x0552}, {0x0553,0x0583,0x0553}, {0x0554,0x0584,0x0554}, {0x0555,0x0585,0x0555}, {0x0556,0x0586,0x0556}, {0x0587,0x0587,0x0587}, {0x0588,0x0588,0x0588}, {0x0589,0x0589,0x0589}, {0x058A,0x058A,0x058A}, {0x058B,0x058B,0x058B}, {0x058C,0x058C,0x058C}, {0x058D,0x058D,0x058D}, {0x058E,0x058E,0x058E}, {0x058F,0x058F,0x058F}, {0x0590,0x0590,0x0590}, {0x0591,0x0591,0x0591}, {0x0592,0x0592,0x0592}, {0x0593,0x0593,0x0593}, {0x0594,0x0594,0x0594}, {0x0595,0x0595,0x0595}, {0x0596,0x0596,0x0596}, {0x0597,0x0597,0x0597}, {0x0598,0x0598,0x0598}, {0x0599,0x0599,0x0599}, {0x059A,0x059A,0x059A}, {0x059B,0x059B,0x059B}, {0x059C,0x059C,0x059C}, {0x059D,0x059D,0x059D}, {0x059E,0x059E,0x059E}, {0x059F,0x059F,0x059F}, {0x05A0,0x05A0,0x05A0}, {0x05A1,0x05A1,0x05A1}, {0x05A2,0x05A2,0x05A2}, {0x05A3,0x05A3,0x05A3}, {0x05A4,0x05A4,0x05A4}, {0x05A5,0x05A5,0x05A5}, {0x05A6,0x05A6,0x05A6}, {0x05A7,0x05A7,0x05A7}, {0x05A8,0x05A8,0x05A8}, {0x05A9,0x05A9,0x05A9}, {0x05AA,0x05AA,0x05AA}, {0x05AB,0x05AB,0x05AB}, {0x05AC,0x05AC,0x05AC}, {0x05AD,0x05AD,0x05AD}, {0x05AE,0x05AE,0x05AE}, {0x05AF,0x05AF,0x05AF}, {0x05B0,0x05B0,0x05B0}, {0x05B1,0x05B1,0x05B1}, {0x05B2,0x05B2,0x05B2}, {0x05B3,0x05B3,0x05B3}, {0x05B4,0x05B4,0x05B4}, {0x05B5,0x05B5,0x05B5}, {0x05B6,0x05B6,0x05B6}, {0x05B7,0x05B7,0x05B7}, {0x05B8,0x05B8,0x05B8}, {0x05B9,0x05B9,0x05B9}, {0x05BA,0x05BA,0x05BA}, {0x05BB,0x05BB,0x05BB}, {0x05BC,0x05BC,0x05BC}, {0x05BD,0x05BD,0x05BD}, {0x05BE,0x05BE,0x05BE}, {0x05BF,0x05BF,0x05BF}, {0x05C0,0x05C0,0x05C0}, {0x05C1,0x05C1,0x05C1}, {0x05C2,0x05C2,0x05C2}, {0x05C3,0x05C3,0x05C3}, {0x05C4,0x05C4,0x05C4}, {0x05C5,0x05C5,0x05C5}, {0x05C6,0x05C6,0x05C6}, {0x05C7,0x05C7,0x05C7}, {0x05C8,0x05C8,0x05C8}, {0x05C9,0x05C9,0x05C9}, {0x05CA,0x05CA,0x05CA}, {0x05CB,0x05CB,0x05CB}, {0x05CC,0x05CC,0x05CC}, {0x05CD,0x05CD,0x05CD}, {0x05CE,0x05CE,0x05CE}, {0x05CF,0x05CF,0x05CF}, {0x05D0,0x05D0,0x05D0}, {0x05D1,0x05D1,0x05D1}, {0x05D2,0x05D2,0x05D2}, {0x05D3,0x05D3,0x05D3}, {0x05D4,0x05D4,0x05D4}, {0x05D5,0x05D5,0x05D5}, {0x05D6,0x05D6,0x05D6}, {0x05D7,0x05D7,0x05D7}, {0x05D8,0x05D8,0x05D8}, {0x05D9,0x05D9,0x05D9}, {0x05DA,0x05DA,0x05DA}, {0x05DB,0x05DB,0x05DB}, {0x05DC,0x05DC,0x05DC}, {0x05DD,0x05DD,0x05DD}, {0x05DE,0x05DE,0x05DE}, {0x05DF,0x05DF,0x05DF}, {0x05E0,0x05E0,0x05E0}, {0x05E1,0x05E1,0x05E1}, {0x05E2,0x05E2,0x05E2}, {0x05E3,0x05E3,0x05E3}, {0x05E4,0x05E4,0x05E4}, {0x05E5,0x05E5,0x05E5}, {0x05E6,0x05E6,0x05E6}, {0x05E7,0x05E7,0x05E7}, {0x05E8,0x05E8,0x05E8}, {0x05E9,0x05E9,0x05E9}, {0x05EA,0x05EA,0x05EA}, {0x05EB,0x05EB,0x05EB}, {0x05EC,0x05EC,0x05EC}, {0x05ED,0x05ED,0x05ED}, {0x05EE,0x05EE,0x05EE}, {0x05EF,0x05EF,0x05EF}, {0x05F0,0x05F0,0x05F0}, {0x05F1,0x05F1,0x05F1}, {0x05F2,0x05F2,0x05F2}, {0x05F3,0x05F3,0x05F3}, {0x05F4,0x05F4,0x05F4}, {0x05F5,0x05F5,0x05F5}, {0x05F6,0x05F6,0x05F6}, {0x05F7,0x05F7,0x05F7}, {0x05F8,0x05F8,0x05F8}, {0x05F9,0x05F9,0x05F9}, {0x05FA,0x05FA,0x05FA}, {0x05FB,0x05FB,0x05FB}, {0x05FC,0x05FC,0x05FC}, {0x05FD,0x05FD,0x05FD}, {0x05FE,0x05FE,0x05FE}, {0x05FF,0x05FF,0x05FF} }; static MY_UNICASE_INFO plane1E[]={ {0x1E00,0x1E01,0x0041}, {0x1E00,0x1E01,0x0041}, {0x1E02,0x1E03,0x0042}, {0x1E02,0x1E03,0x0042}, {0x1E04,0x1E05,0x0042}, {0x1E04,0x1E05,0x0042}, {0x1E06,0x1E07,0x0042}, {0x1E06,0x1E07,0x0042}, {0x1E08,0x1E09,0x0043}, {0x1E08,0x1E09,0x0043}, {0x1E0A,0x1E0B,0x0044}, {0x1E0A,0x1E0B,0x0044}, {0x1E0C,0x1E0D,0x0044}, {0x1E0C,0x1E0D,0x0044}, {0x1E0E,0x1E0F,0x0044}, {0x1E0E,0x1E0F,0x0044}, {0x1E10,0x1E11,0x0044}, {0x1E10,0x1E11,0x0044}, {0x1E12,0x1E13,0x0044}, {0x1E12,0x1E13,0x0044}, {0x1E14,0x1E15,0x0045}, {0x1E14,0x1E15,0x0045}, {0x1E16,0x1E17,0x0045}, {0x1E16,0x1E17,0x0045}, {0x1E18,0x1E19,0x0045}, {0x1E18,0x1E19,0x0045}, {0x1E1A,0x1E1B,0x0045}, {0x1E1A,0x1E1B,0x0045}, {0x1E1C,0x1E1D,0x0045}, {0x1E1C,0x1E1D,0x0045}, {0x1E1E,0x1E1F,0x0046}, {0x1E1E,0x1E1F,0x0046}, {0x1E20,0x1E21,0x0047}, {0x1E20,0x1E21,0x0047}, {0x1E22,0x1E23,0x0048}, {0x1E22,0x1E23,0x0048}, {0x1E24,0x1E25,0x0048}, {0x1E24,0x1E25,0x0048}, {0x1E26,0x1E27,0x0048}, {0x1E26,0x1E27,0x0048}, {0x1E28,0x1E29,0x0048}, {0x1E28,0x1E29,0x0048}, {0x1E2A,0x1E2B,0x0048}, {0x1E2A,0x1E2B,0x0048}, {0x1E2C,0x1E2D,0x0049}, {0x1E2C,0x1E2D,0x0049}, {0x1E2E,0x1E2F,0x0049}, {0x1E2E,0x1E2F,0x0049}, {0x1E30,0x1E31,0x004B}, {0x1E30,0x1E31,0x004B}, {0x1E32,0x1E33,0x004B}, {0x1E32,0x1E33,0x004B}, {0x1E34,0x1E35,0x004B}, {0x1E34,0x1E35,0x004B}, {0x1E36,0x1E37,0x004C}, {0x1E36,0x1E37,0x004C}, {0x1E38,0x1E39,0x004C}, {0x1E38,0x1E39,0x004C}, {0x1E3A,0x1E3B,0x004C}, {0x1E3A,0x1E3B,0x004C}, {0x1E3C,0x1E3D,0x004C}, {0x1E3C,0x1E3D,0x004C}, {0x1E3E,0x1E3F,0x004D}, {0x1E3E,0x1E3F,0x004D}, {0x1E40,0x1E41,0x004D}, {0x1E40,0x1E41,0x004D}, {0x1E42,0x1E43,0x004D}, {0x1E42,0x1E43,0x004D}, {0x1E44,0x1E45,0x004E}, {0x1E44,0x1E45,0x004E}, {0x1E46,0x1E47,0x004E}, {0x1E46,0x1E47,0x004E}, {0x1E48,0x1E49,0x004E}, {0x1E48,0x1E49,0x004E}, {0x1E4A,0x1E4B,0x004E}, {0x1E4A,0x1E4B,0x004E}, {0x1E4C,0x1E4D,0x004F}, {0x1E4C,0x1E4D,0x004F}, {0x1E4E,0x1E4F,0x004F}, {0x1E4E,0x1E4F,0x004F}, {0x1E50,0x1E51,0x004F}, {0x1E50,0x1E51,0x004F}, {0x1E52,0x1E53,0x004F}, {0x1E52,0x1E53,0x004F}, {0x1E54,0x1E55,0x0050}, {0x1E54,0x1E55,0x0050}, {0x1E56,0x1E57,0x0050}, {0x1E56,0x1E57,0x0050}, {0x1E58,0x1E59,0x0052}, {0x1E58,0x1E59,0x0052}, {0x1E5A,0x1E5B,0x0052}, {0x1E5A,0x1E5B,0x0052}, {0x1E5C,0x1E5D,0x0052}, {0x1E5C,0x1E5D,0x0052}, {0x1E5E,0x1E5F,0x0052}, {0x1E5E,0x1E5F,0x0052}, {0x1E60,0x1E61,0x0053}, {0x1E60,0x1E61,0x0053}, {0x1E62,0x1E63,0x0053}, {0x1E62,0x1E63,0x0053}, {0x1E64,0x1E65,0x0053}, {0x1E64,0x1E65,0x0053}, {0x1E66,0x1E67,0x0053}, {0x1E66,0x1E67,0x0053}, {0x1E68,0x1E69,0x0053}, {0x1E68,0x1E69,0x0053}, {0x1E6A,0x1E6B,0x0054}, {0x1E6A,0x1E6B,0x0054}, {0x1E6C,0x1E6D,0x0054}, {0x1E6C,0x1E6D,0x0054}, {0x1E6E,0x1E6F,0x0054}, {0x1E6E,0x1E6F,0x0054}, {0x1E70,0x1E71,0x0054}, {0x1E70,0x1E71,0x0054}, {0x1E72,0x1E73,0x0055}, {0x1E72,0x1E73,0x0055}, {0x1E74,0x1E75,0x0055}, {0x1E74,0x1E75,0x0055}, {0x1E76,0x1E77,0x0055}, {0x1E76,0x1E77,0x0055}, {0x1E78,0x1E79,0x0055}, {0x1E78,0x1E79,0x0055}, {0x1E7A,0x1E7B,0x0055}, {0x1E7A,0x1E7B,0x0055}, {0x1E7C,0x1E7D,0x0056}, {0x1E7C,0x1E7D,0x0056}, {0x1E7E,0x1E7F,0x0056}, {0x1E7E,0x1E7F,0x0056}, {0x1E80,0x1E81,0x0057}, {0x1E80,0x1E81,0x0057}, {0x1E82,0x1E83,0x0057}, {0x1E82,0x1E83,0x0057}, {0x1E84,0x1E85,0x0057}, {0x1E84,0x1E85,0x0057}, {0x1E86,0x1E87,0x0057}, {0x1E86,0x1E87,0x0057}, {0x1E88,0x1E89,0x0057}, {0x1E88,0x1E89,0x0057}, {0x1E8A,0x1E8B,0x0058}, {0x1E8A,0x1E8B,0x0058}, {0x1E8C,0x1E8D,0x0058}, {0x1E8C,0x1E8D,0x0058}, {0x1E8E,0x1E8F,0x0059}, {0x1E8E,0x1E8F,0x0059}, {0x1E90,0x1E91,0x005A}, {0x1E90,0x1E91,0x005A}, {0x1E92,0x1E93,0x005A}, {0x1E92,0x1E93,0x005A}, {0x1E94,0x1E95,0x005A}, {0x1E94,0x1E95,0x005A}, {0x1E96,0x1E96,0x0048}, {0x1E97,0x1E97,0x0054}, {0x1E98,0x1E98,0x0057}, {0x1E99,0x1E99,0x0059}, {0x1E9A,0x1E9A,0x1E9A}, {0x1E60,0x1E9B,0x0053}, {0x1E9C,0x1E9C,0x1E9C}, {0x1E9D,0x1E9D,0x1E9D}, {0x1E9E,0x1E9E,0x1E9E}, {0x1E9F,0x1E9F,0x1E9F}, {0x1EA0,0x1EA1,0x0041}, {0x1EA0,0x1EA1,0x0041}, {0x1EA2,0x1EA3,0x0041}, {0x1EA2,0x1EA3,0x0041}, {0x1EA4,0x1EA5,0x0041}, {0x1EA4,0x1EA5,0x0041}, {0x1EA6,0x1EA7,0x0041}, {0x1EA6,0x1EA7,0x0041}, {0x1EA8,0x1EA9,0x0041}, {0x1EA8,0x1EA9,0x0041}, {0x1EAA,0x1EAB,0x0041}, {0x1EAA,0x1EAB,0x0041}, {0x1EAC,0x1EAD,0x0041}, {0x1EAC,0x1EAD,0x0041}, {0x1EAE,0x1EAF,0x0041}, {0x1EAE,0x1EAF,0x0041}, {0x1EB0,0x1EB1,0x0041}, {0x1EB0,0x1EB1,0x0041}, {0x1EB2,0x1EB3,0x0041}, {0x1EB2,0x1EB3,0x0041}, {0x1EB4,0x1EB5,0x0041}, {0x1EB4,0x1EB5,0x0041}, {0x1EB6,0x1EB7,0x0041}, {0x1EB6,0x1EB7,0x0041}, {0x1EB8,0x1EB9,0x0045}, {0x1EB8,0x1EB9,0x0045}, {0x1EBA,0x1EBB,0x0045}, {0x1EBA,0x1EBB,0x0045}, {0x1EBC,0x1EBD,0x0045}, {0x1EBC,0x1EBD,0x0045}, {0x1EBE,0x1EBF,0x0045}, {0x1EBE,0x1EBF,0x0045}, {0x1EC0,0x1EC1,0x0045}, {0x1EC0,0x1EC1,0x0045}, {0x1EC2,0x1EC3,0x0045}, {0x1EC2,0x1EC3,0x0045}, {0x1EC4,0x1EC5,0x0045}, {0x1EC4,0x1EC5,0x0045}, {0x1EC6,0x1EC7,0x0045}, {0x1EC6,0x1EC7,0x0045}, {0x1EC8,0x1EC9,0x0049}, {0x1EC8,0x1EC9,0x0049}, {0x1ECA,0x1ECB,0x0049}, {0x1ECA,0x1ECB,0x0049}, {0x1ECC,0x1ECD,0x004F}, {0x1ECC,0x1ECD,0x004F}, {0x1ECE,0x1ECF,0x004F}, {0x1ECE,0x1ECF,0x004F}, {0x1ED0,0x1ED1,0x004F}, {0x1ED0,0x1ED1,0x004F}, {0x1ED2,0x1ED3,0x004F}, {0x1ED2,0x1ED3,0x004F}, {0x1ED4,0x1ED5,0x004F}, {0x1ED4,0x1ED5,0x004F}, {0x1ED6,0x1ED7,0x004F}, {0x1ED6,0x1ED7,0x004F}, {0x1ED8,0x1ED9,0x004F}, {0x1ED8,0x1ED9,0x004F}, {0x1EDA,0x1EDB,0x004F}, {0x1EDA,0x1EDB,0x004F}, {0x1EDC,0x1EDD,0x004F}, {0x1EDC,0x1EDD,0x004F}, {0x1EDE,0x1EDF,0x004F}, {0x1EDE,0x1EDF,0x004F}, {0x1EE0,0x1EE1,0x004F}, {0x1EE0,0x1EE1,0x004F}, {0x1EE2,0x1EE3,0x004F}, {0x1EE2,0x1EE3,0x004F}, {0x1EE4,0x1EE5,0x0055}, {0x1EE4,0x1EE5,0x0055}, {0x1EE6,0x1EE7,0x0055}, {0x1EE6,0x1EE7,0x0055}, {0x1EE8,0x1EE9,0x0055}, {0x1EE8,0x1EE9,0x0055}, {0x1EEA,0x1EEB,0x0055}, {0x1EEA,0x1EEB,0x0055}, {0x1EEC,0x1EED,0x0055}, {0x1EEC,0x1EED,0x0055}, {0x1EEE,0x1EEF,0x0055}, {0x1EEE,0x1EEF,0x0055}, {0x1EF0,0x1EF1,0x0055}, {0x1EF0,0x1EF1,0x0055}, {0x1EF2,0x1EF3,0x0059}, {0x1EF2,0x1EF3,0x0059}, {0x1EF4,0x1EF5,0x0059}, {0x1EF4,0x1EF5,0x0059}, {0x1EF6,0x1EF7,0x0059}, {0x1EF6,0x1EF7,0x0059}, {0x1EF8,0x1EF9,0x0059}, {0x1EF8,0x1EF9,0x0059}, {0x1EFA,0x1EFA,0x1EFA}, {0x1EFB,0x1EFB,0x1EFB}, {0x1EFC,0x1EFC,0x1EFC}, {0x1EFD,0x1EFD,0x1EFD}, {0x1EFE,0x1EFE,0x1EFE}, {0x1EFF,0x1EFF,0x1EFF} }; static MY_UNICASE_INFO plane1F[]={ {0x1F08,0x1F00,0x0391}, {0x1F09,0x1F01,0x0391}, {0x1F0A,0x1F02,0x0391}, {0x1F0B,0x1F03,0x0391}, {0x1F0C,0x1F04,0x0391}, {0x1F0D,0x1F05,0x0391}, {0x1F0E,0x1F06,0x0391}, {0x1F0F,0x1F07,0x0391}, {0x1F08,0x1F00,0x0391}, {0x1F09,0x1F01,0x0391}, {0x1F0A,0x1F02,0x0391}, {0x1F0B,0x1F03,0x0391}, {0x1F0C,0x1F04,0x0391}, {0x1F0D,0x1F05,0x0391}, {0x1F0E,0x1F06,0x0391}, {0x1F0F,0x1F07,0x0391}, {0x1F18,0x1F10,0x0395}, {0x1F19,0x1F11,0x0395}, {0x1F1A,0x1F12,0x0395}, {0x1F1B,0x1F13,0x0395}, {0x1F1C,0x1F14,0x0395}, {0x1F1D,0x1F15,0x0395}, {0x1F16,0x1F16,0x1F16}, {0x1F17,0x1F17,0x1F17}, {0x1F18,0x1F10,0x0395}, {0x1F19,0x1F11,0x0395}, {0x1F1A,0x1F12,0x0395}, {0x1F1B,0x1F13,0x0395}, {0x1F1C,0x1F14,0x0395}, {0x1F1D,0x1F15,0x0395}, {0x1F1E,0x1F1E,0x1F1E}, {0x1F1F,0x1F1F,0x1F1F}, {0x1F28,0x1F20,0x0397}, {0x1F29,0x1F21,0x0397}, {0x1F2A,0x1F22,0x0397}, {0x1F2B,0x1F23,0x0397}, {0x1F2C,0x1F24,0x0397}, {0x1F2D,0x1F25,0x0397}, {0x1F2E,0x1F26,0x0397}, {0x1F2F,0x1F27,0x0397}, {0x1F28,0x1F20,0x0397}, {0x1F29,0x1F21,0x0397}, {0x1F2A,0x1F22,0x0397}, {0x1F2B,0x1F23,0x0397}, {0x1F2C,0x1F24,0x0397}, {0x1F2D,0x1F25,0x0397}, {0x1F2E,0x1F26,0x0397}, {0x1F2F,0x1F27,0x0397}, {0x1F38,0x1F30,0x0399}, {0x1F39,0x1F31,0x0399}, {0x1F3A,0x1F32,0x0399}, {0x1F3B,0x1F33,0x0399}, {0x1F3C,0x1F34,0x0399}, {0x1F3D,0x1F35,0x0399}, {0x1F3E,0x1F36,0x0399}, {0x1F3F,0x1F37,0x0399}, {0x1F38,0x1F30,0x0399}, {0x1F39,0x1F31,0x0399}, {0x1F3A,0x1F32,0x0399}, {0x1F3B,0x1F33,0x0399}, {0x1F3C,0x1F34,0x0399}, {0x1F3D,0x1F35,0x0399}, {0x1F3E,0x1F36,0x0399}, {0x1F3F,0x1F37,0x0399}, {0x1F48,0x1F40,0x039F}, {0x1F49,0x1F41,0x039F}, {0x1F4A,0x1F42,0x039F}, {0x1F4B,0x1F43,0x039F}, {0x1F4C,0x1F44,0x039F}, {0x1F4D,0x1F45,0x039F}, {0x1F46,0x1F46,0x1F46}, {0x1F47,0x1F47,0x1F47}, {0x1F48,0x1F40,0x039F}, {0x1F49,0x1F41,0x039F}, {0x1F4A,0x1F42,0x039F}, {0x1F4B,0x1F43,0x039F}, {0x1F4C,0x1F44,0x039F}, {0x1F4D,0x1F45,0x039F}, {0x1F4E,0x1F4E,0x1F4E}, {0x1F4F,0x1F4F,0x1F4F}, {0x1F50,0x1F50,0x03A5}, {0x1F59,0x1F51,0x03A5}, {0x1F52,0x1F52,0x03A5}, {0x1F5B,0x1F53,0x03A5}, {0x1F54,0x1F54,0x03A5}, {0x1F5D,0x1F55,0x03A5}, {0x1F56,0x1F56,0x03A5}, {0x1F5F,0x1F57,0x03A5}, {0x1F58,0x1F58,0x1F58}, {0x1F59,0x1F51,0x03A5}, {0x1F5A,0x1F5A,0x1F5A}, {0x1F5B,0x1F53,0x03A5}, {0x1F5C,0x1F5C,0x1F5C}, {0x1F5D,0x1F55,0x03A5}, {0x1F5E,0x1F5E,0x1F5E}, {0x1F5F,0x1F57,0x03A5}, {0x1F68,0x1F60,0x03A9}, {0x1F69,0x1F61,0x03A9}, {0x1F6A,0x1F62,0x03A9}, {0x1F6B,0x1F63,0x03A9}, {0x1F6C,0x1F64,0x03A9}, {0x1F6D,0x1F65,0x03A9}, {0x1F6E,0x1F66,0x03A9}, {0x1F6F,0x1F67,0x03A9}, {0x1F68,0x1F60,0x03A9}, {0x1F69,0x1F61,0x03A9}, {0x1F6A,0x1F62,0x03A9}, {0x1F6B,0x1F63,0x03A9}, {0x1F6C,0x1F64,0x03A9}, {0x1F6D,0x1F65,0x03A9}, {0x1F6E,0x1F66,0x03A9}, {0x1F6F,0x1F67,0x03A9}, {0x1FBA,0x1F70,0x0391}, {0x1FBB,0x1F71,0x1FBB}, {0x1FC8,0x1F72,0x0395}, {0x1FC9,0x1F73,0x1FC9}, {0x1FCA,0x1F74,0x0397}, {0x1FCB,0x1F75,0x1FCB}, {0x1FDA,0x1F76,0x0399}, {0x1FDB,0x1F77,0x1FDB}, {0x1FF8,0x1F78,0x039F}, {0x1FF9,0x1F79,0x1FF9}, {0x1FEA,0x1F7A,0x03A5}, {0x1FEB,0x1F7B,0x1FEB}, {0x1FFA,0x1F7C,0x03A9}, {0x1FFB,0x1F7D,0x1FFB}, {0x1F7E,0x1F7E,0x1F7E}, {0x1F7F,0x1F7F,0x1F7F}, {0x1F88,0x1F80,0x0391}, {0x1F89,0x1F81,0x0391}, {0x1F8A,0x1F82,0x0391}, {0x1F8B,0x1F83,0x0391}, {0x1F8C,0x1F84,0x0391}, {0x1F8D,0x1F85,0x0391}, {0x1F8E,0x1F86,0x0391}, {0x1F8F,0x1F87,0x0391}, {0x1F88,0x1F80,0x0391}, {0x1F89,0x1F81,0x0391}, {0x1F8A,0x1F82,0x0391}, {0x1F8B,0x1F83,0x0391}, {0x1F8C,0x1F84,0x0391}, {0x1F8D,0x1F85,0x0391}, {0x1F8E,0x1F86,0x0391}, {0x1F8F,0x1F87,0x0391}, {0x1F98,0x1F90,0x0397}, {0x1F99,0x1F91,0x0397}, {0x1F9A,0x1F92,0x0397}, {0x1F9B,0x1F93,0x0397}, {0x1F9C,0x1F94,0x0397}, {0x1F9D,0x1F95,0x0397}, {0x1F9E,0x1F96,0x0397}, {0x1F9F,0x1F97,0x0397}, {0x1F98,0x1F90,0x0397}, {0x1F99,0x1F91,0x0397}, {0x1F9A,0x1F92,0x0397}, {0x1F9B,0x1F93,0x0397}, {0x1F9C,0x1F94,0x0397}, {0x1F9D,0x1F95,0x0397}, {0x1F9E,0x1F96,0x0397}, {0x1F9F,0x1F97,0x0397}, {0x1FA8,0x1FA0,0x03A9}, {0x1FA9,0x1FA1,0x03A9}, {0x1FAA,0x1FA2,0x03A9}, {0x1FAB,0x1FA3,0x03A9}, {0x1FAC,0x1FA4,0x03A9}, {0x1FAD,0x1FA5,0x03A9}, {0x1FAE,0x1FA6,0x03A9}, {0x1FAF,0x1FA7,0x03A9}, {0x1FA8,0x1FA0,0x03A9}, {0x1FA9,0x1FA1,0x03A9}, {0x1FAA,0x1FA2,0x03A9}, {0x1FAB,0x1FA3,0x03A9}, {0x1FAC,0x1FA4,0x03A9}, {0x1FAD,0x1FA5,0x03A9}, {0x1FAE,0x1FA6,0x03A9}, {0x1FAF,0x1FA7,0x03A9}, {0x1FB8,0x1FB0,0x0391}, {0x1FB9,0x1FB1,0x0391}, {0x1FB2,0x1FB2,0x0391}, {0x1FBC,0x1FB3,0x0391}, {0x1FB4,0x1FB4,0x0391}, {0x1FB5,0x1FB5,0x1FB5}, {0x1FB6,0x1FB6,0x0391}, {0x1FB7,0x1FB7,0x0391}, {0x1FB8,0x1FB0,0x0391}, {0x1FB9,0x1FB1,0x0391}, {0x1FBA,0x1F70,0x0391}, {0x1FBB,0x1F71,0x1FBB}, {0x1FBC,0x1FB3,0x0391}, {0x1FBD,0x1FBD,0x1FBD}, {0x0399,0x1FBE,0x0399}, {0x1FBF,0x1FBF,0x1FBF}, {0x1FC0,0x1FC0,0x1FC0}, {0x1FC1,0x1FC1,0x1FC1}, {0x1FC2,0x1FC2,0x0397}, {0x1FCC,0x1FC3,0x0397}, {0x1FC4,0x1FC4,0x0397}, {0x1FC5,0x1FC5,0x1FC5}, {0x1FC6,0x1FC6,0x0397}, {0x1FC7,0x1FC7,0x0397}, {0x1FC8,0x1F72,0x0395}, {0x1FC9,0x1F73,0x1FC9}, {0x1FCA,0x1F74,0x0397}, {0x1FCB,0x1F75,0x1FCB}, {0x1FCC,0x1FC3,0x0397}, {0x1FCD,0x1FCD,0x1FCD}, {0x1FCE,0x1FCE,0x1FCE}, {0x1FCF,0x1FCF,0x1FCF}, {0x1FD8,0x1FD0,0x0399}, {0x1FD9,0x1FD1,0x0399}, {0x1FD2,0x1FD2,0x0399}, {0x1FD3,0x1FD3,0x1FD3}, {0x1FD4,0x1FD4,0x1FD4}, {0x1FD5,0x1FD5,0x1FD5}, {0x1FD6,0x1FD6,0x0399}, {0x1FD7,0x1FD7,0x0399}, {0x1FD8,0x1FD0,0x0399}, {0x1FD9,0x1FD1,0x0399}, {0x1FDA,0x1F76,0x0399}, {0x1FDB,0x1F77,0x1FDB}, {0x1FDC,0x1FDC,0x1FDC}, {0x1FDD,0x1FDD,0x1FDD}, {0x1FDE,0x1FDE,0x1FDE}, {0x1FDF,0x1FDF,0x1FDF}, {0x1FE8,0x1FE0,0x03A5}, {0x1FE9,0x1FE1,0x03A5}, {0x1FE2,0x1FE2,0x03A5}, {0x1FE3,0x1FE3,0x1FE3}, {0x1FE4,0x1FE4,0x03A1}, {0x1FEC,0x1FE5,0x03A1}, {0x1FE6,0x1FE6,0x03A5}, {0x1FE7,0x1FE7,0x03A5}, {0x1FE8,0x1FE0,0x03A5}, {0x1FE9,0x1FE1,0x03A5}, {0x1FEA,0x1F7A,0x03A5}, {0x1FEB,0x1F7B,0x1FEB}, {0x1FEC,0x1FE5,0x03A1}, {0x1FED,0x1FED,0x1FED}, {0x1FEE,0x1FEE,0x1FEE}, {0x1FEF,0x1FEF,0x1FEF}, {0x1FF0,0x1FF0,0x1FF0}, {0x1FF1,0x1FF1,0x1FF1}, {0x1FF2,0x1FF2,0x03A9}, {0x1FFC,0x1FF3,0x03A9}, {0x1FF4,0x1FF4,0x03A9}, {0x1FF5,0x1FF5,0x1FF5}, {0x1FF6,0x1FF6,0x03A9}, {0x1FF7,0x1FF7,0x03A9}, {0x1FF8,0x1F78,0x039F}, {0x1FF9,0x1F79,0x1FF9}, {0x1FFA,0x1F7C,0x03A9}, {0x1FFB,0x1F7D,0x1FFB}, {0x1FFC,0x1FF3,0x03A9}, {0x1FFD,0x1FFD,0x1FFD}, {0x1FFE,0x1FFE,0x1FFE}, {0x1FFF,0x1FFF,0x1FFF} }; static MY_UNICASE_INFO plane21[]={ {0x2100,0x2100,0x2100}, {0x2101,0x2101,0x2101}, {0x2102,0x2102,0x2102}, {0x2103,0x2103,0x2103}, {0x2104,0x2104,0x2104}, {0x2105,0x2105,0x2105}, {0x2106,0x2106,0x2106}, {0x2107,0x2107,0x2107}, {0x2108,0x2108,0x2108}, {0x2109,0x2109,0x2109}, {0x210A,0x210A,0x210A}, {0x210B,0x210B,0x210B}, {0x210C,0x210C,0x210C}, {0x210D,0x210D,0x210D}, {0x210E,0x210E,0x210E}, {0x210F,0x210F,0x210F}, {0x2110,0x2110,0x2110}, {0x2111,0x2111,0x2111}, {0x2112,0x2112,0x2112}, {0x2113,0x2113,0x2113}, {0x2114,0x2114,0x2114}, {0x2115,0x2115,0x2115}, {0x2116,0x2116,0x2116}, {0x2117,0x2117,0x2117}, {0x2118,0x2118,0x2118}, {0x2119,0x2119,0x2119}, {0x211A,0x211A,0x211A}, {0x211B,0x211B,0x211B}, {0x211C,0x211C,0x211C}, {0x211D,0x211D,0x211D}, {0x211E,0x211E,0x211E}, {0x211F,0x211F,0x211F}, {0x2120,0x2120,0x2120}, {0x2121,0x2121,0x2121}, {0x2122,0x2122,0x2122}, {0x2123,0x2123,0x2123}, {0x2124,0x2124,0x2124}, {0x2125,0x2125,0x2125}, {0x2126,0x03C9,0x2126}, {0x2127,0x2127,0x2127}, {0x2128,0x2128,0x2128}, {0x2129,0x2129,0x2129}, {0x212A,0x006B,0x212A}, {0x212B,0x00E5,0x212B}, {0x212C,0x212C,0x212C}, {0x212D,0x212D,0x212D}, {0x212E,0x212E,0x212E}, {0x212F,0x212F,0x212F}, {0x2130,0x2130,0x2130}, {0x2131,0x2131,0x2131}, {0x2132,0x2132,0x2132}, {0x2133,0x2133,0x2133}, {0x2134,0x2134,0x2134}, {0x2135,0x2135,0x2135}, {0x2136,0x2136,0x2136}, {0x2137,0x2137,0x2137}, {0x2138,0x2138,0x2138}, {0x2139,0x2139,0x2139}, {0x213A,0x213A,0x213A}, {0x213B,0x213B,0x213B}, {0x213C,0x213C,0x213C}, {0x213D,0x213D,0x213D}, {0x213E,0x213E,0x213E}, {0x213F,0x213F,0x213F}, {0x2140,0x2140,0x2140}, {0x2141,0x2141,0x2141}, {0x2142,0x2142,0x2142}, {0x2143,0x2143,0x2143}, {0x2144,0x2144,0x2144}, {0x2145,0x2145,0x2145}, {0x2146,0x2146,0x2146}, {0x2147,0x2147,0x2147}, {0x2148,0x2148,0x2148}, {0x2149,0x2149,0x2149}, {0x214A,0x214A,0x214A}, {0x214B,0x214B,0x214B}, {0x214C,0x214C,0x214C}, {0x214D,0x214D,0x214D}, {0x214E,0x214E,0x214E}, {0x214F,0x214F,0x214F}, {0x2150,0x2150,0x2150}, {0x2151,0x2151,0x2151}, {0x2152,0x2152,0x2152}, {0x2153,0x2153,0x2153}, {0x2154,0x2154,0x2154}, {0x2155,0x2155,0x2155}, {0x2156,0x2156,0x2156}, {0x2157,0x2157,0x2157}, {0x2158,0x2158,0x2158}, {0x2159,0x2159,0x2159}, {0x215A,0x215A,0x215A}, {0x215B,0x215B,0x215B}, {0x215C,0x215C,0x215C}, {0x215D,0x215D,0x215D}, {0x215E,0x215E,0x215E}, {0x215F,0x215F,0x215F}, {0x2160,0x2170,0x2160}, {0x2161,0x2171,0x2161}, {0x2162,0x2172,0x2162}, {0x2163,0x2173,0x2163}, {0x2164,0x2174,0x2164}, {0x2165,0x2175,0x2165}, {0x2166,0x2176,0x2166}, {0x2167,0x2177,0x2167}, {0x2168,0x2178,0x2168}, {0x2169,0x2179,0x2169}, {0x216A,0x217A,0x216A}, {0x216B,0x217B,0x216B}, {0x216C,0x217C,0x216C}, {0x216D,0x217D,0x216D}, {0x216E,0x217E,0x216E}, {0x216F,0x217F,0x216F}, {0x2160,0x2170,0x2160}, {0x2161,0x2171,0x2161}, {0x2162,0x2172,0x2162}, {0x2163,0x2173,0x2163}, {0x2164,0x2174,0x2164}, {0x2165,0x2175,0x2165}, {0x2166,0x2176,0x2166}, {0x2167,0x2177,0x2167}, {0x2168,0x2178,0x2168}, {0x2169,0x2179,0x2169}, {0x216A,0x217A,0x216A}, {0x216B,0x217B,0x216B}, {0x216C,0x217C,0x216C}, {0x216D,0x217D,0x216D}, {0x216E,0x217E,0x216E}, {0x216F,0x217F,0x216F}, {0x2180,0x2180,0x2180}, {0x2181,0x2181,0x2181}, {0x2182,0x2182,0x2182}, {0x2183,0x2183,0x2183}, {0x2184,0x2184,0x2184}, {0x2185,0x2185,0x2185}, {0x2186,0x2186,0x2186}, {0x2187,0x2187,0x2187}, {0x2188,0x2188,0x2188}, {0x2189,0x2189,0x2189}, {0x218A,0x218A,0x218A}, {0x218B,0x218B,0x218B}, {0x218C,0x218C,0x218C}, {0x218D,0x218D,0x218D}, {0x218E,0x218E,0x218E}, {0x218F,0x218F,0x218F}, {0x2190,0x2190,0x2190}, {0x2191,0x2191,0x2191}, {0x2192,0x2192,0x2192}, {0x2193,0x2193,0x2193}, {0x2194,0x2194,0x2194}, {0x2195,0x2195,0x2195}, {0x2196,0x2196,0x2196}, {0x2197,0x2197,0x2197}, {0x2198,0x2198,0x2198}, {0x2199,0x2199,0x2199}, {0x219A,0x219A,0x219A}, {0x219B,0x219B,0x219B}, {0x219C,0x219C,0x219C}, {0x219D,0x219D,0x219D}, {0x219E,0x219E,0x219E}, {0x219F,0x219F,0x219F}, {0x21A0,0x21A0,0x21A0}, {0x21A1,0x21A1,0x21A1}, {0x21A2,0x21A2,0x21A2}, {0x21A3,0x21A3,0x21A3}, {0x21A4,0x21A4,0x21A4}, {0x21A5,0x21A5,0x21A5}, {0x21A6,0x21A6,0x21A6}, {0x21A7,0x21A7,0x21A7}, {0x21A8,0x21A8,0x21A8}, {0x21A9,0x21A9,0x21A9}, {0x21AA,0x21AA,0x21AA}, {0x21AB,0x21AB,0x21AB}, {0x21AC,0x21AC,0x21AC}, {0x21AD,0x21AD,0x21AD}, {0x21AE,0x21AE,0x21AE}, {0x21AF,0x21AF,0x21AF}, {0x21B0,0x21B0,0x21B0}, {0x21B1,0x21B1,0x21B1}, {0x21B2,0x21B2,0x21B2}, {0x21B3,0x21B3,0x21B3}, {0x21B4,0x21B4,0x21B4}, {0x21B5,0x21B5,0x21B5}, {0x21B6,0x21B6,0x21B6}, {0x21B7,0x21B7,0x21B7}, {0x21B8,0x21B8,0x21B8}, {0x21B9,0x21B9,0x21B9}, {0x21BA,0x21BA,0x21BA}, {0x21BB,0x21BB,0x21BB}, {0x21BC,0x21BC,0x21BC}, {0x21BD,0x21BD,0x21BD}, {0x21BE,0x21BE,0x21BE}, {0x21BF,0x21BF,0x21BF}, {0x21C0,0x21C0,0x21C0}, {0x21C1,0x21C1,0x21C1}, {0x21C2,0x21C2,0x21C2}, {0x21C3,0x21C3,0x21C3}, {0x21C4,0x21C4,0x21C4}, {0x21C5,0x21C5,0x21C5}, {0x21C6,0x21C6,0x21C6}, {0x21C7,0x21C7,0x21C7}, {0x21C8,0x21C8,0x21C8}, {0x21C9,0x21C9,0x21C9}, {0x21CA,0x21CA,0x21CA}, {0x21CB,0x21CB,0x21CB}, {0x21CC,0x21CC,0x21CC}, {0x21CD,0x21CD,0x21CD}, {0x21CE,0x21CE,0x21CE}, {0x21CF,0x21CF,0x21CF}, {0x21D0,0x21D0,0x21D0}, {0x21D1,0x21D1,0x21D1}, {0x21D2,0x21D2,0x21D2}, {0x21D3,0x21D3,0x21D3}, {0x21D4,0x21D4,0x21D4}, {0x21D5,0x21D5,0x21D5}, {0x21D6,0x21D6,0x21D6}, {0x21D7,0x21D7,0x21D7}, {0x21D8,0x21D8,0x21D8}, {0x21D9,0x21D9,0x21D9}, {0x21DA,0x21DA,0x21DA}, {0x21DB,0x21DB,0x21DB}, {0x21DC,0x21DC,0x21DC}, {0x21DD,0x21DD,0x21DD}, {0x21DE,0x21DE,0x21DE}, {0x21DF,0x21DF,0x21DF}, {0x21E0,0x21E0,0x21E0}, {0x21E1,0x21E1,0x21E1}, {0x21E2,0x21E2,0x21E2}, {0x21E3,0x21E3,0x21E3}, {0x21E4,0x21E4,0x21E4}, {0x21E5,0x21E5,0x21E5}, {0x21E6,0x21E6,0x21E6}, {0x21E7,0x21E7,0x21E7}, {0x21E8,0x21E8,0x21E8}, {0x21E9,0x21E9,0x21E9}, {0x21EA,0x21EA,0x21EA}, {0x21EB,0x21EB,0x21EB}, {0x21EC,0x21EC,0x21EC}, {0x21ED,0x21ED,0x21ED}, {0x21EE,0x21EE,0x21EE}, {0x21EF,0x21EF,0x21EF}, {0x21F0,0x21F0,0x21F0}, {0x21F1,0x21F1,0x21F1}, {0x21F2,0x21F2,0x21F2}, {0x21F3,0x21F3,0x21F3}, {0x21F4,0x21F4,0x21F4}, {0x21F5,0x21F5,0x21F5}, {0x21F6,0x21F6,0x21F6}, {0x21F7,0x21F7,0x21F7}, {0x21F8,0x21F8,0x21F8}, {0x21F9,0x21F9,0x21F9}, {0x21FA,0x21FA,0x21FA}, {0x21FB,0x21FB,0x21FB}, {0x21FC,0x21FC,0x21FC}, {0x21FD,0x21FD,0x21FD}, {0x21FE,0x21FE,0x21FE}, {0x21FF,0x21FF,0x21FF} }; static MY_UNICASE_INFO plane24[]={ {0x2400,0x2400,0x2400}, {0x2401,0x2401,0x2401}, {0x2402,0x2402,0x2402}, {0x2403,0x2403,0x2403}, {0x2404,0x2404,0x2404}, {0x2405,0x2405,0x2405}, {0x2406,0x2406,0x2406}, {0x2407,0x2407,0x2407}, {0x2408,0x2408,0x2408}, {0x2409,0x2409,0x2409}, {0x240A,0x240A,0x240A}, {0x240B,0x240B,0x240B}, {0x240C,0x240C,0x240C}, {0x240D,0x240D,0x240D}, {0x240E,0x240E,0x240E}, {0x240F,0x240F,0x240F}, {0x2410,0x2410,0x2410}, {0x2411,0x2411,0x2411}, {0x2412,0x2412,0x2412}, {0x2413,0x2413,0x2413}, {0x2414,0x2414,0x2414}, {0x2415,0x2415,0x2415}, {0x2416,0x2416,0x2416}, {0x2417,0x2417,0x2417}, {0x2418,0x2418,0x2418}, {0x2419,0x2419,0x2419}, {0x241A,0x241A,0x241A}, {0x241B,0x241B,0x241B}, {0x241C,0x241C,0x241C}, {0x241D,0x241D,0x241D}, {0x241E,0x241E,0x241E}, {0x241F,0x241F,0x241F}, {0x2420,0x2420,0x2420}, {0x2421,0x2421,0x2421}, {0x2422,0x2422,0x2422}, {0x2423,0x2423,0x2423}, {0x2424,0x2424,0x2424}, {0x2425,0x2425,0x2425}, {0x2426,0x2426,0x2426}, {0x2427,0x2427,0x2427}, {0x2428,0x2428,0x2428}, {0x2429,0x2429,0x2429}, {0x242A,0x242A,0x242A}, {0x242B,0x242B,0x242B}, {0x242C,0x242C,0x242C}, {0x242D,0x242D,0x242D}, {0x242E,0x242E,0x242E}, {0x242F,0x242F,0x242F}, {0x2430,0x2430,0x2430}, {0x2431,0x2431,0x2431}, {0x2432,0x2432,0x2432}, {0x2433,0x2433,0x2433}, {0x2434,0x2434,0x2434}, {0x2435,0x2435,0x2435}, {0x2436,0x2436,0x2436}, {0x2437,0x2437,0x2437}, {0x2438,0x2438,0x2438}, {0x2439,0x2439,0x2439}, {0x243A,0x243A,0x243A}, {0x243B,0x243B,0x243B}, {0x243C,0x243C,0x243C}, {0x243D,0x243D,0x243D}, {0x243E,0x243E,0x243E}, {0x243F,0x243F,0x243F}, {0x2440,0x2440,0x2440}, {0x2441,0x2441,0x2441}, {0x2442,0x2442,0x2442}, {0x2443,0x2443,0x2443}, {0x2444,0x2444,0x2444}, {0x2445,0x2445,0x2445}, {0x2446,0x2446,0x2446}, {0x2447,0x2447,0x2447}, {0x2448,0x2448,0x2448}, {0x2449,0x2449,0x2449}, {0x244A,0x244A,0x244A}, {0x244B,0x244B,0x244B}, {0x244C,0x244C,0x244C}, {0x244D,0x244D,0x244D}, {0x244E,0x244E,0x244E}, {0x244F,0x244F,0x244F}, {0x2450,0x2450,0x2450}, {0x2451,0x2451,0x2451}, {0x2452,0x2452,0x2452}, {0x2453,0x2453,0x2453}, {0x2454,0x2454,0x2454}, {0x2455,0x2455,0x2455}, {0x2456,0x2456,0x2456}, {0x2457,0x2457,0x2457}, {0x2458,0x2458,0x2458}, {0x2459,0x2459,0x2459}, {0x245A,0x245A,0x245A}, {0x245B,0x245B,0x245B}, {0x245C,0x245C,0x245C}, {0x245D,0x245D,0x245D}, {0x245E,0x245E,0x245E}, {0x245F,0x245F,0x245F}, {0x2460,0x2460,0x2460}, {0x2461,0x2461,0x2461}, {0x2462,0x2462,0x2462}, {0x2463,0x2463,0x2463}, {0x2464,0x2464,0x2464}, {0x2465,0x2465,0x2465}, {0x2466,0x2466,0x2466}, {0x2467,0x2467,0x2467}, {0x2468,0x2468,0x2468}, {0x2469,0x2469,0x2469}, {0x246A,0x246A,0x246A}, {0x246B,0x246B,0x246B}, {0x246C,0x246C,0x246C}, {0x246D,0x246D,0x246D}, {0x246E,0x246E,0x246E}, {0x246F,0x246F,0x246F}, {0x2470,0x2470,0x2470}, {0x2471,0x2471,0x2471}, {0x2472,0x2472,0x2472}, {0x2473,0x2473,0x2473}, {0x2474,0x2474,0x2474}, {0x2475,0x2475,0x2475}, {0x2476,0x2476,0x2476}, {0x2477,0x2477,0x2477}, {0x2478,0x2478,0x2478}, {0x2479,0x2479,0x2479}, {0x247A,0x247A,0x247A}, {0x247B,0x247B,0x247B}, {0x247C,0x247C,0x247C}, {0x247D,0x247D,0x247D}, {0x247E,0x247E,0x247E}, {0x247F,0x247F,0x247F}, {0x2480,0x2480,0x2480}, {0x2481,0x2481,0x2481}, {0x2482,0x2482,0x2482}, {0x2483,0x2483,0x2483}, {0x2484,0x2484,0x2484}, {0x2485,0x2485,0x2485}, {0x2486,0x2486,0x2486}, {0x2487,0x2487,0x2487}, {0x2488,0x2488,0x2488}, {0x2489,0x2489,0x2489}, {0x248A,0x248A,0x248A}, {0x248B,0x248B,0x248B}, {0x248C,0x248C,0x248C}, {0x248D,0x248D,0x248D}, {0x248E,0x248E,0x248E}, {0x248F,0x248F,0x248F}, {0x2490,0x2490,0x2490}, {0x2491,0x2491,0x2491}, {0x2492,0x2492,0x2492}, {0x2493,0x2493,0x2493}, {0x2494,0x2494,0x2494}, {0x2495,0x2495,0x2495}, {0x2496,0x2496,0x2496}, {0x2497,0x2497,0x2497}, {0x2498,0x2498,0x2498}, {0x2499,0x2499,0x2499}, {0x249A,0x249A,0x249A}, {0x249B,0x249B,0x249B}, {0x249C,0x249C,0x249C}, {0x249D,0x249D,0x249D}, {0x249E,0x249E,0x249E}, {0x249F,0x249F,0x249F}, {0x24A0,0x24A0,0x24A0}, {0x24A1,0x24A1,0x24A1}, {0x24A2,0x24A2,0x24A2}, {0x24A3,0x24A3,0x24A3}, {0x24A4,0x24A4,0x24A4}, {0x24A5,0x24A5,0x24A5}, {0x24A6,0x24A6,0x24A6}, {0x24A7,0x24A7,0x24A7}, {0x24A8,0x24A8,0x24A8}, {0x24A9,0x24A9,0x24A9}, {0x24AA,0x24AA,0x24AA}, {0x24AB,0x24AB,0x24AB}, {0x24AC,0x24AC,0x24AC}, {0x24AD,0x24AD,0x24AD}, {0x24AE,0x24AE,0x24AE}, {0x24AF,0x24AF,0x24AF}, {0x24B0,0x24B0,0x24B0}, {0x24B1,0x24B1,0x24B1}, {0x24B2,0x24B2,0x24B2}, {0x24B3,0x24B3,0x24B3}, {0x24B4,0x24B4,0x24B4}, {0x24B5,0x24B5,0x24B5}, {0x24B6,0x24D0,0x24B6}, {0x24B7,0x24D1,0x24B7}, {0x24B8,0x24D2,0x24B8}, {0x24B9,0x24D3,0x24B9}, {0x24BA,0x24D4,0x24BA}, {0x24BB,0x24D5,0x24BB}, {0x24BC,0x24D6,0x24BC}, {0x24BD,0x24D7,0x24BD}, {0x24BE,0x24D8,0x24BE}, {0x24BF,0x24D9,0x24BF}, {0x24C0,0x24DA,0x24C0}, {0x24C1,0x24DB,0x24C1}, {0x24C2,0x24DC,0x24C2}, {0x24C3,0x24DD,0x24C3}, {0x24C4,0x24DE,0x24C4}, {0x24C5,0x24DF,0x24C5}, {0x24C6,0x24E0,0x24C6}, {0x24C7,0x24E1,0x24C7}, {0x24C8,0x24E2,0x24C8}, {0x24C9,0x24E3,0x24C9}, {0x24CA,0x24E4,0x24CA}, {0x24CB,0x24E5,0x24CB}, {0x24CC,0x24E6,0x24CC}, {0x24CD,0x24E7,0x24CD}, {0x24CE,0x24E8,0x24CE}, {0x24CF,0x24E9,0x24CF}, {0x24B6,0x24D0,0x24B6}, {0x24B7,0x24D1,0x24B7}, {0x24B8,0x24D2,0x24B8}, {0x24B9,0x24D3,0x24B9}, {0x24BA,0x24D4,0x24BA}, {0x24BB,0x24D5,0x24BB}, {0x24BC,0x24D6,0x24BC}, {0x24BD,0x24D7,0x24BD}, {0x24BE,0x24D8,0x24BE}, {0x24BF,0x24D9,0x24BF}, {0x24C0,0x24DA,0x24C0}, {0x24C1,0x24DB,0x24C1}, {0x24C2,0x24DC,0x24C2}, {0x24C3,0x24DD,0x24C3}, {0x24C4,0x24DE,0x24C4}, {0x24C5,0x24DF,0x24C5}, {0x24C6,0x24E0,0x24C6}, {0x24C7,0x24E1,0x24C7}, {0x24C8,0x24E2,0x24C8}, {0x24C9,0x24E3,0x24C9}, {0x24CA,0x24E4,0x24CA}, {0x24CB,0x24E5,0x24CB}, {0x24CC,0x24E6,0x24CC}, {0x24CD,0x24E7,0x24CD}, {0x24CE,0x24E8,0x24CE}, {0x24CF,0x24E9,0x24CF}, {0x24EA,0x24EA,0x24EA}, {0x24EB,0x24EB,0x24EB}, {0x24EC,0x24EC,0x24EC}, {0x24ED,0x24ED,0x24ED}, {0x24EE,0x24EE,0x24EE}, {0x24EF,0x24EF,0x24EF}, {0x24F0,0x24F0,0x24F0}, {0x24F1,0x24F1,0x24F1}, {0x24F2,0x24F2,0x24F2}, {0x24F3,0x24F3,0x24F3}, {0x24F4,0x24F4,0x24F4}, {0x24F5,0x24F5,0x24F5}, {0x24F6,0x24F6,0x24F6}, {0x24F7,0x24F7,0x24F7}, {0x24F8,0x24F8,0x24F8}, {0x24F9,0x24F9,0x24F9}, {0x24FA,0x24FA,0x24FA}, {0x24FB,0x24FB,0x24FB}, {0x24FC,0x24FC,0x24FC}, {0x24FD,0x24FD,0x24FD}, {0x24FE,0x24FE,0x24FE}, {0x24FF,0x24FF,0x24FF} }; static MY_UNICASE_INFO planeFF[]={ {0xFF00,0xFF00,0xFF00}, {0xFF01,0xFF01,0xFF01}, {0xFF02,0xFF02,0xFF02}, {0xFF03,0xFF03,0xFF03}, {0xFF04,0xFF04,0xFF04}, {0xFF05,0xFF05,0xFF05}, {0xFF06,0xFF06,0xFF06}, {0xFF07,0xFF07,0xFF07}, {0xFF08,0xFF08,0xFF08}, {0xFF09,0xFF09,0xFF09}, {0xFF0A,0xFF0A,0xFF0A}, {0xFF0B,0xFF0B,0xFF0B}, {0xFF0C,0xFF0C,0xFF0C}, {0xFF0D,0xFF0D,0xFF0D}, {0xFF0E,0xFF0E,0xFF0E}, {0xFF0F,0xFF0F,0xFF0F}, {0xFF10,0xFF10,0xFF10}, {0xFF11,0xFF11,0xFF11}, {0xFF12,0xFF12,0xFF12}, {0xFF13,0xFF13,0xFF13}, {0xFF14,0xFF14,0xFF14}, {0xFF15,0xFF15,0xFF15}, {0xFF16,0xFF16,0xFF16}, {0xFF17,0xFF17,0xFF17}, {0xFF18,0xFF18,0xFF18}, {0xFF19,0xFF19,0xFF19}, {0xFF1A,0xFF1A,0xFF1A}, {0xFF1B,0xFF1B,0xFF1B}, {0xFF1C,0xFF1C,0xFF1C}, {0xFF1D,0xFF1D,0xFF1D}, {0xFF1E,0xFF1E,0xFF1E}, {0xFF1F,0xFF1F,0xFF1F}, {0xFF20,0xFF20,0xFF20}, {0xFF21,0xFF41,0xFF21}, {0xFF22,0xFF42,0xFF22}, {0xFF23,0xFF43,0xFF23}, {0xFF24,0xFF44,0xFF24}, {0xFF25,0xFF45,0xFF25}, {0xFF26,0xFF46,0xFF26}, {0xFF27,0xFF47,0xFF27}, {0xFF28,0xFF48,0xFF28}, {0xFF29,0xFF49,0xFF29}, {0xFF2A,0xFF4A,0xFF2A}, {0xFF2B,0xFF4B,0xFF2B}, {0xFF2C,0xFF4C,0xFF2C}, {0xFF2D,0xFF4D,0xFF2D}, {0xFF2E,0xFF4E,0xFF2E}, {0xFF2F,0xFF4F,0xFF2F}, {0xFF30,0xFF50,0xFF30}, {0xFF31,0xFF51,0xFF31}, {0xFF32,0xFF52,0xFF32}, {0xFF33,0xFF53,0xFF33}, {0xFF34,0xFF54,0xFF34}, {0xFF35,0xFF55,0xFF35}, {0xFF36,0xFF56,0xFF36}, {0xFF37,0xFF57,0xFF37}, {0xFF38,0xFF58,0xFF38}, {0xFF39,0xFF59,0xFF39}, {0xFF3A,0xFF5A,0xFF3A}, {0xFF3B,0xFF3B,0xFF3B}, {0xFF3C,0xFF3C,0xFF3C}, {0xFF3D,0xFF3D,0xFF3D}, {0xFF3E,0xFF3E,0xFF3E}, {0xFF3F,0xFF3F,0xFF3F}, {0xFF40,0xFF40,0xFF40}, {0xFF21,0xFF41,0xFF21}, {0xFF22,0xFF42,0xFF22}, {0xFF23,0xFF43,0xFF23}, {0xFF24,0xFF44,0xFF24}, {0xFF25,0xFF45,0xFF25}, {0xFF26,0xFF46,0xFF26}, {0xFF27,0xFF47,0xFF27}, {0xFF28,0xFF48,0xFF28}, {0xFF29,0xFF49,0xFF29}, {0xFF2A,0xFF4A,0xFF2A}, {0xFF2B,0xFF4B,0xFF2B}, {0xFF2C,0xFF4C,0xFF2C}, {0xFF2D,0xFF4D,0xFF2D}, {0xFF2E,0xFF4E,0xFF2E}, {0xFF2F,0xFF4F,0xFF2F}, {0xFF30,0xFF50,0xFF30}, {0xFF31,0xFF51,0xFF31}, {0xFF32,0xFF52,0xFF32}, {0xFF33,0xFF53,0xFF33}, {0xFF34,0xFF54,0xFF34}, {0xFF35,0xFF55,0xFF35}, {0xFF36,0xFF56,0xFF36}, {0xFF37,0xFF57,0xFF37}, {0xFF38,0xFF58,0xFF38}, {0xFF39,0xFF59,0xFF39}, {0xFF3A,0xFF5A,0xFF3A}, {0xFF5B,0xFF5B,0xFF5B}, {0xFF5C,0xFF5C,0xFF5C}, {0xFF5D,0xFF5D,0xFF5D}, {0xFF5E,0xFF5E,0xFF5E}, {0xFF5F,0xFF5F,0xFF5F}, {0xFF60,0xFF60,0xFF60}, {0xFF61,0xFF61,0xFF61}, {0xFF62,0xFF62,0xFF62}, {0xFF63,0xFF63,0xFF63}, {0xFF64,0xFF64,0xFF64}, {0xFF65,0xFF65,0xFF65}, {0xFF66,0xFF66,0xFF66}, {0xFF67,0xFF67,0xFF67}, {0xFF68,0xFF68,0xFF68}, {0xFF69,0xFF69,0xFF69}, {0xFF6A,0xFF6A,0xFF6A}, {0xFF6B,0xFF6B,0xFF6B}, {0xFF6C,0xFF6C,0xFF6C}, {0xFF6D,0xFF6D,0xFF6D}, {0xFF6E,0xFF6E,0xFF6E}, {0xFF6F,0xFF6F,0xFF6F}, {0xFF70,0xFF70,0xFF70}, {0xFF71,0xFF71,0xFF71}, {0xFF72,0xFF72,0xFF72}, {0xFF73,0xFF73,0xFF73}, {0xFF74,0xFF74,0xFF74}, {0xFF75,0xFF75,0xFF75}, {0xFF76,0xFF76,0xFF76}, {0xFF77,0xFF77,0xFF77}, {0xFF78,0xFF78,0xFF78}, {0xFF79,0xFF79,0xFF79}, {0xFF7A,0xFF7A,0xFF7A}, {0xFF7B,0xFF7B,0xFF7B}, {0xFF7C,0xFF7C,0xFF7C}, {0xFF7D,0xFF7D,0xFF7D}, {0xFF7E,0xFF7E,0xFF7E}, {0xFF7F,0xFF7F,0xFF7F}, {0xFF80,0xFF80,0xFF80}, {0xFF81,0xFF81,0xFF81}, {0xFF82,0xFF82,0xFF82}, {0xFF83,0xFF83,0xFF83}, {0xFF84,0xFF84,0xFF84}, {0xFF85,0xFF85,0xFF85}, {0xFF86,0xFF86,0xFF86}, {0xFF87,0xFF87,0xFF87}, {0xFF88,0xFF88,0xFF88}, {0xFF89,0xFF89,0xFF89}, {0xFF8A,0xFF8A,0xFF8A}, {0xFF8B,0xFF8B,0xFF8B}, {0xFF8C,0xFF8C,0xFF8C}, {0xFF8D,0xFF8D,0xFF8D}, {0xFF8E,0xFF8E,0xFF8E}, {0xFF8F,0xFF8F,0xFF8F}, {0xFF90,0xFF90,0xFF90}, {0xFF91,0xFF91,0xFF91}, {0xFF92,0xFF92,0xFF92}, {0xFF93,0xFF93,0xFF93}, {0xFF94,0xFF94,0xFF94}, {0xFF95,0xFF95,0xFF95}, {0xFF96,0xFF96,0xFF96}, {0xFF97,0xFF97,0xFF97}, {0xFF98,0xFF98,0xFF98}, {0xFF99,0xFF99,0xFF99}, {0xFF9A,0xFF9A,0xFF9A}, {0xFF9B,0xFF9B,0xFF9B}, {0xFF9C,0xFF9C,0xFF9C}, {0xFF9D,0xFF9D,0xFF9D}, {0xFF9E,0xFF9E,0xFF9E}, {0xFF9F,0xFF9F,0xFF9F}, {0xFFA0,0xFFA0,0xFFA0}, {0xFFA1,0xFFA1,0xFFA1}, {0xFFA2,0xFFA2,0xFFA2}, {0xFFA3,0xFFA3,0xFFA3}, {0xFFA4,0xFFA4,0xFFA4}, {0xFFA5,0xFFA5,0xFFA5}, {0xFFA6,0xFFA6,0xFFA6}, {0xFFA7,0xFFA7,0xFFA7}, {0xFFA8,0xFFA8,0xFFA8}, {0xFFA9,0xFFA9,0xFFA9}, {0xFFAA,0xFFAA,0xFFAA}, {0xFFAB,0xFFAB,0xFFAB}, {0xFFAC,0xFFAC,0xFFAC}, {0xFFAD,0xFFAD,0xFFAD}, {0xFFAE,0xFFAE,0xFFAE}, {0xFFAF,0xFFAF,0xFFAF}, {0xFFB0,0xFFB0,0xFFB0}, {0xFFB1,0xFFB1,0xFFB1}, {0xFFB2,0xFFB2,0xFFB2}, {0xFFB3,0xFFB3,0xFFB3}, {0xFFB4,0xFFB4,0xFFB4}, {0xFFB5,0xFFB5,0xFFB5}, {0xFFB6,0xFFB6,0xFFB6}, {0xFFB7,0xFFB7,0xFFB7}, {0xFFB8,0xFFB8,0xFFB8}, {0xFFB9,0xFFB9,0xFFB9}, {0xFFBA,0xFFBA,0xFFBA}, {0xFFBB,0xFFBB,0xFFBB}, {0xFFBC,0xFFBC,0xFFBC}, {0xFFBD,0xFFBD,0xFFBD}, {0xFFBE,0xFFBE,0xFFBE}, {0xFFBF,0xFFBF,0xFFBF}, {0xFFC0,0xFFC0,0xFFC0}, {0xFFC1,0xFFC1,0xFFC1}, {0xFFC2,0xFFC2,0xFFC2}, {0xFFC3,0xFFC3,0xFFC3}, {0xFFC4,0xFFC4,0xFFC4}, {0xFFC5,0xFFC5,0xFFC5}, {0xFFC6,0xFFC6,0xFFC6}, {0xFFC7,0xFFC7,0xFFC7}, {0xFFC8,0xFFC8,0xFFC8}, {0xFFC9,0xFFC9,0xFFC9}, {0xFFCA,0xFFCA,0xFFCA}, {0xFFCB,0xFFCB,0xFFCB}, {0xFFCC,0xFFCC,0xFFCC}, {0xFFCD,0xFFCD,0xFFCD}, {0xFFCE,0xFFCE,0xFFCE}, {0xFFCF,0xFFCF,0xFFCF}, {0xFFD0,0xFFD0,0xFFD0}, {0xFFD1,0xFFD1,0xFFD1}, {0xFFD2,0xFFD2,0xFFD2}, {0xFFD3,0xFFD3,0xFFD3}, {0xFFD4,0xFFD4,0xFFD4}, {0xFFD5,0xFFD5,0xFFD5}, {0xFFD6,0xFFD6,0xFFD6}, {0xFFD7,0xFFD7,0xFFD7}, {0xFFD8,0xFFD8,0xFFD8}, {0xFFD9,0xFFD9,0xFFD9}, {0xFFDA,0xFFDA,0xFFDA}, {0xFFDB,0xFFDB,0xFFDB}, {0xFFDC,0xFFDC,0xFFDC}, {0xFFDD,0xFFDD,0xFFDD}, {0xFFDE,0xFFDE,0xFFDE}, {0xFFDF,0xFFDF,0xFFDF}, {0xFFE0,0xFFE0,0xFFE0}, {0xFFE1,0xFFE1,0xFFE1}, {0xFFE2,0xFFE2,0xFFE2}, {0xFFE3,0xFFE3,0xFFE3}, {0xFFE4,0xFFE4,0xFFE4}, {0xFFE5,0xFFE5,0xFFE5}, {0xFFE6,0xFFE6,0xFFE6}, {0xFFE7,0xFFE7,0xFFE7}, {0xFFE8,0xFFE8,0xFFE8}, {0xFFE9,0xFFE9,0xFFE9}, {0xFFEA,0xFFEA,0xFFEA}, {0xFFEB,0xFFEB,0xFFEB}, {0xFFEC,0xFFEC,0xFFEC}, {0xFFED,0xFFED,0xFFED}, {0xFFEE,0xFFEE,0xFFEE}, {0xFFEF,0xFFEF,0xFFEF}, {0xFFF0,0xFFF0,0xFFF0}, {0xFFF1,0xFFF1,0xFFF1}, {0xFFF2,0xFFF2,0xFFF2}, {0xFFF3,0xFFF3,0xFFF3}, {0xFFF4,0xFFF4,0xFFF4}, {0xFFF5,0xFFF5,0xFFF5}, {0xFFF6,0xFFF6,0xFFF6}, {0xFFF7,0xFFF7,0xFFF7}, {0xFFF8,0xFFF8,0xFFF8}, {0xFFF9,0xFFF9,0xFFF9}, {0xFFFA,0xFFFA,0xFFFA}, {0xFFFB,0xFFFB,0xFFFB}, {0xFFFC,0xFFFC,0xFFFC}, {0xFFFD,0xFFFD,0xFFFD}, {0xFFFE,0xFFFE,0xFFFE}, {0xFFFF,0xFFFF,0xFFFF} }; MY_UNICASE_INFO *my_unicase_default[256]={ plane00, plane01, plane02, plane03, plane04, plane05, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, plane1E, plane1F, NULL, plane21, NULL, NULL, plane24, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, planeFF }; #define MY_CS_ILSEQ 0 /* Wrong by sequence: wb_wc */ #define MY_CS_TOOSMALL -101 /* Need at least one byte: wc_mb and mb_wc */ #define MY_CS_TOOSMALL2 -102 /* Need at least two bytes: wc_mb and mb_wc */ #define MY_CS_TOOSMALL3 -103 /* Need at least three bytes: wc_mb and mb_wc */ #define MY_CS_TOOSMALL4 -104 /* Need at least 4 bytes: wc_mb and mb_wc */ #define MY_CS_TOOSMALL5 -105 /* Need at least 5 bytes: wc_mb and mb_wc */ #define MY_CS_TOOSMALL6 -106 /* Need at least 6 bytes: wc_mb and mb_wc */ static int my_utf8_uni(unsigned long * pwc, const unsigned char *s, const unsigned char *e) { unsigned char c; if (s >= e) return MY_CS_TOOSMALL; c= s[0]; if (c < 0x80) { *pwc = c; return 1; } else if (c < 0xc2) return MY_CS_ILSEQ; else if (c < 0xe0) { if (s+2 > e) /* We need 2 characters */ return MY_CS_TOOSMALL2; if (!((s[1] ^ 0x80) < 0x40)) return MY_CS_ILSEQ; *pwc = ((unsigned long) (c & 0x1f) << 6) | (unsigned long) (s[1] ^ 0x80); return 2; } else if (c < 0xf0) { if (s+3 > e) /* We need 3 characters */ return MY_CS_TOOSMALL3; if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (c >= 0xe1 || s[1] >= 0xa0))) return MY_CS_ILSEQ; *pwc = ((unsigned long) (c & 0x0f) << 12) | ((unsigned long) (s[1] ^ 0x80) << 6) | (unsigned long) (s[2] ^ 0x80); return 3; } #ifdef UNICODE_32BIT else if (c < 0xf8 && sizeof(my_wc_t)*8 >= 32) { if (s+4 > e) /* We need 4 characters */ return MY_CS_TOOSMALL4; if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (c >= 0xf1 || s[1] >= 0x90))) return MY_CS_ILSEQ; *pwc = ((unsigned long) (c & 0x07) << 18) | ((unsigned long) (s[1] ^ 0x80) << 12) | ((unsigned long) (s[2] ^ 0x80) << 6) | (unsigned long) (s[3] ^ 0x80); return 4; } else if (c < 0xfc && sizeof(my_wc_t)*8 >= 32) { if (s+5 >e) /* We need 5 characters */ return MY_CS_TOOSMALL5; if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 && (c >= 0xf9 || s[1] >= 0x88))) return MY_CS_ILSEQ; *pwc = ((unsigned long) (c & 0x03) << 24) | ((unsigned long) (s[1] ^ 0x80) << 18) | ((unsigned long) (s[2] ^ 0x80) << 12) | ((unsigned long) (s[3] ^ 0x80) << 6) | (unsigned long) (s[4] ^ 0x80); return 5; } else if (c < 0xfe && sizeof(my_wc_t)*8 >= 32) { if ( s+6 >e ) /* We need 6 characters */ return MY_CS_TOOSMALL6; if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 && (s[5] ^ 0x80) < 0x40 && (c >= 0xfd || s[1] >= 0x84))) return MY_CS_ILSEQ; *pwc = ((unsigned long) (c & 0x01) << 30) | ((unsigned long) (s[1] ^ 0x80) << 24) | ((unsigned long) (s[2] ^ 0x80) << 18) | ((unsigned long) (s[3] ^ 0x80) << 12) | ((unsigned long) (s[4] ^ 0x80) << 6) | (unsigned long) (s[5] ^ 0x80); return 6; } #endif return MY_CS_ILSEQ; } #define MY_CS_ILUNI 0 /* Cannot encode Unicode to charset: wc_mb */ #define MY_CS_TOOSMALLN(n) (-100-(n)) static int my_uni_utf8(unsigned long wc, unsigned char *r, unsigned char *e) { int count; if (r >= e) return MY_CS_TOOSMALL; if (wc < 0x80) count = 1; else if (wc < 0x800) count = 2; else if (wc < 0x10000) count = 3; #ifdef UNICODE_32BIT else if (wc < 0x200000) count = 4; else if (wc < 0x4000000) count = 5; else if (wc <= 0x7fffffff) count = 6; #endif else return MY_CS_ILUNI; /* e is a character after the string r, not the last character of it. Because of it (r+count > e), not (r+count-1 >e ) */ if ( r+count > e ) return MY_CS_TOOSMALLN(count); switch (count) { /* Fall through all cases!!! */ #ifdef UNICODE_32BIT case 6: r[5] = (unsigned char) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x4000000; case 5: r[4] = (unsigned char) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x200000; case 4: r[3] = (unsigned char) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x10000; #endif case 3: r[2] = (unsigned char) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x800; case 2: r[1] = (unsigned char) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0xc0; case 1: r[0] = (unsigned char) wc; } return count; } static int cppmysql_caseup_utf8(const char * src, size_t srclen, char *dst, size_t dstlen) { unsigned long wc; int srcres, dstres; const char *srcend = src + srclen; char *dstend = dst + dstlen, *dst0 = dst; MY_UNICASE_INFO **uni_plane= my_unicase_default; while ((src < srcend) && (srcres= my_utf8_uni(&wc, (unsigned char *) src, (unsigned char*) srcend)) > 0) { int plane = (wc>>8) & 0xFF; wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc; if ((dstres = my_uni_utf8(wc, (unsigned char*) dst, (unsigned char*) dstend)) <= 0) { break; } src += srcres; dst += dstres; } return static_cast((dst - dst0)); } char * utf8_strup(const char * const src, size_t srclen) { size_t dstlen; char * dst; if (srclen == 0) { srclen = strlen(src); } dst = new char[(dstlen = srclen * 4) + 1]; if (!dst) { return NULL; } dst[cppmysql_caseup_utf8(src, srclen, dst, dstlen)] = '\0'; return dst; } /* HPUX has some problems with long double : http://docs.hp.com/en/B3782-90716/ch02s02.html strtold() has implementations that return struct long_double, 128bit one, which contains four 32bit words. Fix described : -------- union { long_double l_d; long double ld; } u; // convert str to a long_double; store return val in union //(Putting value into union enables converted value to be // accessed as an ANSI C long double) u.l_d = strtold( (const char *)str, (char **)NULL); -------- reinterpret_cast doesn't work :( */ long double strtold(const char *nptr, char **endptr) { /* * Experienced odd compilation errors on one of windows build hosts - * cmake reported there is strold function. Since double and long double on windows * are of the same size - we are using strtod on those platforms regardless * to the HAVE_FUNCTION_STRTOLD value */ #ifdef _WIN32 return ::strtod(nptr, endptr); #else # ifndef HAVE_FUNCTION_STRTOLD return ::strtod(nptr, endptr); # else # if defined(__hpux) && defined(_LONG_DOUBLE) union { long_double l_d; long double ld; } u; u.l_d = ::strtold( nptr, endptr); return u.ld; # else return ::strtold(nptr, endptr); # endif # endif #endif } } /* namespace util */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_util.h000644 015771 000012 00000014676 12645244436 021647 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_UTIL_H_ #define _MYSQL_UTIL_H_ #include "nativeapi/mysql_private_iface.h" #include #include #include #ifndef UL64 #ifdef _WIN32 #define UL64(x) x##ui64 #else #define UL64(x) x##ULL #endif #endif #ifndef L64 #ifdef _WIN32 #define L64(x) x##i64 #else #define L64(x) x##LL #endif #endif #define NULLCSTR static_cast(0) #ifndef _WIN32 # ifndef HAVE_FUNCTION_STRTOLL # define strtoll(__a, __b, __c) static_cast(sql::mysql::util::strtold((__a), NULL)) # define HAVE_FUNCTION_STRTOLL 1 # endif # ifndef HAVE_FUNCTION_STRTOULL # define strtoull(__a, __b, __c) static_cast(sql::mysql::util::strtold((__a), NULL)) # define HAVE_FUNCTION_STRTOULL 1 # endif #else # ifndef strtoll # define strtoll(x, e, b) _strtoi64((x), (e), (b)) # endif # ifndef strtoull # define strtoull(x, e, b) _strtoui64((x), (e), (b)) # endif #endif // _WIN32 #define bit_uint1korr(A) (*(((uint8_t*)(A)))) #define bit_uint2korr(A) ((uint16_t) (((uint16_t) (((unsigned char*) (A))[1])) +\ ((uint16_t) (((unsigned char*) (A))[0]) << 8))) #define bit_uint3korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[2])) +\ (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[0])) << 16))) #define bit_uint4korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[3])) +\ (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\ (((uint32_t) (((unsigned char*) (A))[0])) << 24))) #define bit_uint5korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[4])) +\ (((uint32_t) (((unsigned char*) (A))[3])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[2])) << 16) +\ (((uint32_t) (((unsigned char*) (A))[1])) << 24)) +\ (((uint64_t) (((unsigned char*) (A))[0])) << 32)) #define bit_uint6korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[5])) +\ (((uint32_t) (((unsigned char*) (A))[4])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[3])) << 16) +\ (((uint32_t) (((unsigned char*) (A))[2])) << 24)) +\ (((uint64_t) (((uint32_t) (((unsigned char*) (A))[1])) +\ (((uint32_t) (((unsigned char*) (A))[0]) << 8)))) <<\ 32)) #define bit_uint7korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[6])) +\ (((uint32_t) (((unsigned char*) (A))[5])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[4])) << 16) +\ (((uint32_t) (((unsigned char*) (A))[3])) << 24)) +\ (((uint64_t) (((uint32_t) (((unsigned char*) (A))[2])) +\ (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[0])) << 16))) <<\ 32)) #define bit_uint8korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[7])) +\ (((uint32_t) (((unsigned char*) (A))[6])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[5])) << 16) +\ (((uint32_t) (((unsigned char*) (A))[4])) << 24)) +\ (((uint64_t) (((uint32_t) (((unsigned char*) (A))[3])) +\ (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\ (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\ (((uint32_t) (((unsigned char*) (A))[0])) << 24))) <<\ 32)) namespace sql { namespace mysql { class MySQL_DebugLogger; namespace NativeAPI { class NativeConnectionWrapper; class NativeStatementWrapper; } /* namespace NativeAPI */ namespace util { extern const char *EMPTYSTR; extern const char *LOCALHOST; void throwSQLException(::sql::mysql::NativeAPI::NativeConnectionWrapper & proxy); void throwSQLException(::sql::mysql::NativeAPI::NativeStatementWrapper & proxy); int mysql_string_type_to_datatype(const sql::SQLString & name); int mysql_type_to_datatype(const MYSQL_FIELD * const field); const char * mysql_type_to_string(const MYSQL_FIELD * const field, boost::shared_ptr< sql::mysql::MySQL_DebugLogger > & l); char * utf8_strup(const char * const src, size_t srclen); long double strtold(const char *nptr, char **endptr); typedef struct st_our_charset { unsigned int nr; const char *name; const char *collation; unsigned int char_minlen; unsigned int char_maxlen; const char *comment; unsigned int (*mb_charlen)(unsigned int c); unsigned int (*mb_valid)(const char *start, const char *end); } OUR_CHARSET; const OUR_CHARSET * find_charset(unsigned int charsetnr); } /* namespace util */ } /* namespace mysql */ } /* namespace sql */ #endif /* _MYSQL_UTIL_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_warning.cpp000644 015771 000012 00000013262 12645244436 022660 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_warning.h" #include #include #include #include namespace sql { namespace mysql { MySQL_Warning::MySQL_Warning(const sql::SQLString& reason, const sql::SQLString& SQLState, int vendorCode) :sql_state(SQLState), errNo(vendorCode), descr(reason), next(NULL) { } MySQL_Warning::MySQL_Warning(const sql::SQLString& reason, const sql::SQLString& SQLState) :sql_state (SQLState), errNo(0), descr(reason), next(NULL) { } MySQL_Warning::MySQL_Warning(const sql::SQLString& reason) : sql_state ("HY000"), errNo(0), descr(reason), next(NULL) { } MySQL_Warning::MySQL_Warning() : sql_state ("HY000"), errNo(0), next(NULL) {} const sql::SQLString & MySQL_Warning::getMessage() const { return descr; } const sql::SQLString & MySQL_Warning::getSQLState() const { return sql_state; } int MySQL_Warning::getErrorCode() const { return errNo; } const SQLWarning * MySQL_Warning::getNextWarning() const { return next.get(); } MySQL_Warning::~MySQL_Warning() { } /* We don't really want it to be called, but we need to implement it */ void MySQL_Warning::setNextWarning(const SQLWarning * _next) { if (_next) { next.reset(new MySQL_Warning(*_next)); } else { next.reset(); } } void MySQL_Warning::setNextWarning(MySQL_Warning * _next) { next.reset(_next); } MySQL_Warning::MySQL_Warning(const MySQL_Warning& w) : sql_state(w.sql_state), errNo(w.errNo), descr(w.descr), next(w.next.get()) {} MySQL_Warning::MySQL_Warning(const ::sql::SQLWarning & w) : sql_state (w.getSQLState()), errNo (w.getErrorCode()), descr (w.getMessage()) { setNextWarning(w.getNextWarning()); } /* * */ const sql::SQLString & errCode2SqlState(int32_t errCode, sql::SQLString & state) { switch (errCode) { case 1037: case 1038: state = "HY001"; break; case 1040: state = "08004"; break; case 1042: case 1043: case 1047: case 1053: state = "08S01"; break; case 1044: case 1049: case 1055: case 1056: case 1057: case 1059: case 1061: case 1063: case 1064: case 1065: case 1066: case 1067: case 1068: case 1069: case 1070: case 1071: case 1072: case 1073: case 1074: case 1075: state = "42000"; break; case 1045: state = "28000"; break; case 1046: state = "3D000"; break; case 1048: case 1052: case 1062: state = "23000"; break; case 1050: state = "42501"; break; case 1051: state = "42S02"; break; case 1054: state = "42S22"; break; case 1058: state = "21S01"; break; case 1060: state = "42S21"; break; case 1264: state = "22003"; break; case 1000: case 1001: case 1002: case 1003: case 1004: case 1005: case 1006: case 1007: case 1008: case 1009: case 1010: case 1011: case 1012: case 1013: case 1014: case 1015: case 1016: case 1017: case 1018: case 1019: case 1020: case 1021: case 1022: case 1023: case 1024: case 1025: case 1026: case 1027: case 1028: case 1029: case 1030: case 1031: case 1032: case 1033: case 1034: case 1035: case 1036: case 1076: state = "HY000"; break; default: state = ""; break; } return state; } MySQL_Warning * loadMysqlWarnings(sql::Connection * connection, unsigned int warningsCount) { MySQL_Warning * first = NULL, * current = NULL; SQLString state; if (warningsCount >0 && connection != NULL) { boost::scoped_ptr< sql::Statement > stmt(connection->createStatement()); boost::scoped_ptr< sql::ResultSet > rset(stmt->executeQuery("SHOW WARNINGS")); while (rset->next()) { // 1 - Level // 2 - Code // 3 - Message int32_t errCode = rset->getInt(2); if (current == NULL) { first = current = new MySQL_Warning(sql::SQLString(rset->getString(3)), errCode2SqlState(errCode, state), errCode); } else { MySQL_Warning * tmp= new MySQL_Warning(sql::SQLString(rset->getString(3)), errCode2SqlState(errCode, state), errCode); current->setNextWarning(tmp); current= tmp; } } } return first; } } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/mysql_warning.h000644 015771 000012 00000004746 12645244436 022334 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __MYSQL_WARNING_H_ #define __MYSQL_WARNING_H_ #include "mysql_connection.h" #include #include #include namespace sql { namespace mysql { class MySQL_Warning : public ::sql::SQLWarning { private: const sql::SQLString sql_state; const int errNo; const sql::SQLString descr; boost::scoped_ptr next; public: MySQL_Warning(const sql::SQLString& reason, const sql::SQLString& SQLState, int vendorCode); MySQL_Warning(const sql::SQLString& reason, const sql::SQLString& SQLState); MySQL_Warning(const sql::SQLString& reason); MySQL_Warning(); const sql::SQLString & getMessage() const; const sql::SQLString & getSQLState() const; int getErrorCode() const; const SQLWarning * getNextWarning() const; ~MySQL_Warning(); private: /* We don't really want it to be called, but we need to implement it */ void setNextWarning(const SQLWarning * _next); public: void setNextWarning(MySQL_Warning * _next); private: MySQL_Warning(const MySQL_Warning& w); MySQL_Warning(const ::sql::SQLWarning & w); const MySQL_Warning & operator = (const MySQL_Warning & rhs); }; const sql::SQLString & errCode2SqlState(int32_t errCode, ::sql::SQLString & state); MySQL_Warning * loadMysqlWarnings( sql::Connection * connection, unsigned int warningsCount=0); } /* namespace mysql */ } /* namespace sql */ #endif mysql-connector-c++-1.1.7/driver/nativeapi/binding_config.h.cm000644 015771 000012 00000002537 12645244436 024753 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPL as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #cmakedefine HAVE_DLFCN_H 1 #cmakedefine MYSQLCLIENT_STATIC_BINDING 1 /* #if !defined(_WIN32) && !defined(HAVE_DLFCN_H) && !defined(MYSQLCLIENT_STATIC_BINDING) # define MYSQLCLIENT_STATIC_BINDING 1 #endif #ifdef HAVE_DLFCN_H #include #endif */ mysql-connector-c++-1.1.7/driver/nativeapi/libmysql_dynamic_proxy.cpp000644 015771 000012 00000054662 12645244436 026560 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libmysql_dynamic_proxy.h" #include namespace sql { namespace mysql { namespace NativeAPI { #if defined(_WIN32) static const char * const baseName = "libmysql.dll"; #elif defined(__APPLE__) static const char * const baseName = "libmysqlclient_r.dylib"; #elif defined(__hpux) && defined(__hppa) static const char * const baseName = "libmysqlclient_r.sl"; #else static const char * const baseName = "libmysqlclient_r.so"; #endif template FunctionType symbol_safe_cast(::sql::mysql::util::SymbolHandle raw) { return *reinterpret_cast< FunctionType* >(&raw); } /* {{{ LibmysqlDynamicProxy::LibmysqlDynamicProxy() */ LibmysqlDynamicProxy::LibmysqlDynamicProxy() : LibraryLoader(baseName) { init_loader(); } /* }}} */ /* {{{ LibmysqlDynamicProxy::LibmysqlDynamicProxy() */ LibmysqlDynamicProxy::LibmysqlDynamicProxy(const SQLString & path2libFile) : LibraryLoader(path2libFile.length() > 0 ? path2libFile.asStdString() : baseName) { init_loader(); } /* }}} */ /* {{{ LibmysqlDynamicProxy::LibmysqlDynamicProxy() */ LibmysqlDynamicProxy::LibmysqlDynamicProxy(const SQLString & dir2look, const SQLString & libFileName) : LibraryLoader(dir2look.asStdString(), libFileName.length() > 0 ? libFileName.asStdString() : baseName) { init_loader(); } /* }}} */ /* {{{ LibmysqlDynamicProxy::~LibmysqlDynamicProxy() */ LibmysqlDynamicProxy::~LibmysqlDynamicProxy() { ptr2mysql_library_end endProc = symbol_safe_cast(GetProcAddr("mysql_server_end")); if (endProc != NULL) { (*endProc)(); } } /* }}} */ /* {{{ LibmysqlDynamicProxy::init_loader() */ void LibmysqlDynamicProxy::init_loader() { ptr2mysql_library_init initProc = symbol_safe_cast(GetProcAddr("mysql_server_init")); if (initProc != NULL) { (*initProc)(0, NULL, NULL); } else { throw ::sql::InvalidArgumentException("Loaded library doesn't contain mysql_library_init"); } } /* }}} */ /************************************************************************/ /* MySQL C-API calls wrappers */ /************************************************************************/ /* {{{ LibmysqlDynamicProxy::affected_rows() */ my_ulonglong LibmysqlDynamicProxy::affected_rows(MYSQL * mysql) { ptr2mysql_affected_rows ptr2_affected_rows = symbol_safe_cast(GetProcAddr("mysql_affected_rows")); return (*ptr2_affected_rows)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::autocommit() */ my_bool LibmysqlDynamicProxy::autocommit(MYSQL * mysql, my_bool mode) { ptr2mysql_autocommit ptr2_autocommit = symbol_safe_cast(GetProcAddr("mysql_autocommit")); return (*ptr2_autocommit)(mysql, mode); } /* }}} */ /* {{{ LibmysqlDynamicProxy::close() */ void LibmysqlDynamicProxy::close(MYSQL * mysql) { ptr2mysql_close ptr2_close = symbol_safe_cast(GetProcAddr("mysql_close")); return (*ptr2_close)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::commit() */ my_bool LibmysqlDynamicProxy::commit(MYSQL * mysql) { ptr2mysql_commit ptr2_commit = symbol_safe_cast(GetProcAddr("mysql_commit")); return (*ptr2_commit)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::data_seek() */ void LibmysqlDynamicProxy::data_seek(MYSQL_RES * result, my_ulonglong offset) { ptr2mysql_data_seek ptr2_data_seek = symbol_safe_cast(GetProcAddr("mysql_data_seek")); return (*ptr2_data_seek)(result, offset); } /* }}} */ /* {{{ LibmysqlDynamicProxy::debug() */ void LibmysqlDynamicProxy::debug(const char * debug) { ptr2mysql_debug ptr2_debug = symbol_safe_cast(GetProcAddr("mysql_debug")); return (*ptr2_debug)(debug); } /* }}} */ /* {{{ LibmysqlDynamicProxy::errno() */ unsigned int LibmysqlDynamicProxy::mysql_errno(MYSQL * mysql) { ptr2mysql_errno ptr2_errno = symbol_safe_cast(GetProcAddr("mysql_errno")); return (*ptr2_errno)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::error() */ const char * LibmysqlDynamicProxy::error(MYSQL * mysql) { ptr2mysql_error ptr2_error = symbol_safe_cast(GetProcAddr("mysql_error")); return (*ptr2_error)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::fetch_field() */ MYSQL_FIELD * LibmysqlDynamicProxy::fetch_field(MYSQL_RES * result) { ptr2mysql_fetch_field ptr2_fetch_field = symbol_safe_cast(GetProcAddr("mysql_fetch_field")); return (*ptr2_fetch_field)(result); } /* }}} */ /* {{{ LibmysqlDynamicProxy::fetch_field_direct() */ MYSQL_FIELD * LibmysqlDynamicProxy::fetch_field_direct(MYSQL_RES * result, unsigned int fieldnr) { ptr2mysql_fetch_field_direct ptr2fetchFieldDirect= symbol_safe_cast(GetProcAddr("mysql_fetch_field_direct")); return (*ptr2fetchFieldDirect)(result, fieldnr); } /* }}} */ /* {{{ LibmysqlDynamicProxy::fetch_lengths() */ unsigned long * LibmysqlDynamicProxy::fetch_lengths(MYSQL_RES * result) { ptr2mysql_fetch_lengths ptr2_fetch_lengths = symbol_safe_cast(GetProcAddr("mysql_fetch_lengths")); return (*ptr2_fetch_lengths)(result); } /* }}} */ /* {{{ LibmysqlDynamicProxy::fetch_row() */ MYSQL_ROW LibmysqlDynamicProxy::fetch_row(MYSQL_RES * result) { ptr2mysql_fetch_row ptr2_fetch_row = symbol_safe_cast(GetProcAddr("mysql_fetch_row")); return (*ptr2_fetch_row)(result); } /* }}} */ /* {{{ LibmysqlDynamicProxy::field_count() */ unsigned int LibmysqlDynamicProxy::field_count(MYSQL * mysql) { ptr2mysql_field_count ptr2_field_count = symbol_safe_cast(GetProcAddr("mysql_field_count")); return (*ptr2_field_count)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::free_result() */ void LibmysqlDynamicProxy::free_result(MYSQL_RES * result) { ptr2mysql_free_result ptr2_free_result = symbol_safe_cast(GetProcAddr("mysql_free_result")); return (*ptr2_free_result)(result); } /* }}} */ /* {{{ LibmysqlDynamicProxy::get_client_version() */ unsigned long LibmysqlDynamicProxy::get_client_version() { ptr2mysql_get_client_version ptr2_get_client_version= (ptr2mysql_get_client_version)(GetProcAddr("mysql_get_client_version")); return (*ptr2_get_client_version)(); } /* }}} */ /* {{{ LibmysqlDynamicProxy::get_server_info() */ const char * LibmysqlDynamicProxy::get_server_info(MYSQL * mysql) { ptr2mysql_get_server_info ptr2_get_server_info = symbol_safe_cast(GetProcAddr("mysql_get_server_info")); return (*ptr2_get_server_info)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::get_server_version() */ unsigned long LibmysqlDynamicProxy::get_server_version(MYSQL * mysql) { ptr2mysql_get_server_version ptr2_get_server_version = symbol_safe_cast(GetProcAddr("mysql_get_server_version")); return (*ptr2_get_server_version)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::get_character_set_info() */ void LibmysqlDynamicProxy::get_character_set_info(MYSQL * mysql, void *cs) { ptr2mysql_get_character_set_info ptr2_get_character_set_info = symbol_safe_cast(GetProcAddr("mysql_get_character_set_info")); return (*ptr2_get_character_set_info)(mysql, static_cast(cs)); } /* }}} */ /* {{{ LibmysqlDynamicProxy::info() */ const char * LibmysqlDynamicProxy::info(MYSQL * mysql) { ptr2mysql_info ptr2_info = symbol_safe_cast(GetProcAddr("mysql_info")); return (*ptr2_info)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::init() */ MYSQL * LibmysqlDynamicProxy::init(MYSQL * mysql) { ptr2mysql_init ptr2init = symbol_safe_cast(GetProcAddr("mysql_init")); return (*ptr2init)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::library_init() */ int LibmysqlDynamicProxy::library_init(int argc,char **argv,char **groups) { ptr2mysql_library_init ptr2_library_init = symbol_safe_cast(GetProcAddr("mysql_library_init")); return (*ptr2_library_init)(argc, argv, groups); } /* }}} */ /* {{{ LibmysqlDynamicProxy::library_end() */ void LibmysqlDynamicProxy::library_end() { ptr2mysql_library_end ptr2_library_end = symbol_safe_cast(GetProcAddr("mysql_library_end")); return (*ptr2_library_end)(); } /* }}} */ /* {{{ LibmysqlDynamicProxy::more_results() */ my_bool LibmysqlDynamicProxy::more_results(MYSQL * mysql) { ptr2mysql_more_results ptr2_more_results = symbol_safe_cast(GetProcAddr("mysql_more_results")); return (*ptr2_more_results)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::next_result() */ int LibmysqlDynamicProxy::next_result(MYSQL * mysql) { ptr2mysql_next_result ptr2_next_result = symbol_safe_cast(GetProcAddr("mysql_next_result")); return (*ptr2_next_result)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::num_fields() */ unsigned int LibmysqlDynamicProxy::num_fields(MYSQL_RES * result) { ptr2mysql_num_fields ptr2_num_fields = symbol_safe_cast(GetProcAddr("mysql_num_fields")); return (*ptr2_num_fields)(result); } /* }}} */ /* {{{ LibmysqlDynamicProxy::num_rows() */ my_ulonglong LibmysqlDynamicProxy::num_rows(MYSQL_RES * result) { ptr2mysql_num_rows ptr2_num_rows = symbol_safe_cast(GetProcAddr("mysql_num_rows")); return (*ptr2_num_rows)(result); } /* }}} */ /* {{{ LibmysqlDynamicProxy::options() */ int LibmysqlDynamicProxy::options(MYSQL * mysql, enum mysql_option option, const void *arg) { ptr2mysql_options ptr2_options = symbol_safe_cast(GetProcAddr("mysql_options")); if ((*ptr2_options)(mysql, option, arg)) { throw sql::InvalidArgumentException("Unsupported option provided to mysql_options()"); } else { return 0; } } /* }}} */ /* {{{ LibmysqlDynamicProxy::options() */ int LibmysqlDynamicProxy::options(MYSQL * mysql, enum mysql_option option, const void *arg1, const void *arg2) { ptr2mysql_options4 ptr2_options = symbol_safe_cast(GetProcAddr("mysql_options4")); if (ptr2_options != NULL) { if (((*ptr2_options)(mysql, option, arg1, arg2))) { throw sql::InvalidArgumentException("Unsupported option provided to mysql_options4()"); } else { return 0; } } else { throw ::sql::MethodNotImplementedException("::mysql_options4()"); } } /* }}} */ /* {{{ LibmysqlDynamicProxy::get_option() */ int LibmysqlDynamicProxy::get_option(MYSQL * mysql, enum mysql_option option, const void *arg) { ptr2mysql_get_option ptr2_get_option = symbol_safe_cast(GetProcAddr("mysql_get_option")); if (ptr2_get_option != NULL) { if (((*ptr2_get_option)(mysql, option, arg))) { throw sql::InvalidArgumentException("Unsupported option provided to mysql_get_option()"); } else { return 0; } } else { throw ::sql::MethodNotImplementedException("::mysql_get_option()"); } } /* }}} */ /* {{{ LibmysqlDynamicProxy::query() */ int LibmysqlDynamicProxy::query(MYSQL * mysql, const char *stmt_str) { ptr2mysql_query ptr2_query = symbol_safe_cast(GetProcAddr("mysql_query")); return (*ptr2_query)(mysql, stmt_str); } /* }}} */ /* {{{ LibmysqlDynamicProxy::ping() */ int LibmysqlDynamicProxy::ping(MYSQL * mysql) { ptr2mysql_ping ptr2_ping = symbol_safe_cast(GetProcAddr("mysql_ping")); return (*ptr2_ping)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::real_connect() */ MYSQL * LibmysqlDynamicProxy::real_connect(MYSQL * mysql, const char * host, const char * user, const char * passwd, const char * db, unsigned int port, const char * unix_socket, unsigned long client_flag) { ptr2mysql_real_connect ptr2_real_connect= symbol_safe_cast(GetProcAddr("mysql_real_connect")); return (*ptr2_real_connect)(mysql, host, user, passwd, db, port, unix_socket, client_flag); } /* }}} */ /* {{{ LibmysqlDynamicProxy::real_escape_string() */ unsigned long LibmysqlDynamicProxy::real_escape_string(MYSQL * mysql, char * to, const char * from, unsigned long length) { ptr2mysql_real_escape_string ptr2_realescapestring = symbol_safe_cast(GetProcAddr("mysql_real_escape_string")); return (*ptr2_realescapestring)(mysql, to, from, length); } /* }}} */ /* {{{ LibmysqlDynamicProxy::real_query() */ int LibmysqlDynamicProxy::real_query(MYSQL *mysql,const char *stmt_str, unsigned long len) { ptr2mysql_real_query ptr2_real_query = symbol_safe_cast(GetProcAddr("mysql_real_query")); return (*ptr2_real_query)(mysql, stmt_str, len); } /* }}} */ /* {{{ LibmysqlDynamicProxy::rollback() */ my_bool LibmysqlDynamicProxy::rollback(MYSQL * mysql) { ptr2mysql_rollback ptr2_rollback = symbol_safe_cast(GetProcAddr("mysql_rollback")); return (*ptr2_rollback)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::sqlstate() */ const char * LibmysqlDynamicProxy::sqlstate(MYSQL * mysql) { ptr2mysql_sqlstate ptr2_sqlstate = symbol_safe_cast(GetProcAddr("mysql_sqlstate")); return (*ptr2_sqlstate)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::ssl_set() */ my_bool LibmysqlDynamicProxy::ssl_set(MYSQL * mysql, const char * key, const char * cert, const char * ca, const char * capath, const char * cipher) { ptr2mysql_ssl_set ptr2_ssl_set = symbol_safe_cast(GetProcAddr("mysql_ssl_set")); return (*ptr2_ssl_set)(mysql, key, cert, ca, capath, cipher); } /* }}} */ /* {{{ LibmysqlDynamicProxy::store_result() */ MYSQL_RES * LibmysqlDynamicProxy::store_result(MYSQL * mysql) { ptr2mysql_store_result ptr2_store_result = symbol_safe_cast(GetProcAddr("mysql_store_result")); return (*ptr2_store_result)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::use_result() */ MYSQL_RES * LibmysqlDynamicProxy::use_result(MYSQL * mysql) { ptr2mysql_use_result ptr2_use_result = symbol_safe_cast(GetProcAddr("mysql_use_result")); return (*ptr2_use_result)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::warning_count() */ unsigned int LibmysqlDynamicProxy::warning_count(MYSQL * mysql) { ptr2mysql_warning_count ptr2_warning_count= symbol_safe_cast(GetProcAddr("mysql_warning_count")); return (*ptr2_warning_count)(mysql); } /* }}} */ /* Prepared Statement mysql_stmt_* functions */ /* {{{ LibmysqlDynamicProxy::stmt_affected_rows() */ my_ulonglong LibmysqlDynamicProxy::stmt_affected_rows(MYSQL_STMT *stmt) { ptr2mysql_stmt_affected_rows ptr2_stmt_affected_rows = symbol_safe_cast(GetProcAddr("mysql_stmt_affected_rows")); return (*ptr2_stmt_affected_rows)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_attr_set() */ my_bool LibmysqlDynamicProxy::stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type option, const void * arg) { ptr2mysql_stmt_attr_set ptr2_stmt_attr_set = symbol_safe_cast(GetProcAddr("mysql_stmt_attr_set")); return (*ptr2_stmt_attr_set)(stmt, option, arg); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_bind_param() */ my_bool LibmysqlDynamicProxy::stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bind) { ptr2mysql_stmt_bind_param ptr2_stmt_bind_param = symbol_safe_cast(GetProcAddr("mysql_stmt_bind_param")); return (*ptr2_stmt_bind_param)(stmt, bind); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_bind_result() */ my_bool LibmysqlDynamicProxy::stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bind) { ptr2mysql_stmt_bind_result ptr2_stmt_bind_result = symbol_safe_cast(GetProcAddr("mysql_stmt_bind_result")); return (*ptr2_stmt_bind_result)(stmt, bind); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_close() */ my_bool LibmysqlDynamicProxy::stmt_close(MYSQL_STMT * stmt) { ptr2mysql_stmt_close ptr2_stmt_close = symbol_safe_cast(GetProcAddr("mysql_stmt_close")); return (*ptr2_stmt_close)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_data_seek() */ void LibmysqlDynamicProxy::stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong row_nr) { ptr2mysql_stmt_data_seek ptr2_stmt_data_seek = symbol_safe_cast(GetProcAddr("mysql_stmt_data_seek")); return (*ptr2_stmt_data_seek)(stmt, row_nr); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_errno() */ unsigned int LibmysqlDynamicProxy::stmt_errno(MYSQL_STMT * stmt) { ptr2mysql_stmt_errno ptr2_stmt_errno = symbol_safe_cast(GetProcAddr("mysql_stmt_errno")); return (*ptr2_stmt_errno)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_error() */ const char * LibmysqlDynamicProxy::stmt_error(MYSQL_STMT * stmt) { ptr2mysql_stmt_error ptr2_stmt_error = symbol_safe_cast(GetProcAddr("mysql_stmt_error")); return (*ptr2_stmt_error)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_execute() */ int LibmysqlDynamicProxy::stmt_execute(MYSQL_STMT * stmt) { ptr2mysql_stmt_execute ptr2_stmt_execute = symbol_safe_cast(GetProcAddr("mysql_stmt_execute")); return (*ptr2_stmt_execute)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_fetch() */ int LibmysqlDynamicProxy::stmt_fetch(MYSQL_STMT * stmt) { ptr2mysql_stmt_fetch ptr2_stmt_fetch = symbol_safe_cast(GetProcAddr("mysql_stmt_fetch")); return (*ptr2_stmt_fetch)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_field_count() */ unsigned int LibmysqlDynamicProxy::stmt_field_count(MYSQL_STMT * stmt) { ptr2mysql_stmt_field_count ptr2_stmt_field_count = symbol_safe_cast(GetProcAddr("mysql_stmt_field_count")); return (*ptr2_stmt_field_count)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_init() */ MYSQL_STMT * LibmysqlDynamicProxy::stmt_init(MYSQL * mysql) { ptr2mysql_stmt_init ptr2_stmt_init = symbol_safe_cast(GetProcAddr("mysql_stmt_init")); return (*ptr2_stmt_init)(mysql); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_num_rows() */ my_ulonglong LibmysqlDynamicProxy::stmt_num_rows(MYSQL_STMT * stmt) { ptr2mysql_stmt_num_rows ptr2_stmt_num_rows = symbol_safe_cast(GetProcAddr("mysql_stmt_num_rows")); return (*ptr2_stmt_num_rows)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_param_count() */ unsigned long LibmysqlDynamicProxy::stmt_param_count(MYSQL_STMT * stmt) { ptr2mysql_stmt_param_count ptr2_stmt_param_count = symbol_safe_cast(GetProcAddr("mysql_stmt_param_count")); return (*ptr2_stmt_param_count)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_prepare() */ int LibmysqlDynamicProxy::stmt_prepare(MYSQL_STMT * stmt, const char * stmt_str, unsigned long len) { ptr2mysql_stmt_prepare ptr2_stmt_prepare = symbol_safe_cast(GetProcAddr("mysql_stmt_prepare")); return (*ptr2_stmt_prepare)(stmt, stmt_str, len); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_result_metadata() */ MYSQL_RES * LibmysqlDynamicProxy::stmt_result_metadata(MYSQL_STMT * stmt) { ptr2mysql_stmt_result_metadata ptr2_stmt_result_metadata = symbol_safe_cast(GetProcAddr("mysql_stmt_result_metadata")); return (*ptr2_stmt_result_metadata)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_send_long_data() */ my_bool LibmysqlDynamicProxy::stmt_send_long_data(MYSQL_STMT * stmt, unsigned int par_number, const char * data, unsigned long len) { ptr2mysql_stmt_send_long_data ptr2_stmt_send_long_data = symbol_safe_cast(GetProcAddr("mysql_stmt_send_long_data")); return (*ptr2_stmt_send_long_data)(stmt, par_number, data, len); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_sqlstate() */ const char * LibmysqlDynamicProxy::stmt_sqlstate(MYSQL_STMT * stmt) { ptr2mysql_stmt_sqlstate ptr2_stmt_sqlstate = symbol_safe_cast(GetProcAddr("mysql_stmt_sqlstate")); return (*ptr2_stmt_sqlstate)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_store_result() */ int LibmysqlDynamicProxy::stmt_store_result(MYSQL_STMT * stmt) { ptr2mysql_stmt_store_result ptr2_stmt_store_result = symbol_safe_cast(GetProcAddr("mysql_stmt_store_result")); return (*ptr2_stmt_store_result)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_next_result() */ int LibmysqlDynamicProxy::stmt_next_result(MYSQL_STMT * stmt) { ptr2mysql_stmt_next_result ptr2_stmt_next_result = symbol_safe_cast(GetProcAddr("mysql_stmt_next_result")); if (ptr2_stmt_next_result != NULL) { return (*ptr2_stmt_next_result)(stmt); } else { throw ::sql::MethodNotImplementedException("::mysql_stmt_next_result()"); } } /* }}} */ /* {{{ LibmysqlDynamicProxy::stmt_free_result() */ bool LibmysqlDynamicProxy::stmt_free_result(MYSQL_STMT * stmt) { ptr2mysql_stmt_free_result ptr2_stmt_free_result = symbol_safe_cast(GetProcAddr("mysql_stmt_free_result")); return (*ptr2_stmt_next_result)(stmt); } /* }}} */ /* {{{ LibmysqlDynamicProxy::thread_end() */ void LibmysqlDynamicProxy::thread_end() { ptr2mysql_thread_end ptr2_thread_end = symbol_safe_cast(GetProcAddr("mysql_thread_end")); (*ptr2_thread_end)(); } /* }}} */ /* {{{ LibmysqlDynamicProxy::thread_init() */ void LibmysqlDynamicProxy::thread_init() { ptr2mysql_thread_init ptr2_thread_init = symbol_safe_cast(GetProcAddr("mysql_thread_init")); (*ptr2_thread_init)(); } /* }}} */ } /* namespace util */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/libmysql_dynamic_proxy.h000644 015771 000012 00000011610 12645244436 026207 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_LIBMYSQL_LOADER_H_ #define _MYSQL_LIBMYSQL_LOADER_H_ #include #include #include "mysql_client_api.h" #include "library_loader.h" namespace sql { namespace mysql { namespace NativeAPI { class LibmysqlDynamicProxy : public sql::mysql::util::LibraryLoader, public IMySQLCAPI { private: void init_loader(); public: LibmysqlDynamicProxy(); LibmysqlDynamicProxy(const LibmysqlDynamicProxy &); LibmysqlDynamicProxy(const SQLString & path2libFile); LibmysqlDynamicProxy(const SQLString & dir2look, const SQLString & libFileName); virtual ~LibmysqlDynamicProxy(); // MySQL C-API calls wrappers my_ulonglong affected_rows(MYSQL *); my_bool autocommit(MYSQL * , my_bool); void close (MYSQL *mysql); my_bool commit(MYSQL *mysql); void data_seek(MYSQL_RES *, my_ulonglong); void debug(const char *); unsigned int mysql_errno(MYSQL *); const char * error(MYSQL *); MYSQL_FIELD * fetch_field(MYSQL_RES *); MYSQL_FIELD * fetch_field_direct(MYSQL_RES *, unsigned int); unsigned long * fetch_lengths(MYSQL_RES *); MYSQL_ROW fetch_row(MYSQL_RES *); unsigned int field_count(MYSQL *); void free_result(MYSQL_RES *); unsigned long get_client_version(); const char * get_server_info(MYSQL *); unsigned long get_server_version(MYSQL *); void get_character_set_info(MYSQL *, void *); const char * info(MYSQL *); MYSQL * init(MYSQL *mysql); int library_init(int, char **, char **); void library_end(); my_bool more_results(MYSQL *); int next_result(MYSQL *); unsigned int num_fields(MYSQL_RES *); my_ulonglong num_rows(MYSQL_RES *); int options (MYSQL *, enum mysql_option, const void *); int options (MYSQL *, enum mysql_option, const void *, const void *); int get_option (MYSQL *, enum mysql_option, const void *); int ping(MYSQL *); int query(MYSQL *, const char *); MYSQL * real_connect(MYSQL * mysql, const char * host, const char * user, const char * passwd, const char * db, unsigned int port, const char * unix_socket, unsigned long client_flag); unsigned long real_escape_string(MYSQL * mysql, char * to, const char * from, unsigned long length); int real_query(MYSQL *, const char *, unsigned long); my_bool rollback(MYSQL *); const char * sqlstate(MYSQL *); my_bool ssl_set(MYSQL * mysql, const char * key, const char * cert, const char * ca, const char * capath, const char * cipher); MYSQL_RES * store_result(MYSQL *); MYSQL_RES * use_result(MYSQL *); unsigned int warning_count(MYSQL *); /* Prepared Statement stmt_* functions */ my_ulonglong stmt_affected_rows (MYSQL_STMT *); my_bool stmt_attr_set(MYSQL_STMT *, enum enum_stmt_attr_type, const void *); my_bool stmt_bind_param(MYSQL_STMT *, MYSQL_BIND *); my_bool stmt_bind_result(MYSQL_STMT *, MYSQL_BIND *); my_bool stmt_close(MYSQL_STMT *); void stmt_data_seek(MYSQL_STMT *, my_ulonglong); unsigned int stmt_errno(MYSQL_STMT *); const char * stmt_error(MYSQL_STMT *); int stmt_execute(MYSQL_STMT *); int stmt_fetch(MYSQL_STMT *); unsigned int stmt_field_count(MYSQL_STMT *); MYSQL_STMT * stmt_init(MYSQL *); my_ulonglong stmt_num_rows(MYSQL_STMT *); unsigned long stmt_param_count(MYSQL_STMT *); int stmt_prepare(MYSQL_STMT *, const char *, unsigned long); MYSQL_RES * stmt_result_metadata(MYSQL_STMT *); my_bool stmt_send_long_data (MYSQL_STMT * , unsigned int, const char *, unsigned long); const char * stmt_sqlstate(MYSQL_STMT *); int stmt_store_result(MYSQL_STMT *); int stmt_next_result(MYSQL_STMT *); bool stmt_free_result(MYSQL_STMT *); void thread_init(); void thread_end(); }; } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/libmysql_static_proxy.cpp000644 015771 000012 00000032547 12645244436 026421 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libmysql_static_proxy.h" #include namespace sql { namespace mysql { namespace NativeAPI { /* {{{ LibmysqlStaticProxy::LibmysqlStaticProxy() */ LibmysqlStaticProxy::LibmysqlStaticProxy() { this->library_init(0, NULL, NULL); } /* }}} */ /* {{{ LibmysqlStaticProxy::~LibmysqlStaticProxy() */ LibmysqlStaticProxy::~LibmysqlStaticProxy() { this->library_end(); } /* }}} */ // MySQL C-API calls wrappers /* {{{ LibmysqlStaticProxy::affected_rows() */ my_ulonglong LibmysqlStaticProxy::affected_rows(MYSQL * mysql) { return ::mysql_affected_rows(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::autocommit() */ my_bool LibmysqlStaticProxy::autocommit(MYSQL * mysql, my_bool mode) { return ::mysql_autocommit(mysql, mode); } /* }}} */ /* {{{ LibmysqlStaticProxy::close() */ void LibmysqlStaticProxy::close(MYSQL * mysql) { return ::mysql_close(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::commit() */ my_bool LibmysqlStaticProxy::commit(MYSQL * mysql) { return ::mysql_commit(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::data_seek() */ void LibmysqlStaticProxy::data_seek(MYSQL_RES * result, my_ulonglong offset) { return ::mysql_data_seek(result, offset); } /* }}} */ /* {{{ LibmysqlStaticProxy::debug() */ void LibmysqlStaticProxy::debug(const char * debug) { return ::mysql_debug(debug); } /* }}} */ /* {{{ LibmysqlStaticProxy::mysql_errno() */ unsigned int LibmysqlStaticProxy::mysql_errno(MYSQL * mysql) { return ::mysql_errno(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::error() */ const char * LibmysqlStaticProxy::error(MYSQL * mysql) { return ::mysql_error(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::fetch_field() */ MYSQL_FIELD * LibmysqlStaticProxy::fetch_field(MYSQL_RES * result) { return ::mysql_fetch_field(result); } /* }}} */ /* {{{ LibmysqlStaticProxy::fetch_field_direct() */ MYSQL_FIELD * LibmysqlStaticProxy::fetch_field_direct(MYSQL_RES * result, unsigned int fieldnr) { return ::mysql_fetch_field_direct(result, fieldnr); } /* }}} */ /* {{{ LibmysqlStaticProxy::fetch_lengths() */ unsigned long * LibmysqlStaticProxy::fetch_lengths(MYSQL_RES * result) { return ::mysql_fetch_lengths(result); } /* }}} */ /* {{{ LibmysqlStaticProxy::fetch_row() */ MYSQL_ROW LibmysqlStaticProxy::fetch_row(MYSQL_RES * result) { return ::mysql_fetch_row(result); } /* }}} */ /* {{{ LibmysqlStaticProxy::field_count() */ unsigned int LibmysqlStaticProxy::field_count(MYSQL * mysql) { return ::mysql_field_count(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::free_result() */ void LibmysqlStaticProxy::free_result(MYSQL_RES * result) { return ::mysql_free_result(result); } /* }}} */ /* {{{ LibmysqlStaticProxy::get_client_version() */ unsigned long LibmysqlStaticProxy::get_client_version() { return ::mysql_get_client_version(); } /* }}} */ /* {{{ LibmysqlStaticProxy::get_server_info() */ const char * LibmysqlStaticProxy::get_server_info(MYSQL * mysql) { return ::mysql_get_server_info(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::get_server_version() */ unsigned long LibmysqlStaticProxy::get_server_version(MYSQL * mysql) { return ::mysql_get_server_version(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::get_character_set_info() */ void LibmysqlStaticProxy::get_character_set_info(MYSQL * mysql, void *cs) { return ::mysql_get_character_set_info(mysql, static_cast(cs)); } /* }}} */ /* {{{ LibmysqlStaticProxy::info() */ const char * LibmysqlStaticProxy::info(MYSQL * mysql) { return ::mysql_info(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::init() */ MYSQL * LibmysqlStaticProxy::init(MYSQL * mysql) { return ::mysql_init(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::library_init() */ int LibmysqlStaticProxy::library_init(int argc,char **argv,char **groups) { return ::mysql_library_init(argc, argv, groups); } /* }}} */ /* {{{ LibmysqlStaticProxy::library_end() */ void LibmysqlStaticProxy::library_end() { return ::mysql_library_end(); } /* }}} */ /* {{{ LibmysqlStaticProxy::more_results() */ my_bool LibmysqlStaticProxy::more_results(MYSQL * mysql) { return ::mysql_more_results(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::next_result() */ int LibmysqlStaticProxy::next_result(MYSQL * mysql) { return ::mysql_next_result(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::num_fields() */ unsigned int LibmysqlStaticProxy::num_fields(MYSQL_RES * result) { return ::mysql_num_fields(result); } /* }}} */ /* {{{ LibmysqlStaticProxy::num_rows() */ my_ulonglong LibmysqlStaticProxy::num_rows(MYSQL_RES * result) { return ::mysql_num_rows(result); } /* }}} */ /* {{{ LibmysqlStaticProxy::options() */ int LibmysqlStaticProxy::options(MYSQL * mysql, enum mysql_option option, const void *arg) { // in 5.0 mysql_options's 3rd parameter is "const char *" if ((::mysql_options(mysql, option, static_cast(arg)))) { throw sql::InvalidArgumentException("Unsupported option provided to mysql_options()"); } else { return 0; } } /* }}} */ /* {{{ LibmysqlStaticProxy::options4() */ int LibmysqlStaticProxy::options(MYSQL * mysql, enum mysql_option option, const void *arg1, const void *arg2) { #if MYSQL_VERSION_ID >= 50606 if ((::mysql_options4(mysql, option, static_cast(arg1), static_cast(arg2)))) { throw sql::InvalidArgumentException("Unsupported option provided to mysql_options4()"); } else { return 0; } #else throw ::sql::MethodNotImplementedException("::mysql_options4()"); #endif } /* }}} */ /* {{{ LibmysqlStaticProxy::get_option() */ int LibmysqlStaticProxy::get_option(MYSQL * mysql, enum mysql_option option, const void *arg) { #if MYSQL_VERSION_ID >= 50703 if (::mysql_get_option(mysql, option, arg)) { throw sql::InvalidArgumentException("Unsupported option provided to mysql_get_option()"); } else { return 0; } #else throw ::sql::MethodNotImplementedException("::mysql_get_option()"); #endif } /* }}} */ /* {{{ LibmysqlStaticProxy::query() */ int LibmysqlStaticProxy::query(MYSQL * mysql, const char *stmt_str) { return ::mysql_query(mysql, stmt_str); } /* }}} */ /* {{{ LibmysqlStaticProxy::ping() */ int LibmysqlStaticProxy::ping(MYSQL * mysql) { return ::mysql_ping(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::real_connect() */ MYSQL * LibmysqlStaticProxy::real_connect(MYSQL * mysql, const char * host, const char * user, const char * passwd, const char * db, unsigned int port, const char * unix_socket, unsigned long client_flag) { return ::mysql_real_connect(mysql, host, user, passwd, db, port, unix_socket, client_flag); } /* }}} */ /* {{{ LibmysqlStaticProxy::real_escape_string() */ unsigned long LibmysqlStaticProxy::real_escape_string(MYSQL * mysql, char * to, const char * from, unsigned long length) { return ::mysql_real_escape_string(mysql, to, from, length); } /* }}} */ /* {{{ LibmysqlStaticProxy::real_query() */ int LibmysqlStaticProxy::real_query(MYSQL *mysql,const char *stmt_str, unsigned long len) { return ::mysql_real_query(mysql, stmt_str, len); } /* }}} */ /* {{{ LibmysqlStaticProxy::rollback() */ my_bool LibmysqlStaticProxy::rollback(MYSQL * mysql) { return ::mysql_rollback(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::sqlstate() */ const char * LibmysqlStaticProxy::sqlstate(MYSQL * mysql) { return ::mysql_sqlstate(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::ssl_set() */ my_bool LibmysqlStaticProxy::ssl_set(MYSQL* mysql, const char * key, const char * cert, const char * ca, const char * capath, const char * cipher) { return ::mysql_ssl_set(mysql, key, cert, ca, capath, cipher); } /* }}} */ /* {{{ LibmysqlStaticProxy::store_result() */ MYSQL_RES * LibmysqlStaticProxy::store_result(MYSQL * mysql) { return ::mysql_store_result(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::use_result() */ MYSQL_RES * LibmysqlStaticProxy::use_result(MYSQL * mysql) { return ::mysql_use_result(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::warning_count() */ unsigned int LibmysqlStaticProxy::warning_count(MYSQL * mysql) { return ::mysql_warning_count(mysql); } /* }}} */ /* Prepared Statement mysql_stmt_* functions */ /* {{{ LibmysqlStaticProxy::stmt_affected_rows() */ my_ulonglong LibmysqlStaticProxy::stmt_affected_rows(MYSQL_STMT *stmt) { return ::mysql_stmt_affected_rows(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_attr_set() */ my_bool LibmysqlStaticProxy::stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type option, const void * arg) { return ::mysql_stmt_attr_set(stmt, option, arg); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_bind_param() */ my_bool LibmysqlStaticProxy::stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bind) { return ::mysql_stmt_bind_param(stmt, bind); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_bind_result() */ my_bool LibmysqlStaticProxy::stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bind) { return ::mysql_stmt_bind_result(stmt, bind); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_close() */ my_bool LibmysqlStaticProxy::stmt_close(MYSQL_STMT * stmt) { return ::mysql_stmt_close(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_data_seek() */ void LibmysqlStaticProxy::stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong row_nr) { return ::mysql_stmt_data_seek(stmt, row_nr); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_errno() */ unsigned int LibmysqlStaticProxy::stmt_errno(MYSQL_STMT * stmt) { return ::mysql_stmt_errno(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_error() */ const char * LibmysqlStaticProxy::stmt_error(MYSQL_STMT * stmt) { return ::mysql_stmt_error(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_execute() */ int LibmysqlStaticProxy::stmt_execute(MYSQL_STMT * stmt) { return ::mysql_stmt_execute(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::data_seek() */ int LibmysqlStaticProxy::stmt_fetch(MYSQL_STMT * stmt) { return ::mysql_stmt_fetch(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_field_count() */ unsigned int LibmysqlStaticProxy::stmt_field_count(MYSQL_STMT * stmt) { return ::mysql_stmt_field_count(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_init() */ MYSQL_STMT * LibmysqlStaticProxy::stmt_init(MYSQL * mysql) { return ::mysql_stmt_init(mysql); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_num_rows() */ my_ulonglong LibmysqlStaticProxy::stmt_num_rows(MYSQL_STMT * stmt) { return ::mysql_stmt_num_rows(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_param_count() */ unsigned long LibmysqlStaticProxy::stmt_param_count(MYSQL_STMT * stmt) { return ::mysql_stmt_param_count(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_prepare() */ int LibmysqlStaticProxy::stmt_prepare(MYSQL_STMT * stmt, const char * stmt_str, unsigned long len) { return ::mysql_stmt_prepare(stmt, stmt_str, len); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_result_metadata() */ MYSQL_RES * LibmysqlStaticProxy::stmt_result_metadata(MYSQL_STMT * stmt) { return ::mysql_stmt_result_metadata(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_send_long_data() */ my_bool LibmysqlStaticProxy::stmt_send_long_data(MYSQL_STMT * stmt, unsigned int par_number, const char * data, unsigned long len) { return ::mysql_stmt_send_long_data(stmt, par_number, data, len); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_sqlstate() */ const char * LibmysqlStaticProxy::stmt_sqlstate(MYSQL_STMT * stmt) { return ::mysql_stmt_sqlstate(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_store_result() */ int LibmysqlStaticProxy::stmt_store_result(MYSQL_STMT * stmt) { return ::mysql_stmt_store_result(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_next_result() */ int LibmysqlStaticProxy::stmt_next_result(MYSQL_STMT * stmt) { #if MYSQL_VERSION_ID >= 50503 return ::mysql_stmt_next_result(stmt); #else throw ::sql::MethodNotImplementedException("::mysql_stmt_next_result()"); #endif } /* }}} */ /* {{{ LibmysqlStaticProxy::stmt_free_result() */ bool LibmysqlStaticProxy::stmt_free_result(MYSQL_STMT * stmt) { return ::mysql_stmt_free_result(stmt); } /* }}} */ /* {{{ LibmysqlStaticProxy::thread_end() */ void LibmysqlStaticProxy::thread_end() { ::mysql_thread_end(); } /* }}} */ /* {{{ LibmysqlStaticProxy::thread_init() */ void LibmysqlStaticProxy::thread_init() { ::mysql_thread_init(); } /* }}} */ } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/libmysql_static_proxy.h000644 015771 000012 00000012352 12645244436 026056 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_LIBMYSQL_STATIC_H_ #define _MYSQL_LIBMYSQL_STATIC_H_ #include "mysql_client_api.h" #include #include namespace sql { namespace mysql { namespace util { template class Singleton: public boost::noncopyable { protected: Singleton(){} public: static boost::shared_ptr & theInstance() { //shared::ptr is used only to be able to use in getCApiHandle static boost::shared_ptr instance(new T()); return instance; } }; // macros to use in private/protected part of singleton-ed class #define CCPP_SINGLETON(classname) classname();\ friend class sql::mysql::util::Singleton } namespace NativeAPI { class LibmysqlStaticProxy : public IMySQLCAPI, public ::sql::mysql::util::Singleton< LibmysqlStaticProxy > { private: CCPP_SINGLETON(LibmysqlStaticProxy); public: virtual ~LibmysqlStaticProxy(); // MySQL C-API calls wrappers my_ulonglong affected_rows(MYSQL * mysql); my_bool autocommit(MYSQL *, my_bool); void close(MYSQL * mysql); my_bool commit(MYSQL * mysql); void data_seek(MYSQL_RES *, my_ulonglong); void debug(const char *); unsigned int mysql_errno(MYSQL * mysql); const char * error(MYSQL * mysql); MYSQL_FIELD *fetch_field(MYSQL_RES *); MYSQL_FIELD *fetch_field_direct(MYSQL_RES *, unsigned int); unsigned long *fetch_lengths(MYSQL_RES *); MYSQL_ROW fetch_row(MYSQL_RES *); unsigned int field_count(MYSQL * mysql); void free_result(MYSQL_RES *); unsigned long get_client_version(); const char * get_server_info(MYSQL * mysql); unsigned long get_server_version(MYSQL * mysql); void get_character_set_info(MYSQL * mysql, void *cs); const char * info(MYSQL * mysql); MYSQL * init(MYSQL * mysql); int library_init(int, char **, char **); void library_end(); my_bool more_results(MYSQL * mysql); int next_result(MYSQL * mysql); unsigned int num_fields(MYSQL_RES *); my_ulonglong num_rows(MYSQL_RES *); int options(MYSQL *, enum mysql_option, const void *); int options(MYSQL *, enum mysql_option, const void *, const void *); int get_option(MYSQL *, enum mysql_option, const void *); int ping(MYSQL *); int query(MYSQL *, const char *); MYSQL * real_connect(MYSQL * mysql, const char * host, const char * user, const char * passwd, const char * db, unsigned int port, const char * unix_socket, unsigned long client_flag); unsigned long real_escape_string(MYSQL * mysql, char * to, const char * from, unsigned long length); int real_query(MYSQL *, const char *, unsigned long); my_bool rollback(MYSQL * mysql); const char * sqlstate(MYSQL * mysql); my_bool ssl_set(MYSQL * mysql, const char * key, const char * cert, const char * ca, const char * capath, const char * cipher); MYSQL_RES * store_result(MYSQL * mysql); MYSQL_RES * use_result(MYSQL * mysql); unsigned int warning_count(MYSQL * mysql); /* Prepared Statementstmt_* functions */ my_ulonglong stmt_affected_rows(MYSQL_STMT *); my_bool stmt_attr_set(MYSQL_STMT *, enum enum_stmt_attr_type, const void *); my_bool stmt_bind_param(MYSQL_STMT *, MYSQL_BIND *); my_bool stmt_bind_result(MYSQL_STMT *, MYSQL_BIND *); my_bool stmt_close(MYSQL_STMT *); void stmt_data_seek(MYSQL_STMT *, my_ulonglong); unsigned int stmt_errno(MYSQL_STMT *); const char * stmt_error(MYSQL_STMT *); int stmt_execute(MYSQL_STMT *); int stmt_fetch(MYSQL_STMT *); unsigned int stmt_field_count(MYSQL_STMT *); MYSQL_STMT * stmt_init(MYSQL * mysql); my_ulonglong stmt_num_rows(MYSQL_STMT *); unsigned long stmt_param_count(MYSQL_STMT *); int stmt_prepare(MYSQL_STMT *, const char *, unsigned long); MYSQL_RES * stmt_result_metadata(MYSQL_STMT *); my_bool stmt_send_long_data(MYSQL_STMT *, unsigned int, const char *, unsigned long); const char * stmt_sqlstate(MYSQL_STMT *); int stmt_store_result(MYSQL_STMT *); int stmt_next_result(MYSQL_STMT *); bool stmt_free_result(MYSQL_STMT *); void thread_init(); void thread_end(); }; } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/library_loader.cpp000644 015771 000012 00000007025 12645244436 024740 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "binding_config.h" #ifndef MYSQLCLIENT_STATIC_BINDING #include #include // Needed to make SetDllDirectory available #define _WIN32_WINNT 0x0502 #include "library_loader.h" /* TODO consider using of dlopen, dlsym and dlclose definitions in my_global.h * sort of doesn't like that. */ #ifndef _WIN32 #define LoadLibrary(p) ::dlopen(p, RTLD_LAZY) #define FreeLibrary(p) ::dlclose(p) #define GetProcAddress(p1,p2) ::dlsym(p1,p2) #endif namespace sql { namespace mysql { namespace util { std::string ErrorMessage() { #ifdef _WIN32 TCHAR buffer[255]; DWORD _errcode = GetLastError(); ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, _errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); return buffer; #else return dlerror(); #endif } /* {{{ LibraryLoader::LibraryLoader() */ LibraryLoader::LibraryLoader(const std::string & path2libFile) : loadedLibHandle (NULL) { if ((loadedLibHandle = LoadLibrary(path2libFile.c_str())) == NULL) { throw std::runtime_error(std::string("Couldn't load library ") + path2libFile + ": " + ErrorMessage()); } } /* }}} */ /* {{{ LibraryLoader::LibraryLoader() */ LibraryLoader::LibraryLoader(const std::string & dir2look, const std::string & libFileName) : loadedLibHandle(NULL) { #if _WIN32 SetDllDirectory(dir2look.c_str()); if ((loadedLibHandle= LoadLibrary(libFileName.c_str())) == NULL) { #else std::string fullname(dir2look); fullname += "/"; fullname += libFileName; if ((loadedLibHandle = LoadLibrary(fullname.c_str())) == NULL) { #endif throw std::runtime_error(std::string("Couldn't load library ") + libFileName + ": " + ErrorMessage()); } } /* }}} */ /* {{{ LibraryLoader::~LibraryLoader() */ LibraryLoader::~LibraryLoader() { FreeLibrary(loadedLibHandle); } /* }}} */ /* {{{ LibraryLoader::GetProcAddr() */ SymbolHandle LibraryLoader::GetProcAddr(const std::string & name) { if (loadedLibHandle == NULL) { return NULL; } ProcCache::const_iterator cit = functions.find(name); if (cit != functions.end()) { return cit->second; } SymbolHandle proc = GetProcAddress(loadedLibHandle, name.c_str()); if (proc == NULL) { throw std::runtime_error("Couldn't find symbol " + name); } functions.insert(std::make_pair(name, proc)); return proc; } /* }}} */ } /* namespace util */ } /* namespace mysql */ } /* namespace sql */ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/library_loader.h000644 015771 000012 00000004362 12645244436 024406 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_LIB_LOADER_H_ #define _MYSQL_LIB_LOADER_H_ #include "binding_config.h" #ifdef _WIN32 #include #elif defined(HAVE_DLFCN_H) # include #else # error This should never happen - if this header is included, one of macros above supposed to be defined. #endif #include #include namespace sql { namespace mysql { namespace util { #ifdef _WIN32 typedef HMODULE ModuleHandle; typedef FARPROC SymbolHandle; #else typedef void * ModuleHandle; typedef void * SymbolHandle; #endif /* possibly C_LibraryLoader would be better name */ class LibraryLoader : public boost::noncopyable { private: typedef std::map< std::string, SymbolHandle > ProcCache; ProcCache functions; ModuleHandle loadedLibHandle; LibraryLoader() {} protected: LibraryLoader(const std::string & path2libFile); LibraryLoader(const std::string & dir2look, const std::string & libFileName); ~LibraryLoader(); SymbolHandle GetProcAddr(const std::string & name); }; } /* namespace util */ } /* namespace mysql */ } /* namespace sql */ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_client_api.cpp000644 015771 000012 00000004674 12645244436 025311 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "binding_config.h" #ifdef MYSQLCLIENT_STATIC_BINDING /* MySQL client library is linked */ # include "libmysql_static_proxy.h" #else /* MySQL client library will be dynamically loaded */ # include "libmysql_dynamic_proxy.h" #endif namespace sql { namespace mysql { namespace NativeAPI { /* We need probably multi_index map by path and HMODULE/void * as we can load same library by different name */ static std::map< sql::SQLString, boost::shared_ptr > wrapper; boost::shared_ptr< IMySQLCAPI > getCApiHandle(const sql::SQLString & name) { #ifdef MYSQLCLIENT_STATIC_BINDING return LibmysqlStaticProxy::theInstance(); #else std::map< sql::SQLString, boost::shared_ptr< IMySQLCAPI > >::const_iterator cit; if ((cit = wrapper.find(name)) != wrapper.end()) { return cit->second; } else { boost::shared_ptr< IMySQLCAPI > newWrapper; newWrapper.reset(new LibmysqlDynamicProxy(name)); wrapper[name] = newWrapper; return newWrapper; } #endif } } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #include "binding_config.h" #ifdef MYSQLCLIENT_STATIC_BINDING # include "libmysql_static_proxy.cpp" #else # include "libmysql_dynamic_proxy.cpp" #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_client_api.h000644 015771 000012 00000024212 12645244436 024744 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_LIBMYSQL_API_H_ #define _MYSQL_LIBMYSQL_API_H_ #include "mysql_private_iface.h" #include namespace sql { class SQLString; namespace mysql { namespace NativeAPI { typedef my_ulonglong (STDCALL *ptr2mysql_affected_rows)(MYSQL *); typedef my_bool (STDCALL *ptr2mysql_autocommit)(MYSQL *, my_bool); typedef void (STDCALL *ptr2mysql_close)(MYSQL *mysql); typedef my_bool (STDCALL *ptr2mysql_commit)(MYSQL *mysql); typedef void (STDCALL *ptr2mysql_data_seek)(MYSQL_RES *, my_ulonglong); typedef void (STDCALL *ptr2mysql_debug)(const char *debug); typedef unsigned int (STDCALL *ptr2mysql_errno)(MYSQL *mysql); typedef const char * (STDCALL *ptr2mysql_error)(MYSQL *mysql); typedef MYSQL_FIELD * (STDCALL *ptr2mysql_fetch_field)(MYSQL_RES *); typedef MYSQL_FIELD * (STDCALL *ptr2mysql_fetch_field_direct)(MYSQL_RES *, unsigned int); typedef unsigned long * (STDCALL *ptr2mysql_fetch_lengths)(MYSQL_RES *); typedef MYSQL_ROW (STDCALL *ptr2mysql_fetch_row)(MYSQL_RES *); typedef unsigned int (STDCALL *ptr2mysql_field_count)(MYSQL *); typedef void (STDCALL *ptr2mysql_free_result)(MYSQL_RES *); typedef unsigned long (STDCALL *ptr2mysql_get_client_version)(); typedef const char * (STDCALL *ptr2mysql_get_server_info)(MYSQL *); typedef unsigned long (STDCALL *ptr2mysql_get_server_version)(MYSQL *); typedef void (STDCALL *ptr2mysql_get_character_set_info)(MYSQL *, void *); typedef char * (STDCALL *ptr2mysql_info)(MYSQL *mysql); typedef MYSQL * (STDCALL *ptr2mysql_init)(MYSQL *mysql); typedef int (STDCALL *ptr2mysql_library_init)(int, char **, char **); typedef void (STDCALL *ptr2mysql_library_end)(void); typedef my_bool (STDCALL *ptr2mysql_more_results)(MYSQL *); typedef int (STDCALL *ptr2mysql_next_result)(MYSQL *); typedef unsigned int (STDCALL *ptr2mysql_num_fields)(MYSQL_RES *); typedef my_ulonglong (STDCALL *ptr2mysql_num_rows)(MYSQL_RES *); typedef int (STDCALL *ptr2mysql_options)(MYSQL *, enum mysql_option, const void *); typedef int (STDCALL *ptr2mysql_options4)(MYSQL *, enum mysql_option, const void *, const void *); typedef int (STDCALL *ptr2mysql_get_option)(MYSQL *, enum mysql_option, const void *); typedef int (STDCALL *ptr2mysql_query)(MYSQL *, const char *); typedef int (STDCALL *ptr2mysql_ping)(MYSQL *); typedef MYSQL * (STDCALL *ptr2mysql_real_connect)(MYSQL *, const char *, const char *, const char * , const char *, unsigned int, const char *, unsigned long); typedef unsigned long (STDCALL *ptr2mysql_real_escape_string)(MYSQL * mysql, char *, const char *, unsigned long); typedef int (STDCALL *ptr2mysql_real_query)(MYSQL *, const char *, unsigned long); typedef my_bool (STDCALL *ptr2mysql_rollback)(MYSQL *mysql); typedef const char * (STDCALL *ptr2mysql_sqlstate)(MYSQL *mysql); typedef my_bool (STDCALL *ptr2mysql_ssl_set)(MYSQL *, const char *, const char *, const char *, const char *, const char *); typedef MYSQL_RES * (STDCALL *ptr2mysql_store_result)(MYSQL *); typedef MYSQL_RES * (STDCALL *ptr2mysql_use_result)(MYSQL *); typedef unsigned int (STDCALL *ptr2mysql_warning_count)(MYSQL *); /* Prepared Statement stmt_* functions */ typedef my_ulonglong (STDCALL *ptr2mysql_stmt_affected_rows)(MYSQL_STMT *); typedef my_bool (STDCALL *ptr2mysql_stmt_attr_set)(MYSQL_STMT *, enum enum_stmt_attr_type, const void *); typedef my_bool (STDCALL *ptr2mysql_stmt_bind_param)(MYSQL_STMT *, MYSQL_BIND *); typedef my_bool (STDCALL *ptr2mysql_stmt_bind_result)(MYSQL_STMT *, MYSQL_BIND *); typedef my_bool (STDCALL *ptr2mysql_stmt_close)(MYSQL_STMT *); typedef void (STDCALL *ptr2mysql_stmt_data_seek)(MYSQL_STMT *, my_ulonglong); typedef unsigned int (STDCALL *ptr2mysql_stmt_errno)(MYSQL_STMT *); typedef const char * (STDCALL *ptr2mysql_stmt_error)(MYSQL_STMT *); typedef int (STDCALL *ptr2mysql_stmt_execute)(MYSQL_STMT *); typedef int (STDCALL *ptr2mysql_stmt_fetch)(MYSQL_STMT *); typedef unsigned int (STDCALL *ptr2mysql_stmt_field_count)(MYSQL_STMT *); typedef MYSQL_STMT * (STDCALL *ptr2mysql_stmt_init)(MYSQL *); typedef my_ulonglong (STDCALL *ptr2mysql_stmt_num_rows)(MYSQL_STMT *); typedef unsigned long (STDCALL *ptr2mysql_stmt_param_count)(MYSQL_STMT *); typedef int (STDCALL *ptr2mysql_stmt_prepare)(MYSQL_STMT *, const char *, unsigned long); typedef MYSQL_RES * (STDCALL *ptr2mysql_stmt_result_metadata)(MYSQL_STMT *); typedef my_bool (STDCALL *ptr2mysql_stmt_send_long_data)(MYSQL_STMT *, unsigned int, const char *, unsigned long); typedef const char * (STDCALL *ptr2mysql_stmt_sqlstate)(MYSQL_STMT *); typedef int (STDCALL *ptr2mysql_stmt_store_result)(MYSQL_STMT *); typedef int (STDCALL *ptr2mysql_stmt_next_result)(MYSQL_STMT *); typedef bool (STDCALL *ptr2mysql_stmt_free_result)(MYSQL_STMT *); typedef void (STDCALL *ptr2mysql_thread_init)(); typedef void (STDCALL *ptr2mysql_thread_end)(); /* * Interface MySQL C-API wrapper class should implement. * At the moment we must have at least 2 implementation - for static and dynamic * mysql client library linking */ class IMySQLCAPI { public: virtual my_ulonglong affected_rows(MYSQL *) = 0; virtual my_bool autocommit(MYSQL *, my_bool) = 0; virtual void close(MYSQL *mysql) = 0; virtual my_bool commit(MYSQL *mysql) = 0; virtual void data_seek(MYSQL_RES *, my_ulonglong) = 0; virtual void debug(const char *) = 0; virtual unsigned int mysql_errno(MYSQL *mysql) = 0; virtual const char * error(MYSQL *mysql) = 0; virtual MYSQL_FIELD * fetch_field(MYSQL_RES *) = 0; virtual MYSQL_FIELD * fetch_field_direct (MYSQL_RES *, unsigned int) = 0; virtual unsigned long * fetch_lengths(MYSQL_RES * ) = 0; virtual MYSQL_ROW fetch_row(MYSQL_RES * ) = 0; virtual unsigned int field_count(MYSQL *) = 0; virtual void free_result(MYSQL_RES * ) = 0; virtual unsigned long get_client_version() = 0; virtual const char * get_server_info(MYSQL *) = 0; virtual unsigned long get_server_version(MYSQL *) = 0; virtual void get_character_set_info(MYSQL *, void *) = 0; virtual const char * info(MYSQL *mysql) = 0; virtual MYSQL * init(MYSQL *mysql) = 0; virtual int library_init(int argc, char **argv, char **groups) = 0; virtual void library_end() = 0; virtual my_bool more_results(MYSQL *) = 0; virtual int next_result(MYSQL *) = 0; virtual unsigned int num_fields(MYSQL_RES * ) = 0; virtual my_ulonglong num_rows(MYSQL_RES * ) = 0; virtual int options(MYSQL *, enum mysql_option option , const void *arg) = 0; virtual int options(MYSQL *, enum mysql_option option , const void *arg1, const void *arg2) = 0; virtual int get_option(MYSQL *, enum mysql_option option , const void *arg) = 0; virtual int ping(MYSQL *) = 0; virtual int query(MYSQL *, const char *) = 0; virtual MYSQL * real_connect(MYSQL * mysql, const char * host, const char * user, const char * passwd, const char * db, unsigned int port, const char * unix_socket, unsigned long client_flag) = 0; virtual unsigned long real_escape_string(MYSQL * mysql, char * to, const char * from, unsigned long length) = 0; virtual int real_query(MYSQL *, const char *, unsigned long) = 0; virtual my_bool rollback(MYSQL *) = 0; virtual const char * sqlstate(MYSQL *) = 0; virtual my_bool ssl_set(MYSQL * mysql, const char * key, const char * cert, const char * ca, const char * capath, const char * cipher) = 0; virtual MYSQL_RES * store_result(MYSQL *) = 0; virtual MYSQL_RES * use_result(MYSQL *) = 0; virtual unsigned int warning_count(MYSQL *) = 0; /* Methods - wrappers of prepared statement stmt_* functions */ virtual my_ulonglong stmt_affected_rows (MYSQL_STMT *) = 0; virtual my_bool stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type option , const void *arg) = 0; virtual my_bool stmt_bind_param(MYSQL_STMT *, MYSQL_BIND *) = 0; virtual my_bool stmt_bind_result(MYSQL_STMT *, MYSQL_BIND *) = 0; virtual my_bool stmt_close(MYSQL_STMT *) = 0; virtual void stmt_data_seek(MYSQL_STMT *, my_ulonglong) = 0; virtual unsigned int stmt_errno(MYSQL_STMT *) = 0; virtual const char * stmt_error(MYSQL_STMT *) = 0; virtual int stmt_execute(MYSQL_STMT *) = 0; virtual int stmt_fetch(MYSQL_STMT *) = 0; virtual unsigned int stmt_field_count(MYSQL_STMT *) = 0; virtual MYSQL_STMT * stmt_init(MYSQL *) = 0; virtual my_ulonglong stmt_num_rows(MYSQL_STMT *) = 0; virtual unsigned long stmt_param_count(MYSQL_STMT *) = 0; virtual int stmt_prepare(MYSQL_STMT *, const char *, unsigned long) = 0; virtual MYSQL_RES * stmt_result_metadata(MYSQL_STMT *) = 0; virtual my_bool stmt_send_long_data(MYSQL_STMT * stmt , unsigned int par_number, const char * data, unsigned long len) = 0; virtual const char * stmt_sqlstate(MYSQL_STMT *) = 0; virtual int stmt_store_result(MYSQL_STMT *) = 0; virtual int stmt_next_result(MYSQL_STMT *) = 0; virtual bool stmt_free_result(MYSQL_STMT *) = 0; virtual void thread_end() = 0; virtual void thread_init() = 0; }; boost::shared_ptr getCApiHandle(const sql::SQLString & name); } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql*/ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_connection_wrapper.cpp000644 015771 000012 00000025670 12645244436 030446 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "../mysql_util.h" #include "../mysql_connection_options.h" #include "mysql_client_api.h" #include "mysql_native_resultset_wrapper.h" #include "mysql_native_statement_wrapper.h" #include "mysql_native_connection_wrapper.h" namespace sql { namespace mysql { namespace NativeAPI { /* {{{ MySQL_NativeConnectionWrapper::MySQL_NativeConnectionWrapper() */ MySQL_NativeConnectionWrapper::MySQL_NativeConnectionWrapper(boost::shared_ptr _api) : api(_api), mysql(api->init(NULL)) { if (mysql == NULL) { throw sql::SQLException("Insufficient memory: cannot create MySQL handle using mysql_init()"); } } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::~MySQL_NativeConnectionWrapper() */ MySQL_NativeConnectionWrapper::~MySQL_NativeConnectionWrapper() { api->close(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::affected_rows() */ uint64_t MySQL_NativeConnectionWrapper::affected_rows() { return api->affected_rows(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::autocommit() */ bool MySQL_NativeConnectionWrapper::autocommit(bool mode) { return (api->autocommit(mysql, mode) != '\0'); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::connect() */ bool MySQL_NativeConnectionWrapper::connect(const ::sql::SQLString & host, const ::sql::SQLString & user, const ::sql::SQLString & passwd, const ::sql::SQLString & db, unsigned int port, const ::sql::SQLString & socket_or_pipe, unsigned long client_flag) { return (NULL != api->real_connect(mysql, nullIfEmpty(host), user.c_str(), nullIfEmpty(passwd), nullIfEmpty(db), port, nullIfEmpty(socket_or_pipe), client_flag)); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::commit() */ bool MySQL_NativeConnectionWrapper::commit() { return (api->commit(mysql) != '\0'); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::debug() */ void MySQL_NativeConnectionWrapper::debug(const SQLString & debug) { api->debug(debug.c_str()); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::errNo() */ unsigned int MySQL_NativeConnectionWrapper::errNo() { return api->mysql_errno(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::escapeString() */ SQLString MySQL_NativeConnectionWrapper::escapeString(const SQLString & s) { boost::scoped_array< char > buffer(new char[s.length() * 2 + 1]); if (!buffer.get()) { return ""; } unsigned long return_len = api->real_escape_string(mysql, buffer.get(), s.c_str(), (unsigned long) s.length()); return sql::SQLString(buffer.get(), return_len); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::error() */ SQLString MySQL_NativeConnectionWrapper::error() { return api->error(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::field_count() */ unsigned int MySQL_NativeConnectionWrapper::field_count() { return api->field_count(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_client_version() */ unsigned long MySQL_NativeConnectionWrapper::get_client_version() { return api->get_client_version(); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_server_info() */ const SQLString & MySQL_NativeConnectionWrapper::get_server_info() { serverInfo = api->get_server_info(mysql); return serverInfo; } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_server_version() */ unsigned long MySQL_NativeConnectionWrapper::get_server_version() { return api->get_server_version(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_character_set_info() */ void MySQL_NativeConnectionWrapper::get_character_set_info(void *cs) { return api->get_character_set_info(mysql, cs); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::more_results() */ bool MySQL_NativeConnectionWrapper::more_results() { return (api->more_results(mysql) != '\0'); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::next_result() */ int MySQL_NativeConnectionWrapper::next_result() { return api->next_result(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::options() */ int MySQL_NativeConnectionWrapper::options(::sql::mysql::MySQL_Connection_Options option, const void * value) { return api->options(mysql, static_cast< mysql_option >(option), value); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::options(SQLString &) */ int MySQL_NativeConnectionWrapper::options(::sql::mysql::MySQL_Connection_Options option, const ::sql::SQLString &str) { return api->options(mysql, static_cast< mysql_option >(option), str.c_str()); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::options(bool &) */ int MySQL_NativeConnectionWrapper::options(::sql::mysql::MySQL_Connection_Options option, const bool &option_val) { my_bool dummy= option_val ? '\1' : '\0'; return api->options(mysql, static_cast< mysql_option >(option), &dummy); } /* {{{ MySQL_NativeConnectionWrapper::options(int &) */ int MySQL_NativeConnectionWrapper::options(::sql::mysql::MySQL_Connection_Options option, const int &option_val) { return api->options(mysql, static_cast< mysql_option >(option), &option_val); } /* {{{ MySQL_NativeConnectionWrapper::options(SQLString &, SQLString &) */ int MySQL_NativeConnectionWrapper::options(::sql::mysql::MySQL_Connection_Options option, const ::sql::SQLString &key, const ::sql::SQLString &value) { return api->options(mysql, static_cast< mysql_option >(option), key.c_str(), value.c_str()); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_option() */ int MySQL_NativeConnectionWrapper::get_option(::sql::mysql::MySQL_Connection_Options option, const void * value) { return api->get_option(mysql, static_cast< mysql_option >(option), value); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_option(SQLString &) */ int MySQL_NativeConnectionWrapper::get_option(::sql::mysql::MySQL_Connection_Options option, const ::sql::SQLString &str) { return api->get_option(mysql, static_cast< mysql_option >(option), str.c_str()); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::get_option(bool &) */ int MySQL_NativeConnectionWrapper::get_option(::sql::mysql::MySQL_Connection_Options option, const bool &option_val) { my_bool dummy= option_val ? '\1' : '\0'; return api->get_option(mysql, static_cast< mysql_option >(option), &dummy); } /* {{{ MySQL_NativeConnectionWrapper::get_option(int &) */ int MySQL_NativeConnectionWrapper::get_option(::sql::mysql::MySQL_Connection_Options option, const int &option_val) { return api->get_option(mysql, static_cast< mysql_option >(option), &option_val); } /* {{{ MySQL_NativeConnectionWrapper::query() */ int MySQL_NativeConnectionWrapper::query(const SQLString & stmt_str) { return api->real_query(mysql, stmt_str.c_str(), stmt_str.length()); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::ping() */ int MySQL_NativeConnectionWrapper::ping() { return api->ping(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::rollback() */ bool MySQL_NativeConnectionWrapper::rollback() { return (api->rollback(mysql) != '\0'); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::sqlstate() */ SQLString MySQL_NativeConnectionWrapper::sqlstate() { return api->sqlstate(mysql); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::sqlstate() */ SQLString MySQL_NativeConnectionWrapper::info() { const char * result= api->info(mysql); return (result ? result : ""); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::ssl_set() */ bool MySQL_NativeConnectionWrapper::ssl_set(const SQLString & key, const SQLString & cert, const SQLString & ca, const SQLString & capath, const SQLString & cipher) { return ('\0' != api->ssl_set(mysql, nullIfEmpty(key), nullIfEmpty(cert), nullIfEmpty(ca), nullIfEmpty(capath), nullIfEmpty(cipher))); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::store_result() */ NativeResultsetWrapper * MySQL_NativeConnectionWrapper::store_result() { ::st_mysql_res * raw= api->store_result(mysql); if (raw == NULL) { /*CPP_ERR_FMT("Error during %s_result : %d:(%s) %s", resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY? "use":"store", this->errNo(), this->sqlstate(), this->error());*/ return NULL; } return new MySQL_NativeResultsetWrapper(raw, api); } /* }}} */ static const int protocolType2mysql[PROTOCOL_COUNT][2]= { {PROTOCOL_TCP, MYSQL_PROTOCOL_TCP}, {PROTOCOL_SOCKET, MYSQL_PROTOCOL_SOCKET}, {PROTOCOL_PIPE, MYSQL_PROTOCOL_PIPE} }; /* {{{ MySQL_NativeConnectionWrapper::use_protocol() */ int MySQL_NativeConnectionWrapper::use_protocol(Protocol_Type protocol) { for (int i= 0; i< PROTOCOL_COUNT; ++i) { if (protocolType2mysql[i][0] == protocol) return options(MYSQL_OPT_PROTOCOL, (const char *)&protocolType2mysql[i][1]); } return -1; } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::use_result() */ NativeResultsetWrapper * MySQL_NativeConnectionWrapper::use_result() { ::st_mysql_res * raw= api->use_result(mysql); if (raw == NULL) { /*CPP_ERR_FMT("Error during %s_result : %d:(%s) %s", resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY? "use":"store", this->errNo(), this->sqlstate(), this->error());*/ return NULL; } return new MySQL_NativeResultsetWrapper(raw, api); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::stmt_init() */ NativeStatementWrapper & MySQL_NativeConnectionWrapper::stmt_init() { ::st_mysql_stmt * raw= api->stmt_init(mysql); if (raw == NULL) { /*CPP_ERR_FMT("No statement : %d:(%s) %s", e->errNo(), proxy->sqlstate(), proxy->error());*/ ::sql::mysql::util::throwSQLException(*this); } return *(new MySQL_NativeStatementWrapper(raw, api, this)); } /* }}} */ /* {{{ MySQL_NativeConnectionWrapper::warning_count() */ unsigned int MySQL_NativeConnectionWrapper::warning_count() { return api->warning_count(mysql); } /* }}} */ } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_connection_wrapper.h000644 015771 000012 00000007704 12645244436 030111 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_CONNECTION_PROXY_H_ #define _MYSQL_CONNECTION_PROXY_H_ #include "native_connection_wrapper.h" #include #include namespace sql { namespace mysql { namespace NativeAPI { class IMySQLCAPI; inline const char * nullIfEmpty(const ::sql::SQLString & str) { return str.length() > 0 ? str.c_str() : NULL; } class MySQL_NativeConnectionWrapper : public NativeConnectionWrapper { /* api should be declared before mysql here */ boost::shared_ptr< IMySQLCAPI > api; struct ::st_mysql * mysql; ::sql::SQLString serverInfo; MySQL_NativeConnectionWrapper(){} public: MySQL_NativeConnectionWrapper(boost::shared_ptr _api); virtual ~MySQL_NativeConnectionWrapper(); uint64_t affected_rows(); bool autocommit(bool); bool connect(const ::sql::SQLString & host, const ::sql::SQLString & user, const ::sql::SQLString & passwd, const ::sql::SQLString & db, unsigned int port, const ::sql::SQLString & socket_or_pipe, unsigned long client_flag); bool commit(); void debug(const ::sql::SQLString &); unsigned int errNo(); ::sql::SQLString error(); ::sql::SQLString escapeString(const ::sql::SQLString &); unsigned int field_count(); unsigned long get_client_version(); const ::sql::SQLString & get_server_info(); unsigned long get_server_version(); void get_character_set_info(void *cs); bool more_results(); int next_result(); int options(::sql::mysql::MySQL_Connection_Options, const void * ); int options(::sql::mysql::MySQL_Connection_Options, const ::sql::SQLString &); int options(::sql::mysql::MySQL_Connection_Options, const bool &); int options(::sql::mysql::MySQL_Connection_Options, const int &); int options(::sql::mysql::MySQL_Connection_Options, const ::sql::SQLString &, const ::sql::SQLString &); int get_option(::sql::mysql::MySQL_Connection_Options, const void * ); int get_option(::sql::mysql::MySQL_Connection_Options, const ::sql::SQLString &); int get_option(::sql::mysql::MySQL_Connection_Options, const bool &); int get_option(::sql::mysql::MySQL_Connection_Options, const int &); int query(const ::sql::SQLString &); int ping(); /* int real_query(const ::sql::SQLString &, uint64_t);*/ bool rollback(); ::sql::SQLString sqlstate(); bool ssl_set(const ::sql::SQLString & key, const ::sql::SQLString & cert, const ::sql::SQLString & ca, const ::sql::SQLString & capath, const ::sql::SQLString & cipher); ::sql::SQLString info(); NativeResultsetWrapper * store_result(); int use_protocol(Protocol_Type protocol); NativeResultsetWrapper * use_result(); NativeStatementWrapper & stmt_init(); unsigned int warning_count(); }; } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_driver_wrapper.cpp000644 015771 000012 00000004563 12645244436 027600 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_client_api.h" #include "mysql_native_driver_wrapper.h" #include "mysql_native_connection_wrapper.h" namespace sql { namespace mysql { namespace NativeAPI { /* {{{ createStMysqlWrapper() */ NativeDriverWrapper * createNativeDriverWrapper(const SQLString & clientFileName) { return new MySQL_NativeDriverWrapper(clientFileName); } /* }}} */ /* {{{ MySQL_NativeDriverWrapper::MySQL_NativeDriverWrapper() */ MySQL_NativeDriverWrapper::MySQL_NativeDriverWrapper(const ::sql::SQLString & clientFileName) : api(::sql::mysql::NativeAPI::getCApiHandle(clientFileName)) { } /* }}} */ /* {{{ MySQL_NativeDriverWrapper::~MySQL_NativeDriverWrapper() */ MySQL_NativeDriverWrapper::~MySQL_NativeDriverWrapper() { } /* }}} */ NativeConnectionWrapper & MySQL_NativeDriverWrapper::conn_init() { return *(new MySQL_NativeConnectionWrapper(api)); } /* {{{ MySQL_NativeDriverWrapper::thread_end() */ void MySQL_NativeDriverWrapper::thread_end() { return api->thread_end(); } /* }}} */ /* {{{ MySQL_NativeDriverWrapper::thread_init() */ void MySQL_NativeDriverWrapper::thread_init() { return api->thread_init(); } /* }}} */ } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_driver_wrapper.h000644 015771 000012 00000003476 12645244436 027247 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_NATIVE_DRIVER_WRAPPER_H_ #define _MYSQL_NATIVE_DRIVER_WRAPPER_H_ #include #include "native_driver_wrapper.h" namespace sql { namespace mysql { namespace NativeAPI { class IMySQLCAPI; class MySQL_NativeDriverWrapper : public NativeDriverWrapper { boost::shared_ptr api; MySQL_NativeDriverWrapper(){} public: MySQL_NativeDriverWrapper(const ::sql::SQLString & clientFileName); ~MySQL_NativeDriverWrapper(); NativeConnectionWrapper & conn_init(); ; void thread_end(); void thread_init(); }; } /* NativeAPI */ } /* mysql */ } /* sql */ #endif /* _MYSQL_NATIVE_DRIVER_WRAPPER_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_resultset_wrapper.cpp000644 015771 000012 00000006035 12645244436 030333 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_native_resultset_wrapper.h" #include "mysql_client_api.h" namespace sql { namespace mysql { class MySQL_DebugLogger; class MySQL_ConnectionMetaData; namespace NativeAPI { /* {{{ MySQL_NativeResultsetWrapper::MySQL_NativeResultsetWrapper */ MySQL_NativeResultsetWrapper::MySQL_NativeResultsetWrapper(::st_mysql_res * res, boost::shared_ptr< NativeAPI::IMySQLCAPI > & _capi /*, boost::shared_ptr< MySQL_DebugLogger > & l*/) : /*logger(l),*/ capi(_capi), rs(res) { } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::~MySQL_NativeResultsetWrapper */ MySQL_NativeResultsetWrapper::~MySQL_NativeResultsetWrapper() { capi->free_result(rs); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::data_seek */ void MySQL_NativeResultsetWrapper::data_seek(uint64_t offset) { capi->data_seek(rs, offset); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::fetch_field */ ::st_mysql_field * MySQL_NativeResultsetWrapper::fetch_field() { return capi->fetch_field(rs); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::fetch_field_direct */ ::st_mysql_field * MySQL_NativeResultsetWrapper::fetch_field_direct(unsigned int field_nr) { return capi->fetch_field_direct(rs, field_nr); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::fetch_lengths */ unsigned long * MySQL_NativeResultsetWrapper::fetch_lengths() { return capi->fetch_lengths(rs); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::fetch_row */ char** MySQL_NativeResultsetWrapper::fetch_row() { return capi->fetch_row(rs); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::num_fields */ unsigned int MySQL_NativeResultsetWrapper::num_fields() { return capi->num_fields(rs); } /* }}} */ /* {{{ MySQL_NativeResultsetWrapper::num_rows */ uint64_t MySQL_NativeResultsetWrapper::num_rows() { return capi->num_rows(rs); } /* }}} */ } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_resultset_wrapper.h000644 015771 000012 00000004455 12645244436 030004 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_NativeResultsetWrapper_H_ #define _MYSQL_NativeResultsetWrapper_H_ #include #include "native_resultset_wrapper.h" struct st_mysql_res; namespace sql { namespace mysql { class MySQL_DebugLogger; namespace NativeAPI { class IMySQLCAPI; class MySQL_NativeResultsetWrapper : public NativeResultsetWrapper { public: MySQL_NativeResultsetWrapper(::st_mysql_res *, boost::shared_ptr &/*, boost::shared_ptr< MySQL_DebugLogger > & l*/); ~MySQL_NativeResultsetWrapper(); void data_seek(uint64_t); ::st_mysql_field * fetch_field(); ::st_mysql_field * fetch_field_direct(unsigned int); unsigned long * fetch_lengths(); char** fetch_row(); unsigned int num_fields(); uint64_t num_rows(); //boost::shared_ptr getApiHandle(); private: MySQL_NativeResultsetWrapper(){} //Also need to decide should it be copyable boost::shared_ptr< MySQL_DebugLogger > logger; boost::shared_ptr< NativeAPI::IMySQLCAPI > capi; ::st_mysql_res * rs; }; } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #endif // _MYSQL_RESULTSET_DATA_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_statement_wrapper.cpp000644 015771 000012 00000013431 12645244436 030303 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "mysql_client_api.h" #include "mysql_native_statement_wrapper.h" #include "mysql_native_resultset_wrapper.h" #include "native_connection_wrapper.h" #include "../mysql_util.h" namespace sql { namespace mysql { namespace NativeAPI { /* * * * */ /* {{{ MySQL_NativeStatementWrapper::MySQL_NativeStatementWrapper() */ MySQL_NativeStatementWrapper::MySQL_NativeStatementWrapper(::st_mysql_stmt * _stmt, boost::shared_ptr _api, NativeConnectionWrapper * connProxy) : api (_api), stmt(_stmt), conn(connProxy) { } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::~MySQL_NativeStatementWrapper() */ MySQL_NativeStatementWrapper::~MySQL_NativeStatementWrapper() { api->stmt_close(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::affected_rows() */ uint64_t MySQL_NativeStatementWrapper::affected_rows() { return api->stmt_affected_rows(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::attr_set */ bool MySQL_NativeStatementWrapper::attr_set(MySQL_Statement_Options option, const void *arg) { return (api->stmt_attr_set(stmt, static_cast< enum_stmt_attr_type >(option), arg) != '\0'); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::bind_param() */ bool MySQL_NativeStatementWrapper::bind_param(::st_mysql_bind * bind ) { return (api->stmt_bind_param(stmt, bind) != '\0'); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::bind_result() */ bool MySQL_NativeStatementWrapper::bind_result(::st_mysql_bind * bind) { return (api->stmt_bind_result(stmt, bind) != '\0'); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::data_seek() */ void MySQL_NativeStatementWrapper::data_seek(uint64_t offset) { api->stmt_data_seek(stmt, offset); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::errNo() */ unsigned int MySQL_NativeStatementWrapper::errNo() { return api->stmt_errno(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::error() */ ::sql::SQLString MySQL_NativeStatementWrapper::error() { return api->stmt_error(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::execute() */ int MySQL_NativeStatementWrapper::execute() { return api->stmt_execute(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::fetch() */ int MySQL_NativeStatementWrapper::fetch() { return api->stmt_fetch(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::field_count() */ unsigned int MySQL_NativeStatementWrapper::field_count() { return api->stmt_field_count(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::more_results() */ bool MySQL_NativeStatementWrapper::more_results() { return conn->more_results(); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::next_result() */ int MySQL_NativeStatementWrapper::next_result() { return conn->next_result(); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::num_rows() */ uint64_t MySQL_NativeStatementWrapper::num_rows() { return api->stmt_num_rows(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::param_count() */ unsigned long MySQL_NativeStatementWrapper::param_count() { return api->stmt_param_count(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::prepare() */ int MySQL_NativeStatementWrapper::prepare(const ::sql::SQLString & stmt_str) { return api->stmt_prepare(stmt, stmt_str.c_str(), stmt_str.length()); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::result_metadata() */ NativeResultsetWrapper * MySQL_NativeStatementWrapper::result_metadata() { ::st_mysql_res * raw = api->stmt_result_metadata(stmt); if (raw == NULL) { return NULL; } return new MySQL_NativeResultsetWrapper(raw, api); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::send_long_data() */ bool MySQL_NativeStatementWrapper::send_long_data(unsigned int par_number, const char * data, unsigned long len) { return api->stmt_send_long_data(stmt, par_number, data, len) != '\0'; } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::sqlstate() */ ::sql::SQLString MySQL_NativeStatementWrapper::sqlstate() { return api->stmt_sqlstate(stmt); } /* {{{ MySQL_NativeStatementWrapper::store_result() */ int MySQL_NativeStatementWrapper::store_result() { return api->stmt_store_result(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::next_result() */ int MySQL_NativeStatementWrapper::stmt_next_result() { return api->stmt_next_result(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::stmt_free_result() */ bool MySQL_NativeStatementWrapper::stmt_free_result() { return api->stmt_free_result(stmt); } /* }}} */ /* {{{ MySQL_NativeStatementWrapper::warning_count() */ unsigned int MySQL_NativeStatementWrapper::warning_count() { return conn->warning_count(); } /* }}} */ } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_native_statement_wrapper.h000644 015771 000012 00000005066 12645244436 027755 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYSQL_NativeStatementWrapper_H_ #define _MYSQL_NativeStatementWrapper_H_ #include #include "native_statement_wrapper.h" struct st_mysql_stmt; namespace sql { namespace mysql { namespace NativeAPI { class IMySQLCAPI; class NativeConnectionWrapper; /* * * * */ class MySQL_NativeStatementWrapper : public NativeStatementWrapper { boost::shared_ptr api; ::st_mysql_stmt * stmt; NativeConnectionWrapper * conn; MySQL_NativeStatementWrapper(){} public: MySQL_NativeStatementWrapper(::st_mysql_stmt *, boost::shared_ptr, NativeConnectionWrapper * connProxy); ~MySQL_NativeStatementWrapper(); uint64_t affected_rows(); bool attr_set(MySQL_Statement_Options option, const void *arg); bool bind_param(::st_mysql_bind *); bool bind_result(::st_mysql_bind *); void data_seek(uint64_t ); unsigned int errNo(); sql::SQLString error(); int execute (); int fetch(); unsigned int field_count(); bool more_results(); int next_result(); uint64_t num_rows(); unsigned long param_count(); int prepare (const ::sql::SQLString &); NativeResultsetWrapper * result_metadata(); bool send_long_data(unsigned int par_number, const char * data, unsigned long len); ::sql::SQLString sqlstate(); int store_result(); int stmt_next_result(); bool stmt_free_result(); unsigned int warning_count(); }; } } } #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/mysql_private_iface.h000644 015771 000012 00000004254 12645244436 025442 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MYSQL_PRIVATE_IFACE_H #define MYSQL_PRIVATE_IFACE_H #if !defined(bool) #define WE_DEFINE_BOOL_TO_SKIP_LIBMYSQL #define bool #endif #if !defined(max) #define WE_DEFINE_MAX_TO_SKIP_LIBMYSQL #define max #endif #if ( defined(_WIN32) || defined(_WIN64) ) && defined(WE_DEFINE_BOOL_TO_SKIP_LIBMYSQL) #undef bool #endif #if ( defined(_WIN32) || defined(_WIN64) ) && defined(WE_DEFINE_MAX_TO_SKIP_LIBMYSQL) #undef max #endif #if ( defined(_WIN32) || defined(_WIN64) ) && !defined(snprintf) #define snprintf _snprintf #endif #if !defined(_WIN32) && !defined(_WIN64) extern "C" { #endif #if defined(_WIN32) #include #endif #if A0_IF_WE_NEED_GET_CHARSET_FROM_LIBMYSQL #include #endif #include #include #if !defined(_WIN32) && !defined(_WIN64) } #endif /* my_global.h introduces bool and max */ #ifdef WE_DEFINE_BOOL_TO_SKIP_LIBMYSQL #undef bool #undef WE_DEFINE_BOOL_TO_SKIP_LIBMYSQL #endif #ifdef WE_DEFINE_MAX_TO_SKIP_LIBMYSQL #undef max #undef WE_DEFINE_MAX_TO_SKIP_LIBMYSQL #endif #if defined(_WIN32) || defined(_WIN64) #pragma warning(disable:4251) #endif #endif /* MYSQL_PRIVATE_IFACE_H */ mysql-connector-c++-1.1.7/driver/nativeapi/native_connection_wrapper.h000644 015771 000012 00000010441 12645244436 026654 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _NATIVE_CONNECTION_WRAPPER_H_ #define _NATIVE_CONNECTION_WRAPPER_H_ #include #include #ifdef HAVE_STDINT_H #include #endif #include "../mysql_connection_options.h" namespace sql { class SQLString; namespace mysql { namespace NativeAPI { class NativeResultsetWrapper; class NativeStatementWrapper; enum Protocol_Type { PROTOCOL_TCP, PROTOCOL_SOCKET, PROTOCOL_PIPE, /* Total number of supported protocol types */ PROTOCOL_COUNT }; class NativeConnectionWrapper : public boost::noncopyable { public: virtual ~NativeConnectionWrapper() {} virtual uint64_t affected_rows() = 0; virtual bool autocommit(bool) = 0; virtual bool connect(const ::sql::SQLString & host, const ::sql::SQLString & user, const ::sql::SQLString & passwd, const ::sql::SQLString & db, unsigned int port, const ::sql::SQLString & socket_or_pipe, unsigned long client_flag) = 0; virtual bool commit() = 0; virtual void debug(const ::sql::SQLString &) = 0; virtual unsigned int errNo() = 0; virtual ::sql::SQLString error() = 0; virtual ::sql::SQLString escapeString(const ::sql::SQLString &) = 0; virtual unsigned int field_count() = 0; virtual unsigned long get_client_version() = 0; virtual const ::sql::SQLString & get_server_info() = 0; virtual unsigned long get_server_version() = 0; virtual void get_character_set_info(void *cs) = 0; virtual bool more_results() = 0; virtual int next_result() = 0; virtual int options(::sql::mysql::MySQL_Connection_Options, const void *) = 0; virtual int options(::sql::mysql::MySQL_Connection_Options, const ::sql::SQLString &) = 0; virtual int options(::sql::mysql::MySQL_Connection_Options, const bool &) = 0; virtual int options(::sql::mysql::MySQL_Connection_Options, const int &) = 0; virtual int options(::sql::mysql::MySQL_Connection_Options, const ::sql::SQLString &, const ::sql::SQLString &) = 0; virtual int get_option(::sql::mysql::MySQL_Connection_Options, const void *) = 0; virtual int get_option(::sql::mysql::MySQL_Connection_Options, const ::sql::SQLString &) = 0; virtual int get_option(::sql::mysql::MySQL_Connection_Options, const bool &) = 0; virtual int get_option(::sql::mysql::MySQL_Connection_Options, const int &) = 0; virtual int query(const SQLString &) = 0; virtual int ping() = 0; /* virtual int real_query(const SQLString &, uint64_t) = 0;*/ virtual bool rollback() = 0; virtual ::sql::SQLString sqlstate() = 0; virtual ::sql::SQLString info() = 0; virtual bool ssl_set(const ::sql::SQLString & key, const ::sql::SQLString & cert, const ::sql::SQLString & ca, const ::sql::SQLString & capath, const ::sql::SQLString & cipher) = 0; virtual NativeResultsetWrapper * store_result() = 0; virtual int use_protocol(Protocol_Type) = 0; virtual NativeResultsetWrapper * use_result() = 0; virtual NativeStatementWrapper & stmt_init() = 0; virtual unsigned int warning_count() = 0; }; } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #endif /* _NATIVE_CONNECTION_WRAPPER_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/native_driver_wrapper.h000644 015771 000012 00000003534 12645244436 026015 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _NATIVE_DRIVER_WRAPPER_H_ #define _NATIVE_DRIVER_WRAPPER_H_ #include #include #ifdef HAVE_STDINT_H #include #endif namespace sql { namespace mysql { namespace NativeAPI { class NativeConnectionWrapper; class NativeDriverWrapper : public boost::noncopyable { public: virtual ~NativeDriverWrapper(){} virtual NativeConnectionWrapper & conn_init() = 0; virtual void thread_end() = 0; virtual void thread_init() = 0; }; NativeDriverWrapper * createNativeDriverWrapper(const SQLString & clientFileName); } /* namespace NativeAPI*/ } /* namespace mysql */ } /* namespace sql */ #endif // _NATIVE_DRIVER_WRAPPER_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/native_resultset_wrapper.h000644 015771 000012 00000003717 12645244436 026557 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _NATIVE_RESULTSET_WRAPPER_H_ #define _NATIVE_RESULTSET_WRAPPER_H_ #include #include #ifdef HAVE_STDINT_H #include #endif struct st_mysql_field; namespace sql { namespace mysql { namespace NativeAPI { class NativeResultsetWrapper : public boost::noncopyable { public: virtual ~NativeResultsetWrapper(){} virtual void data_seek(uint64_t) = 0; virtual ::st_mysql_field * fetch_field() = 0; virtual ::st_mysql_field * fetch_field_direct(unsigned int) = 0; virtual unsigned long * fetch_lengths() = 0; virtual char** fetch_row() = 0; virtual unsigned int num_fields() = 0; virtual uint64_t num_rows() = 0; }; } /* namespace NativeAPI*/ } /* namespace mysql */ } /* namespace sql */ #endif // _NATIVE_RESULTSET_WRAPPER_H_ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/nativeapi/native_statement_wrapper.h000644 015771 000012 00000005442 12645244436 026526 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _NATIVE_STATEMENT_WRAPPER_H_ #define _NATIVE_STATEMENT_WRAPPER_H_ #include #include #ifdef HAVE_STDINT_H #include #endif #include "../mysql_statement_options.h" struct st_mysql_bind; struct st_mysql_res; namespace sql { class SQLString; namespace mysql { namespace NativeAPI { class NativeResultsetWrapper; /* * * * */ class NativeStatementWrapper : public boost::noncopyable { public: virtual ~NativeStatementWrapper(){} virtual uint64_t affected_rows() = 0; virtual bool attr_set(MySQL_Statement_Options attr, const void *arg) = 0; virtual bool bind_param(::st_mysql_bind *) = 0; virtual bool bind_result(::st_mysql_bind *) = 0; virtual void data_seek(uint64_t) = 0; virtual unsigned int errNo() = 0; virtual ::sql::SQLString error() = 0; virtual int execute() = 0; virtual int fetch() = 0; virtual unsigned int field_count() = 0; virtual bool more_results() = 0; virtual int next_result() = 0; virtual uint64_t num_rows() = 0; virtual unsigned long param_count() = 0; virtual int prepare(const ::sql::SQLString &) = 0; virtual NativeResultsetWrapper * result_metadata () = 0; virtual bool send_long_data(unsigned int par_number, const char * data, unsigned long len) = 0; virtual ::sql::SQLString sqlstate() = 0; virtual int store_result() = 0; virtual int stmt_next_result() = 0; virtual bool stmt_free_result() = 0; /* some enhancements comparing to mysql api */ virtual unsigned int warning_count() = 0; }; } /* namespace NativeAPI */ } /* namespace mysql */ } /* namespace sql */ #endif /* _NATIVE_STATEMENT_WRAPPER_H_ */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/driver/version_info.h.cmake000644 015771 000012 00000003567 12645244436 023221 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* @EDIT_WARNING_MESSAGE@ */ #define MYCPPCONN_MAJOR_VERSION @CONNECTOR_MAJOR@ #define MYCPPCONN_MINOR_VERSION @CONNECTOR_MINOR@ #define MYCPPCONN_PATCH_VERSION @CONNECTOR_PATCH@ #define SETUP_VERSION "@CONNECTOR_MAJOR@.@CONNECTOR_MINOR_PADDED@.@CONNECTOR_PATCH_PADDED@" #define DRIVER_VERSION "0" SETUP_VERSION #define MYCPPCONN_VERSION SETUP_VERSION #define MYCPPCONN_FILEVER @CONNECTOR_MAJOR@,@CONNECTOR_MINOR@,@CONNECTOR_PATCH@,0 #define MYCPPCONN_PRODUCTVER MYCPPCONN_FILEVER #define MYCPPCONN_STRFILEVER "@CONNECTOR_MAJOR@, @CONNECTOR_MINOR@, @CONNECTOR_PATCH@, 0\0" #define MYCPPCONN_STRPRODUCTVER MYCPPCONN_STRFILEVER #define MYCPPCONN_STRSERIES "@CONNECTOR_MAJOR@.@CONNECTOR_MINOR@" #define MYCPPCONN_STRQUALITY "@CONNECTOR_QUALITY@" #define MYCPPCONN_STRVERSION "@CONNECTOR_VERSION@" mysql-connector-c++-1.1.7/examples/CMakeLists.txt000755 015771 000012 00000022350 12645244436 022346 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(CMAKE_VERBOSE_MAKEFILE 0) SET(MYSQLCPPCONN_BUILD_EXAMPLES 1 CACHE BOOL "build-examples") IF(MYSQLCPPCONN_BUILD_EXAMPLES) LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/cppconn) IF(WIN32) IF(CMAKE_BUILD_TYPE STREQUAL "Debug") LINK_DIRECTORIES(${MYSQL_DIR}/lib/debug) ELSEIF(CMAKE_BUILD_TYPE STREQUAL "") LINK_DIRECTORIES(${MYSQL_DIR}/lib/opt) ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn) IF(MYSQLCLIENT_STATIC_BINDING) SET(MY_TARGET_LINK_LIBRARIES ${MY_TARGET_LINK_LIBRARIES}) ENDIF(MYSQLCLIENT_STATIC_BINDING) SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") FIND_LIBRARY(MYSQLCPPCONN_DYNLOAD_MYSQL_LIB NAMES libmysql PATHS ${MYSQL_LIB_DIR} ${MYSQL_LIB_DIR}/lib/${libsuffixDist} ${MYSQL_LIB_DIR}/lib #mysqlclient may be in lib for some c/c distros ${MYSQL_LIB_DIR}/libmysql/${libsuffixBuild} ${MYSQL_LIB_DIR}/client/${libsuffixBuild} $ENV{MYSQL_LIB_DIR} $ENV{MYSQL_LIB_DIR}/lib/${libsuffixDist} $ENV{MYSQL_LIB_DIR}/lib #mysqlclient may be in lib for some c/c distros $ENV{MYSQL_LIB_DIR}/libmysql/${libsuffixBuild} $ENV{MYSQL_LIB_DIR}/client/${libsuffixBuild} $ENV{MYSQL_DIR}/lib/${libsuffixDist} $ENV{MYSQL_DIR}/lib #mysqlclient may be in lib for some c/c distros $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} $ENV{MYSQL_DIR}/client/${libsuffixBuild} $ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist} $ENV{ProgramFiles}/MySQL/*/lib $ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist} $ENV{SystemDrive}/MySQL/*/lib NO_DEFAULT_PATH ) ELSEIF(NOT WIN32) SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn-static) IF(MYSQLCLIENT_STATIC_BINDING) SET(MY_TARGET_LINK_LIBRARIES ${MY_TARGET_LINK_LIBRARIES}) ENDIF(MYSQLCLIENT_STATIC_BINDING) FIND_LIBRARY(MYSQLCPPCONN_DYNLOAD_MYSQL_LIB NAMES libmysqlclient_r.so libmysqlclient.so PATHS ${MYSQL_LIB_DIR} ${MYSQL_LIB_DIR}/libmysql_r/.libs ${MYSQL_LIB_DIR}/lib ${MYSQL_LIB_DIR}/lib/mysql $ENV{MYSQL_LIB_DIR} $ENV{MYSQL_LIB_DIR}/libmysql_r/.libs $ENV{MYSQL_LIB_DIR}/lib $ENV{MYSQL_LIB_DIR}/lib/mysql $ENV{MYSQL_DIR}/libmysql_r/.libs $ENV{MYSQL_DIR}/lib $ENV{MYSQL_DIR}/lib/mysql ${MYSQL_CLIB_DIR} ${MYSQL_CLIB_DIR}/libmysql_r/.libs ${MYSQL_CLIB_DIR}/lib ${MYSQL_CLIB_DIR}/lib/mysql /usr/lib/mysql /usr/local/lib/mysql /usr/local/mysql/lib /usr/local/mysql/lib/mysql /opt/mysql/mysql/lib /opt/mysql/mysql/lib/mysql NO_DEFAULT_PATH ) ENDIF(WIN32) ADD_DEFINITIONS("-DDYNLOAD_MYSQL_LIB=\"${MYSQLCPPCONN_DYNLOAD_MYSQL_LIB}\"") MESSAGE(STATUS "MySQL dynamic load test library: ${MYSQLCPPCONN_DYNLOAD_MYSQL_LIB}") IF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(MY_GCOV_LINK_LIBRARIES gcov) ENDIF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) ADD_EXECUTABLE(connect connect.cpp) SET_TARGET_PROPERTIES(connect PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(connect ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(connection_meta_schemaobj connection_meta_schemaobj.cpp) SET_TARGET_PROPERTIES(connection_meta_schemaobj PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(connection_meta_schemaobj ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(debug_output debug_output.cpp) SET_TARGET_PROPERTIES(debug_output PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(debug_output ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(exceptions exceptions.cpp) SET_TARGET_PROPERTIES(exceptions PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(exceptions ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(prepared_statement prepared_statement.cpp) SET_TARGET_PROPERTIES(prepared_statement PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(prepared_statement ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(resultset resultset.cpp) SET_TARGET_PROPERTIES(resultset PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(resultset ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(resultset_binary resultset_binary.cpp) SET_TARGET_PROPERTIES(resultset_binary PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(resultset_binary ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(resultset_meta resultset_meta.cpp) SET_TARGET_PROPERTIES(resultset_meta PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(resultset_meta ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(resultset_types resultset_types.cpp) SET_TARGET_PROPERTIES(resultset_types PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(resultset_types ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(statement statement.cpp) SET_TARGET_PROPERTIES(statement PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(statement ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ADD_EXECUTABLE(dynamic_load dynamic_load.cpp) SET_TARGET_PROPERTIES(dynamic_load PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(dynamic_load ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES} ${MYSQLCPPCONN_BOOST_SYSTEM_LIBS} ${MYSQLCPPCONN_BOOST_THREAD_LIBS} ${MYSQLCPPCONN_ICU_LIBRARY}) ENDIF(MYSQLCPPCONN_BUILD_EXAMPLES) MESSAGE(STATUS "Configuring examples") mysql-connector-c++-1.1.7/examples/README000644 015771 000012 00000001055 12645244436 020462 0ustar00pb2userwheel000000 000000 The directory examples/ contains basic usage examples of the MySQL Connector/C++. In order to compile and run them you must have a MySQL server installed. By default the examples will try to connect to a MySQL server on the host "127.0.0.1" at port "3306" using the username "root" and the password "root" to access the database "test". You can change the connection properties in example.h Its possible to specify alternative connection parameters using command line parameters: example_program tcp://[:] [username] [password] [database] mysql-connector-c++-1.1.7/examples/connect.cpp000644 015771 000012 00000020424 12645244436 021740 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Basic example demonstrating connect and simple queries * */ // Standard C++ includes #include #include #include #include #include /* Public interface of the MySQL Connector/C++. You might not use it but directly include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include /* Connection parameter and sample data */ #include "examples.h" using namespace std; /** * Usage example for Driver, Connection, (simple) Statement, ResultSet */ int main(int argc, const char **argv) { string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* sql::ResultSet.rowsCount() returns size_t */ size_t row; stringstream sql; stringstream msg; int i, affected_rows; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ connect basic usage example.." << endl; cout << "#" << endl; try { sql::Driver * driver = sql::mysql::get_driver_instance(); /* Using the Driver to create a connection */ boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); /* Creating a "simple" statement - "simple" = not a prepared statement */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); /* Create a test table demonstrating the use of sql::Statement.execute() */ stmt->execute("USE " + database); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, label CHAR(1))"); cout << "#\t Test table created" << endl; /* Populate the test table with data */ for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { /* KLUDGE: You should take measures against SQL injections! example.h contains the test data */ sql.str(""); sql << "INSERT INTO test(id, label) VALUES ("; sql << test_data[i].id << ", '" << test_data[i].label << "')"; stmt->execute(sql.str()); } cout << "#\t Test table populated" << endl; { /* Run a query which returns exactly one result set like SELECT Stored procedures (CALL) may return more than one result set */ boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC")); cout << "#\t Running 'SELECT id, label FROM test ORDER BY id ASC'" << endl; /* Number of rows in the result set */ cout << "#\t\t Number of rows\t"; cout << "res->rowsCount() = " << res->rowsCount() << endl; if (res->rowsCount() != EXAMPLE_NUM_TEST_ROWS) { msg.str(""); msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, found " << res->rowsCount(); throw runtime_error(msg.str()); } /* Fetching data */ row = 0; while (res->next()) { cout << "#\t\t Fetching row " << row << "\t"; /* You can use either numeric offsets... */ cout << "id = " << res->getInt(1); /* ... or column names for accessing results. The latter is recommended. */ cout << ", label = '" << res->getString("label") << "'" << endl; row++; } } { /* Fetching again but using type convertion methods */ boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id FROM test ORDER BY id DESC")); cout << "#\t Fetching 'SELECT id FROM test ORDER BY id DESC' using type conversion" << endl; row = 0; while (res->next()) { cout << "#\t\t Fetching row " << row; cout << "#\t id (int) = " << res->getInt("id"); cout << "#\t id (boolean) = " << res->getBoolean("id"); cout << "#\t id (long) = " << res->getInt64("id") << endl; row++; } } /* Usage of UPDATE */ stmt->execute("INSERT INTO test(id, label) VALUES (100, 'z')"); affected_rows = stmt->executeUpdate("UPDATE test SET label = 'y' WHERE id = 100"); cout << "#\t UPDATE indicates " << affected_rows << " affected rows" << endl; if (affected_rows != 1) { msg.str(""); msg << "Expecting one row to be changed, but " << affected_rows << "change(s) reported"; throw runtime_error(msg.str()); } { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id, label FROM test WHERE id = 100")); res->next(); if ((res->getInt("id") != 100) || (res->getString("label") != "y")) { msg.str("Update must have failed, expecting 100/y got"); msg << res->getInt("id") << "/" << res->getString("label"); throw runtime_error(msg.str()); } cout << "#\t\t Expecting id = 100, label = 'y' and got id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; } /* Clean up */ stmt->execute("DROP TABLE IF EXISTS test"); stmt.reset(NULL); /* free the object inside */ cout << "#" << endl; cout << "#\t Demo of connection URL syntax" << endl; try { /*s This will implicitly assume that the host is 'localhost' */ url = "unix://path_to_mysql_socket.sock"; con.reset(driver->connect(url, user, pass)); } catch (sql::SQLException &e) { cout << "#\t\t unix://path_to_mysql_socket.sock caused expected exception" << endl; cout << "#\t\t " << e.what() << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } try { url = "tcp://hostname_or_ip[:port]"; con.reset(driver->connect(url, user, pass)); } catch (sql::SQLException &e) { cout << "#\t\t tcp://hostname_or_ip[:port] caused expected exception" << endl; cout << "#\t\t " << e.what() << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } try { /* Note: in the MySQL C-API host = localhost would cause a socket connection! Not so with the C++ Connector. The C++ Connector will translate tcp://localhost into tcp://127.0.0.1 and give you a TCP connection url = "tcp://localhost[:port]"; */ con.reset(driver->connect(url, user, pass)); } catch (sql::SQLException &e) { cout << "#\t\t tcp://hostname_or_ip[:port] caused expected exception" << endl; cout << "#\t\t " << e.what() << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } cout << "# done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what() (derived from std::runtime_error) to fetch the error message */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/connect.php" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/connect.php" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/connect.php" << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/connection_meta_schemaobj.cpp000644 015771 000012 00000025562 12645244436 025477 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Basic example demonstrating connect and simple queries * */ /* Standard C++ includes */ #include #include #include #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" using namespace std; /** * Usage example for Driver, Connection, (simple) Statement, ResultSet */ int main(int argc, const char **argv) { string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); static std::list< sql::SQLString > table_types; table_types.push_back("TABLE"); unsigned int column, row; string ddl; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ connection meta data example.." << endl; cout << "#" << endl; try { /* Using the Driver to create a connection */ sql::Driver * driver = sql::mysql::get_driver_instance(); cout << "# " << driver->getName() << ", version "; cout << driver->getMajorVersion() << "." << driver->getMinorVersion(); cout << "." << driver->getPatchVersion() << endl; boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); sql::DatabaseMetaData * con_meta = con->getMetaData(); cout << "# CDBC (API) major version = " << con_meta->getCDBCMajorVersion() << endl; if (con_meta->getCDBCMajorVersion() <= 0) { throw runtime_error("API major version must not be 0"); } cout << "# CDBC (API) minor version = " << con_meta->getCDBCMinorVersion() << endl; { /* Which schemata/databases exist? NOTE Connector C++ defines catalog = n/a, schema = MySQL database */ cout << "# List of available schemata/databases: "; boost::scoped_ptr< sql::ResultSet > res(con_meta->getSchemas()); /* just for fun... of course you can scroll and fetch in whatever order you want */ res->afterLast(); while (res->previous()) { cout << res->getString("TABLE_SCHEM"); if (!res->isFirst()) { cout << ", "; } } cout << endl; if (!res->isBeforeFirst() || res->isFirst()) throw runtime_error("Cursor should be positioned before first row"); } { /* What object types does getSchemaObjects support? */ cout << "# Supported Object types: "; boost::scoped_ptr< sql::ResultSet > res(con_meta->getSchemaObjectTypes()); while (res->next()) { cout << res->getString(1); if (!res->isLast()) { cout << ", "; } } cout << endl; if (!res->isAfterLast() || res->isLast()) throw runtime_error("Cursor should be positioned after last row"); } boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("USE " + database); stmt->execute("DROP TABLE IF EXISTS test1"); stmt->execute("CREATE TABLE test1(id INT, label CHAR(1))"); stmt->execute("DROP TABLE IF EXISTS test2"); stmt->execute("CREATE TABLE test2(id INT, label CHAR(1))"); /* "" = empty string requests all types of objects */ boost::scoped_ptr< sql::ResultSet > res(con_meta->getSchemaObjects(con->getCatalog(), con->getSchema(), "")); row = 1; sql::ResultSetMetaData * res_meta = res->getMetaData(); while (res->next()) { if (row++ > 2) break; cout << "#\t Object " << res->getRow() << " (" << res->getString("OBJECT_TYPE") << ")" << endl; if (res->getString(1) != res->getString("OBJECT_TYPE")) { throw runtime_error("Fetch using numeric/non-numeric index failed for OBJECT_TYPE"); } if (res->getString("OBJECT_TYPE").length() == 0) { throw runtime_error("OBJECT_TYPE must not be empty"); } cout << "#\t Catalog = " << res->getString("CATALOG"); cout << " (empty: " << (res->getString("CATALOG").length() == 0) << ")" << endl; if (res->getString(2) != res->getString("CATALOG")) { throw runtime_error("Fetch using numeric/non-numeric index failed for CATALOG"); } cout << "#\t Schema = " << res->getString("SCHEMA"); cout << " (empty: " << (res->getString("SCHEMA").length() == 0) << ")" << endl; if (res->getString(3) != res->getString("SCHEMA")) { throw runtime_error("Fetch using numeric/non-numeric index failed for SCHEMA"); } cout << "#\t Name = " << res->getString("NAME"); cout << " (empty: " << (res->getString("NAME").length() == 0) << ")" << endl; if (res->getString(4) != res->getString("NAME")) { throw runtime_error("Fetch using numeric/non-numeric index failed for NAME"); } ddl = res->getString("DDL"); cout << "#\t DDL = " << setw(40); cout << ddl.substr(0, ddl.find_first_of("\n", 1) - 1) << "..." << endl; cout << "#\t DDL is empty: " << ddl.empty() << endl; if (res->getString(5) != res->getString("DDL")) { throw runtime_error("Fetch using numeric/non-numeric index failed for DDL"); } } cout << "#" << endl; cout << "#\t\t Using different getter methods at the example of the DDL column" << endl; cout << "#\t\t Column DDL is of type " << res_meta->getColumnTypeName(5); cout << " / Code: " << res_meta->getColumnType(5) << endl; /* scroll back to last row in set */ res->previous(); cout << "#\t\t DDL (as String) = " << setw(30) << ddl.substr(0, ddl.find_first_of("\n", 1) - 1) << "..." << endl; cout << "#\t\t DDL (as Boolean) = " << res->getBoolean("DDL") << "/" << res->getBoolean(5) << endl; cout << "#\t\t DDL (as Double) = " << res->getDouble("DDL") << "/" << res->getDouble(5) << endl; cout << "#\t\t DDL (as Int) = " << res->getInt("DDL") << "/" << res->getInt(5) << endl; cout << "#\t\t DDL (as Long) = " << res->getInt64("DDL") << "/" << res->getInt64(5) << endl; cout << "#" << endl; cout << "#\t\t Meta data on the result set at the example of the DDL column" << endl; cout << "#\t\t Column count = " << res_meta->getColumnCount() << " (Columns: "; for (column = 1; column <= res_meta->getColumnCount(); column++) { cout << res_meta->getColumnName(column); if (column < res_meta->getColumnCount()) { cout << ", "; } } cout << ")" << endl; cout << "#\t\t getCatalogName() = " << res_meta->getCatalogName(5) << endl; /* cout << "#\t\t getColumnDisplaySize() = " << res_meta->getDisplaySize("DDL") << endl; */ cout << "#\t\t getColumnLabel() = " << res_meta->getColumnLabel(5) << endl; cout << "#\t\t getColumnName() = " << res_meta->getColumnName(5) << endl; if (res_meta->getColumnName(5) != res_meta->getColumnLabel(5)) { throw runtime_error("column names differ for column DDL"); } cout << "#\t\t getColumnType() = " << res_meta->getColumnType(5) << endl; cout << "#\t\t getColumnTypeName() " << res_meta->getColumnTypeName(5) << endl; /* cout << "#\t\t getPrecision() = " << res_meta->getPrecision(5) << endl; */ cout << "#\t\t getSchemaName() = " << res_meta->getSchemaName(5) << endl; cout << "#\t\t getTableName() = " << res_meta->getTableName(5) << endl; cout << "#\t\t isAutoIncrement() = " << res_meta->isAutoIncrement(5) << endl; cout << "#\t\t isCaseSensitive() = " << res_meta->isCaseSensitive(5) << endl; cout << "#\t\t isCurrency() = " << res_meta->isCurrency(5) << endl; cout << "#\t\t isDefinitelyWritable() = " << res_meta->isDefinitelyWritable(5) << endl; cout << "#\t\t isNullable() = " << res_meta->isNullable(5) << endl; cout << "#\t\t isReadOnly() = " << res_meta->isReadOnly(5) << endl; cout << "#\t\t isSearchable() = " << res_meta->isSearchable(5) << endl; cout << "#\t\t isSigned() = " << res_meta->isSigned(5) << endl; cout << "#\t\t isWritable() = " << res_meta->isWritable(5) << endl; boost::scoped_ptr< sql::ResultSet > res_tables(con_meta->getTables(con->getCatalog(), database, "t%", table_types)); sql::ResultSetMetaData * res_meta_tables = res_tables->getMetaData(); cout << "#" << endl; cout << "# Tables with names like 't%':" << endl;; cout << "#\t rowsCount() = " << res_tables->rowsCount() << endl; cout << "#\t getColumnCount() = " << res_meta_tables->getColumnCount() << endl; cout << "#\t" << endl; while (res_tables->next()) { cout << "#\t "; for (column = 1; column < res_meta_tables->getColumnCount(); column++) { cout << "'" << res_tables->getString(column) << "' "; } cout << endl; } cout << "#" << endl; res_tables->first(); boost::scoped_ptr< sql::ResultSet > res_columns(con_meta->getColumns(con->getCatalog(), database, "test1", "%")); cout << "#" << "Columns in the table 'test1'..." << endl; cout << "#\t rowsCount() = " << res_columns->rowsCount() << endl; if (res_columns->rowsCount() != 2) throw runtime_error("Table test1 has two columns, no more!"); while (res_columns->next()) { cout << "#\t Column name = '" << res_columns->getString("COLUMN_NAME") << "'" << endl; } cout << "#" << endl; cout << "# done!" << endl; cout << "ok 1 - examples/connection_meta_schemaobj.cpp" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what() (derived from std::runtime_error) */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/connection_meta_schemaobj.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/connection_meta_schemaobj.cpp" << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/cpp_trace_analyzer.php000644 015771 000012 00000036772 12645244436 024176 0ustar00pb2userwheel000000 000000 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Script to filter Connector/C++ (and Connector/OpenOffice.org) debug traces * * NOTE: NO SUPPORT FOR THIS SCRIPT * NOTE: FIX BUGS YOURSELF! * * MySQL Connector/C++ offers several debug traces, The internal debug trace is * a call trace. It shows each and every function call and sometimes * the function arguments and other related information. * * Example: * | INF: Tracing enabled * MySQL_Prepared_Statement::setInt * | INF: this=0x69a2e0 * | >MySQL_Prepared_Statement::checkClosed * | // * * - number of the line in the input file which causes the output * - see -t trace_nesting_level * - line number the line in the the generated output * * * -t trace_nesting_level * * Show only information up to a function call depth of -t . * Nesting starts at level 1. If you apply -t 1 to the above example trace, * the calls to MySQL_Prepared_Statement::checkClosed and * MySQL_Prepared_Statement::setInt should not be shown, because they are * on nesting level 2. * * * -s show_function * * Show only classes and methods that apply to the pattern -s . * To show only method calls from the class X use -s X:: . To show * only calls to method Y from class X, use -s X::Y. To show only * all methods with the name Y from any class, use -s Y. * * Example based on the above trace: * * -s MySQL_Connection:: * show only calls from the MySQL Connection class * * -s execute * show only calls of the method "execute" from any class * * -s MySQL_Prepared_Statement::setInt * show calls of method setInt from class MySQL_Prepared_statement * * * -r remove_function * * Hide classes and methods that apply to pattern -r . * See -s show_function for a description of . * * * -b read_file_backwards * * Not functional. * * * - m max_number_of_lines_to_display * * Limit output to lines. * * * -c * * Compress opening and closing function name into one line. Normally the trace * will show two lines for every function call. The first line gets printed when * entering a function. The second line gets printed when exiting. -c does * "collapse" or "compress" to subsequent lines that show entering and leaving * a function into one line. For example: * * > class::func() * < class::func() * * Would be compressed into one line: * * = class::func() * * Compression happens only if no further lines are between entering and leaving * a function. * * * -v * * Print debug output. * * * - stats * * Print call statistics. This can be useful to decide which * classes and/or methods to exclude from the output using -r or -s. Statistics * cover all calls - regardless if hidden from the output or not! * * * @see http://dev.mysql.com/doc/refman/6.0/en/connector-cpp-debug-tracing.html */ $analyzer = new cpp_trace_analyzer(); if (!$analyzer->checkArgs($argc, $argv) || !$analyzer->parseOptions($argc, $argv)) die("Syntax error\n\n"); $analyzer->printLog(); class cpp_trace_analyzer { protected $tracefile = null; protected $level = 0; protected $show_functions = array(); protected $exclude_functions = array(); protected $verbose = false; protected $max_lines = 0; protected $read_from_tail = false; protected $collapse = false; protected $stats = array(); protected $collect_stats = false; protected $fetch_buffer = array(); protected $fetch_unfetched = 0; public function __construct() { } public function checkArgs($argc, $argv) { if ($argc < 2) { $this->printUsage(); return false; } return true; } public function parseOptions($argc, $argv) { $this->tracefile = $argv[$argc - 1]; if (!file_exists($this->tracefile) || !is_readable($this->tracefile)) { $this->printUsage("Trace file missing"); return false; } unset($argv[$argc - 1]); // skip file name unset($argv[0]); while ($token = array_shift($argv)) { switch ($token) { case '-l': $level = array_shift($argv); if (is_null($level)) { $this->printUsage("-l passed without level"); return false; } if ($level < 0) { $this->printUsage("-l passed with nevative level"); return false; } $this->level = (int)$level; break; case '-s': $function = array_shift($argv); if (is_null($function)) { $this->printUsage("-s used without function name"); return false; } $this->show_functions[$function] = $function; break; case '-r': $function = array_shift($argv); if (is_null($function)) { $this->printUsage("-r used without function name"); return false; } $this->exclude_functions[$function] = $function; break; case '-m': $max = array_shift($argv); if (is_null($max)) { $this->printUsage("-m max lines to display used without limit"); return false; } if ($max < 0) { $this->printUsage("-m passed with negative limit"); return false; } $this->max_lines = $max; break; case '-c': $this->collapse = true; break; case '-b': $this->printUsage("-b is not supported yet"); return false; $this->read_from_tail = true; break; case '-stats': $this->collect_stats = true; break; case '-v'; $this->verbose = true; break; } } return true; } public function printLog() { $fp = fopen($this->tracefile, 'r'); if (!$fp) { $this->printUsage("Cannot open tracefile for reading"); return false; } $lineno = 0; $displayed = 0; $show_level = null; while ($line = $this->fetchLine($fp)) { $lineno++; $function = trim($line); $level = 1; $exit = false; do { $left = substr(trim($function), 0, 1); switch ($left) { case '|': // indentation $level++; break; case '<': // function exit $function = substr(trim($function), 1); $exit = true; break 2; case '>': // function enter $function = substr(trim($function), 1); if ($this->collapse) { // look ahead: is the next line the closing function call? $next = $this->fetchLine($fp); if (strstr($next, '<' . $function)) { // Yes, it is..- lets collapse into one line if ($this->verbose) printf("%07d - Collapsing\n%s/%s", $lineno, $line, $next); $line = str_replace('>' . $function, '=' . $function, $line); $lineno++; } else { if ($this->verbose) printf("%07d - No collapse\n%s/%s\n", $lineno, $line, $next); $this->unfetchLine(); } } $level++; break 2; default: // function name or similar break 2; } $function = substr($function, 1); } while ($function != ''); if ('' == $function) { if ($this->verbose) printf("%07d - Skip unknown '%s'\n", $lineno, $line); continue; } if (strstr($function, '::')) { $pclass = ''; $pmethod = $function; $len = strlen($function); for ($i = 0; $i < $len; $i++) { $char = $function{$i}; if (':' == $char && ($i < $len -1) && ':' == $function{$i + 1}) { break; } $pclass .= $char; } if ($pclass != '') $pmethod = substr($function, $i + 2); } if ($this->collect_stats && !$exit && $pmethod != '') { if (!isset($this->stats[$pclass][$pmethod])) $this->stats[$pclass][$pmethod] = 1; else $this->stats[$pclass][$pmethod]++; } if ($this->level > 0 && ($level > $this->level)) { if ($this->verbose) printf("%07d - Skip - level %d > %d\n", $lineno, $level, $this->level); continue; } if ($pclass != '' && $pclass != $class) $class = $pclass; if ($pmethod != '' && $pmethod != $method) $method = $pmethod; if (isset($this->exclude_functions[$class . '::'])) { if ($this->verbose) printf("%07d - Skip - class %s because of -r %s::\n", $lineno, $class, $class); continue; } if (isset($this->exclude_functions[$method])) { if ($this->verbose) printf("%07d - Skip - method %s because of -r %s\n", $lineno, $method, $method); continue; } if (isset($this->exclude_functions[$class . '::' . $method])) { if ($this->verbose) printf("%07d - Skip - method %s::%s because of -r %s::%s\n", $lineno, $class, $method, $class, $method); continue; } if (!empty($this->show_functions)) { if (!isset($this->show_functions[$class . '::']) && !isset($this->show_functions[$method]) && !isset($this->show_functions[$class . '::' . $method])) { if ((!is_null($show_level) && $level < $show_level) || is_null($show_level)) { if ($this->verbose) printf("%07d/%03d - Skip - class %s or method %s not in positive show list, no -s %s:: and no -s %s\n", $lineno, $level, $class, $method, $class, $method); $show_level = null; continue; } else if ($show_level === $level) { // last one on the initial opening level? if (!$exit) { // something else, could be a new function, eat up - KLUDGE no proper way to detect if it should be skipped if ($this->verbose) printf("%07d/%03d - Skip - class %s or method %s not in positive show list, no -s %s:: and no -s %s\n", $lineno, $level, $class, $method, $class, $method); $show_level = null; continue; } else { // verbose) printf("%07d - Info - accepting level > %d\n", $lineno, $level); } } } $displayed++; printf("%07d/%02d/%07d\t%s", $lineno, $level, $displayed, $line); if (($this->max_lines > 0) && ($displayed == $this->max_lines)) { if ($this->verbose) printf("%07d - Skip - showed %d lines, limit of -m %d reached\n", $lineno, $displayed, $this->max_lines); break; } } fclose($fp); if ($this->collect_stats) $this->printStats(); return true; } public function printStats() { printf("\n"); $total_calls = $fac = 0; foreach ($this->stats as $class => $methods) { foreach ($methods as $method => $calls) $total_calls += $calls; } $fac = 100 / $total_calls; $total_hidden = 0; $auto_hide = ''; ksort($this->stats); foreach ($this->stats as $class => $methods) { if (!empty($this->show_functions)) { if (isset($this->show_functions[$class . '::'])) $comment = sprintf("(shown because of -s %s::)", $class); else $comment = "(hidden)"; } else if (!empty($this->exclude_functions)) { if (isset($this->exclude_functions[$class . '::'])) $comment = sprintf("(hidden because of -r %s::)", $class); else $comment = '(shown)'; } if ($class) printf("Class: %s %s\n\n", $class, $comment); else printf("No class\n\n"); arsort($methods, SORT_NUMERIC); foreach ($methods as $method => $calls) { $hidden = false; $comment = ''; if (!empty($this->show_functions)) { if (isset($this->show_functions[$method])) { $comment = sprintf("(shown because of -s %s)", $method); } else if (isset($this->show_functions[$class . '::' . $method])) { $comment = sprintf("(shown because of -s %s::%s)", $class, $method); } else if (isset($this->show_functions[$class . '::'])) { $comment = sprintf("(shown because of -s %s::)", $class); } else { $total_hidden += $calls; $hidden = true; $comment = "(hidden)"; } } else if (!empty($this->exclude_functions)) { if (isset($this->exclude_functions[$method])) { $total_hidden += $calls; $comment = sprintf("(hidden because of -r %s)", $method); } else if (isset($this->exclude_functions[$class . '::' . $method])) { $total_hidden += $calls; $hidden = true; $comment = sprintf("(hidden because of -r %s::%s)", $class, $method); } else if (isset($this->exclude_functions[$class . '::'])) { $total_hidden += $calls; $hidden = true; $comment = sprintf("(hidden because of -r %s::)", $class); } } if ($comment == '') { if ($hidden) { $comment = '(hidden)'; } else if ($calls * $fac >= 2) { $comment = sprintf('(shown, use "-r %s::%s" to hide)', $class, $method); $auto_hide .= sprintf("-r %s::%s ", $class, $method); } else { $comment = "(shown)"; } } printf(" %-40s %-7d (= %5s%%) - %s\n", $method, $calls, sprintf("%2.2f", $calls * $fac), $comment); } printf("\n"); } printf("NOTE: %2.2f%% of all calls hidden.\n", $total_hidden * $fac); printf("\n"); printf("If you want to hide all functions which are invoked in more than 2%% of all cases, use:\n"); printf("%s\n", $auto_hide); printf("\n"); } protected function fetchLine($fp, $bytes = 16384) { if ($this->unfetched > 0) { $line = $this->fetch_buffer[count($this->fetch_buffer) - $this->unfetched]; $this->unfetched--; return $line; } if (!$this->read_from_tail) $line = fgets($fp, $bytes); $this->fetch_buffer[] = $line; if (count($this->fetch_buffer) > 10) { // remove oldest array_shift($this->fetch_buffer); } return $line; } protected function unfetchLine() { if ($this->unfetched == count($this->fetch_buffer)) return false; $this->unfetched++; return $this->fetch_buffer[count($this->fetch_buffer) - $this->unfetched - 1]; } protected function printUsage($msg = NULL) { print "\n"; print "Usage:\n"; print " script.php [-l trace_nesting_level] [-s show_function] [-r remove_function] [-b read_file_backwards] [-m max_number_of_lines_to_display] [-stats] trace\n"; print "\n"; if (!is_null($msg)) printf(" %s\n\n", $msg); } } ?>mysql-connector-c++-1.1.7/examples/debug_output.cpp000644 015771 000012 00000014011 12645244436 023010 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Debug/Tracefile generation * * Two types of debug/trace files are available with Connector/C++. You can make * Connector/C++ write a trace file and/or activate tracing on the level of the * underlying MySQL Client Libarary. * * Connector/C++ is based on the MySQL Client Library (C-API, AKA libmysql). * Connector/C++ is a proxy/wrapper of the MySQL Client Library. * Debug versions of the MySQL Client Library can write a trace file. On the C-level * this is done by passing a string with debug instructions to the C function * mysql_debug(). You can use the Connector/C++ method * setClientOption("libmysql_debug", const string debug) to pass a string to the * C-API function mysql_debug(). See the MySQL C-API documentation * * Example of a libmysql trace: * >mysql_stmt_init * | >_mymalloc * | | enter: Size: 816 * | | exit: ptr: 0x68e7b8 * | <_mymalloc * | >init_alloc_root * | | enter: root: 0x68e7b8 * | | >_mymalloc * | | | enter: Size: 2064 * | | | exit: ptr: 0x68eb28 * [...] * * If you do not have compiled Connector/C++ against a debug version of the MySQL * Client Library but you have compiled Connector/C++ with tracing enabled, then * you may activate the Connector/C++ internal trace using * setClientOption("clientTrace", bool on_off). * * To compile Connector/C++ with tracing enabled, do: * cmake -DMYSQLCPPCONN_TRACE_ENABLE:BOOL=1 * * Example of a Connector/C++ trace: * | INF: Tracing enabled * MySQL_Prepared_Statement::setInt * | INF: this=0x69a2e0 * | >MySQL_Prepared_Statement::checkClosed * | #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" using namespace std; int main(int argc, const char **argv) { const string host(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); sql::Driver *driver; int i; int on_off = 1; cout << boolalpha; cout << "1..1" << endl;; cout << "# Connector/C++ debug / client_options example.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(host, user, pass)); /* Activate debug trace of the MySQL Client Library (C-API) Only available with a debug build of the MySQL Client Library! */ con->setClientOption("libmysql_debug", "d:t:O,client.trace"); con->setSchema(database); boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))"); cout << "#\t Test table created" << endl; boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("INSERT INTO test(id, label) VALUES (?, ?)")); for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { prep_stmt->setInt(1, test_data[i].id); prep_stmt->setString(2, test_data[i].label); prep_stmt->executeUpdate(); /* Pointless activity to demo how to activating and de-activating the Connector/C++ internal trace */ on_off = (i + 2) % 2; con->setClientOption("clientTrace", &on_off); } stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << endl; cout << "# ERR: DbcException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; // Use what(), getErrorCode() and getSQLState() cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; if (e.getErrorCode() == 1047) { /* Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR) Message: Unknown command */ cout << "# ERR: Your server seems not to support PS at all because its MYSQL <4.1" << endl; } cout << "not ok 1 - examples/debug.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << endl; cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/debug.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/debug.cpp" << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/dynamic_load.cpp000755 015771 000012 00000030137 12645244436 022737 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Basic example demonstrating how to load a different driver. * */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" static void validateResultSet(boost::scoped_ptr< sql::ResultSet > & res, struct _test_data *min, struct _test_data *max); using namespace std; int main(int argc, const char **argv) { static const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* Driver Manager */ sql::Driver *driver; /* Connection properties */ sql::ConnectOptionsMap connection_properties; /* sql::ResultSet.rowsCount() returns size_t */ stringstream sql; int i; struct _test_data min, max; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ dynamic loading.." << endl; try { /* Driver / client library to load. The preprocessor constant DYNLOAD_MYSQL_LIB comes from the build environment. It should contain the path of the C library which Connector/C++ has been linked against. For testing the functionality, feed free to replace DYNLOAD_MYSQL_LIB with any constant string containing the path of an alternate client library. get_driver_instance_by_name(const char * const clientlib) If you use get_driver_instance_by_name Connector/C++ will not load the default C client library to establish a connection to MySQL but the one you specify. The default C library is the one found during cmake (configure) and used for building Connector/C++. On most systems this will be the MySQL Client Library shipped together with the MySQL Server found on the build host. However, at runtime you can advise Connector/C++ to dynamically load a different MySQL Client Library. This can be a MySQL Client Library from another MySQL Server or the library of Connector/C. CAUTION: In some development versions of C/C++ 1.1.0 a connection property has been used to set the library. This has changed. The temporary syntax has been like this: sql::SQLString lib(DYNLOAD_MYSQL_LIB); connection_properties["clientlib"] = lib; */ driver = sql::mysql::get_driver_instance_by_name(DYNLOAD_MYSQL_LIB); /* 'standard' connection properties */ connection_properties["hostName"] = url; connection_properties["userName"] = user; connection_properties["password"] = pass; connection_properties["schema"] = database; boost::scoped_ptr< sql::Connection > con(driver->connect(connection_properties)); /* Creating a "simple" statement - "simple" = not a prepared statement */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, label CHAR(1))"); cout << "#\t Test table created" << endl; /* Populate the test table with data */ min = max = test_data[0]; for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { /* Remember mnin/max values for further testing */ if (test_data[i].id < min.id) { min = test_data[i]; } if (test_data[i].id > max.id) { max = test_data[i]; } /* KLUDGE: You should take measures against SQL injections! */ sql.str(""); sql << "INSERT INTO test(id, label) VALUES ("; sql << test_data[i].id << ", '" << test_data[i].label << "')"; stmt->execute(sql.str()); } cout << "#\t Test table populated" << endl; /* This is an example how to fetch in reverse order using the ResultSet cursor. Every ResultSet object maintains a cursor, which points to its current row of data. The cursor is 1-based. The first row has the cursor position 1. NOTE: The Connector/C++ preview/alpha uses buffered results. THe driver will always fetch all data no matter how big the result set is! */ cout << "#\t Testing sql::Statement based resultset" << endl; { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC")); validateResultSet(res, &min, &max); } cout << "#" << endl; cout << "#\t Testing sql::PreparedStatment based resultset" << endl; { boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("SELECT id, label FROM test ORDER BY id ASC")); boost::scoped_ptr< sql::ResultSet > res(prep_stmt->executeQuery()); validateResultSet(res, &min, &max); } /* Clean up */ stmt->execute("DROP TABLE IF EXISTS test"); cout << "# done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; // Use what(), getErrorCode() and getSQLState() cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/resultset.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/resultset.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/dynamic_load.cpp" << endl; return EXIT_SUCCESS; } static void validateRow(boost::scoped_ptr< sql::ResultSet > & res, struct _test_data *exp) { stringstream msg; cout << "#\t\t Fetching the first row, id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; if ((res->getInt("id") != exp->id) || (res->getString("label") != exp->label)) { msg.str("Wrong results"); msg << "Expected (" << exp->id << "," << exp->label << ")"; msg << " got (" << res->getInt("id") <<", " << res->getString("label") << ")"; throw runtime_error(msg.str()); } } static void validateResultSet(boost::scoped_ptr< sql::ResultSet > & res, struct _test_data *min, struct _test_data *max) { size_t row; cout << "#\t Selecting in ascending order but fetching in descending (reverse) order" << endl; /* Move the cursor after the last row - n + 1 */ res->afterLast(); if (true != res->isAfterLast()) throw runtime_error("Position should be after last row (1)"); row = res->rowsCount() - 1; /* Move the cursor backwards to: n, n - 1, ... 1, 0. Return true if rows are available. */ while (res->previous()) { cout << "#\t\t Row " << row << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row--; } /* The last call to res->previous() has moved the cursor before the first row Cursor position is 0, recall: rows are from 1 ... n */ cout << "#\t\t isBeforeFirst() = " << res->isBeforeFirst() << endl; cout << "#\t\t isFirst() = " << res->isFirst() << endl; if (!res->isBeforeFirst()) { throw runtime_error("Cursor should be positioned before the first row"); } /* Move the cursor forward again to position 1 - the first row */ res->next(); cout << "#\t Positioning cursor to 1 using next(), isFirst() = " << res->isFirst() << endl; validateRow(res, min); /* Move the cursor to position 0 = before the first row */ if (false != res->absolute(0)) { throw runtime_error("Call did not fail although its not allowed to move the cursor before the first row"); } cout << "#\t Positioning before first row using absolute(0), isFirst() = " << res->isFirst() << endl; /* Move the cursor forward to position 1 = the first row */ res->next(); validateRow(res, min); /* Move the cursor to position 0 = before the first row */ res->beforeFirst(); cout << "#\t Positioning cursor using beforeFirst(), isFirst() = " << res->isFirst() << endl; /* Move the cursor forward to position 1 = the first row */ res->next(); cout << "#\t\t Moving cursor forward using next(), isFirst() = " << res->isFirst() << endl; validateRow(res, min); cout << "#\t Finally, reading in descending (reverse) order again" << endl; /* Move the cursor after the last row - n + 1 */ res->afterLast(); row = res->rowsCount() - 1; /* Move the cursor backwards to: n, n - 1, ... 1, 0. Return true if rows are available.*/ while (res->previous()) { cout << "#\t\t Row " << row << ", getRow() " << res->getRow(); cout << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row--; } /* The last call to res->previous() has moved the cursor before the first row Cursor position is 0, recall: rows are from 1 ... n */ cout << "#\t\t isBeforeFirst() = " << res->isBeforeFirst() << endl; if (true != res->isBeforeFirst()) { throw runtime_error("Position should be 0 = before first row"); } cout << "#\t And in regular order..." << endl; res->beforeFirst(); if (true != res->isBeforeFirst()) { throw runtime_error("Cursor should be positioned before the first row"); } row = 0; while (res->next()) { cout << "#\t\t Row " << row << ", getRow() " << res->getRow(); cout << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row++; } cout << "#\t\t isAfterLast() = " << res->isAfterLast() << endl; if (true != res->isAfterLast()) { throw runtime_error("next() has returned false and the cursor should be after the last row"); } /* Move to the last entry using a negative offset for absolute() */ cout << "#\t Trying absolute(-1) to fetch last entry..." << endl; if (true != res->absolute(-1)) { throw runtime_error("Call did fail although -1 is valid"); } cout << "#\t\t isAfterLast() = " << res->isAfterLast() << endl; if (false != res->isAfterLast()) { throw runtime_error("Cursor should be positioned to the last row and not after the last row"); } cout << "#\t\t isLast() = " << res->isLast() << endl; if (true != res->isLast()) { throw runtime_error("Cursor should be positioned to the last row"); } validateRow(res, max); /* Another way to move after the last entry */ cout << "#\t Trying absolute(NUMROWS + 10) to move cursor after last row and fetch last entry..." << endl; if (false != res->absolute(res->rowsCount() + 10)) { throw runtime_error("Call did fail although parameter is valid"); } if (true != res->isAfterLast()) { throw runtime_error("Cursor should be positioned after the last row"); } cout << "#\t\t isLast() = " << res->isLast() << endl; if (false != res->isLast()) { throw runtime_error("Cursor should be positioned after the last row"); } try { res->getString(1); throw runtime_error("Fetching is possible although cursor is out of range"); } catch (sql::InvalidArgumentException &) { cout << "#\t\t OK, fetching not allowed when cursor is out of range..." << endl; } /* absolute(NUM_ROWS + 10) is internally aligned to NUM_ROWS + 1 = afterLastRow() */ res->previous(); validateRow(res, max); } mysql-connector-c++-1.1.7/examples/examples.h000644 015771 000012 00000004360 12645244436 021573 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _EXAMPLES_H #define _EXAMPLES_H /* __FUNCTION__/__func__ is not portable. We do not promise that our example definition covers each and every compiler. If not, it is up to you to find a different definition for your setup. */ #if __STDC_VERSION__ < 199901L # if __GNUC__ >= 2 # define EXAMPLE_FUNCTION __FUNCTION__ # else # define EXAMPLE_FUNCTION "(function n/a)" # endif #elif defined(_MSC_VER) # if _MSC_VER < 1300 # define EXAMPLE_FUNCTION "(function n/a)" # else # define EXAMPLE_FUNCTION __FUNCTION__ # endif #elif (defined __func__) # define EXAMPLE_FUNCTION __func__ #else # define EXAMPLE_FUNCTION "(function n/a)" #endif /* Again, either you are lucky and this definition works for you or you have to find your own. */ #ifndef __LINE__ #define __LINE__ "(line number n/a)" #endif // Connection properties #define EXAMPLE_DB "test" #define EXAMPLE_HOST "tcp://127.0.0.1:3306" #define EXAMPLE_USER "root" #define EXAMPLE_PASS "root" // Sample data #define EXAMPLE_NUM_TEST_ROWS 4 struct _test_data { int id; const char* label; }; static _test_data test_data[EXAMPLE_NUM_TEST_ROWS] = { {1, ""}, {2, "a"}, {3, "b"}, {4, "c"}, }; #endif /* _EXAMPLES_H */ mysql-connector-c++-1.1.7/examples/exceptions.cpp000644 015771 000012 00000017357 12645244436 022503 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Types of execptions thrown by Connector/C++ * */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++. You might not use it but directly include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include /* Connection parameter and sample data */ #include "examples.h" using namespace std; int main(int argc, const char **argv) { static const string host(argc >= 2 ? argv[1] : EXAMPLE_HOST); static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); // Driver Manager sql::Driver *driver; int i; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ types of exceptions.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(host, user, pass)); /* Run in autocommit mode */ con->setAutoCommit(1); boost::scoped_ptr< sql::Savepoint > savepoint(NULL); try { // It makes no sense to set a savepoint in autocommit mode savepoint.reset(con->setSavepoint(string("before_insert"))); throw new runtime_error("Setting a savepoint should not be allow in autocommit mode"); } catch (sql::InvalidArgumentException &e) { cout << "#\t Invalid Argument: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } con->setSchema(database); boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))"); cout << "#\t Test table created" << endl; try { con->setReadOnly(true); } catch (sql::MethodNotImplementedException &e) { cout << "#\t Not implemented: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } con->setAutoCommit(0); try { savepoint.reset(con->setSavepoint(string(""))); } catch (sql::InvalidArgumentException &e) { cout << "#\t Invalid Argument: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } savepoint.reset(con->setSavepoint(string("before_insert"))); { boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("INSERT INTO test(id, label) VALUES (?, ?)")); for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { prep_stmt->setInt(1, test_data[i].id); prep_stmt->setString(2, test_data[i].label); prep_stmt->executeUpdate(); } } try { boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("INSERT INTO test(id, label) VALUES (?, ?)")); prep_stmt->setInt(1, test_data[0].id); /* This will cause a duplicate index error */ prep_stmt->executeUpdate(); throw new runtime_error("Query not executed or duplicate key not detected"); } catch (sql::SQLException &e) { cout << "#\t SQL Exception: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } /* Switching back to auto commit will invalidate the savepoint! */ con->setAutoCommit(1); try { con->releaseSavepoint(savepoint.get()); throw new runtime_error("Releasing a savepoint should not be allow in autocommit mode"); } catch (sql::InvalidArgumentException &e) { cout << "#\t Invalid Argument: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } stmt->execute("DROP TABLE IF EXISTS test"); cout << "#done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) sql::SQLException is the base class. */ cout << endl; cout << "# ERR: DbcException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what(), getErrorCode() and getSQLState() */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; if (e.getErrorCode() == 1047) { /* Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR) Message: Unknown command */ cout << "# ERR: Your server seems not to support PS at all because its MYSQL <4.1" << endl; } cout << "not ok 1 - examples/exceptions.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << endl; cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/exceptions.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/exceptions.cpp" << endl; return EXIT_SUCCESS; } bool prepare_execute(sql::Connection *con, const char *sql) { sql::PreparedStatement *prep_stmt; prep_stmt = con->prepareStatement(sql); prep_stmt->execute(); delete prep_stmt; return true; } sql::Statement* emulate_prepare_execute(sql::Connection *con, const char *sql) { sql::PreparedStatement *prep_stmt; sql::Statement *stmt = NULL; cout << "#\t\t 'emulation': " << sql << endl; try { prep_stmt = con->prepareStatement(sql); prep_stmt->execute(); cout << "#\t\t 'emulation': use of sql::PreparedStatement possible" << endl; // safe upcast - PreparedStatement is derived from Statement stmt = prep_stmt; } catch (sql::SQLException &e) { /* Maybe the command is not supported by the MySQL Server? http://dev.mysql.com/doc/refman/5.1/en/error-messages-server.html Error: 1295 SQLSTATE: HY000 (ER_UNSUPPORTED_PS) Message: This command is not supported in the prepared statement protocol yet */ if (e.getErrorCode() != 1295) { /* The MySQL Server should be able to prepare the statement but something went wrong. Let the caller handle the error. */ throw ; } cout << "#\t\t 'emulation': ER_UNSUPPORTED_PS and fallback to sql::Statement" << endl; cout << "#\t\t ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; stmt = con->createStatement(); stmt->execute(sql); } return stmt; } mysql-connector-c++-1.1.7/examples/prepared_statement.cpp000644 015771 000012 00000030237 12645244436 024200 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Example of statements - not to be confused with prepared statements * * NOTE: The MySQL Server does not support each and every SQL statement * to be prepared. The list of statements which can be prepared is available * in the MySQL Server documentation and the C API documentation: * http://dev.mysql.com/doc/refman/5.1/en/c-api-prepared-statements.html * (Link to the MySQL Server 5.1 documentation!) * * Connector/C++ is based on the C API and C library "libmysql". Therefore * it inherits all limitations from the MySQL Server and the MySQL C API. * * MySQL 5.1.12 can prepare the following statements: * * - CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE * - most SHOW commands * - ANALYZE TABLE, OPTIMIZE TABLE, REPAIR TABLE * - CACHE INDEX, CHANGE MASTER, CHECKSUM {TABLE | TABLES}, * - {CREATE | RENAME | DROP} DATABASE, {CREATE | RENAME | DROP} USER * - FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES} * - GRANT, REVOKE, KILL, LOAD INDEX INTO CACHE, RESET {MASTER | SLAVE | QUERY CACHE} * - SHOW BINLOG EVENTS, SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW} * - SHOW {AUTHORS | CONTRIBUTORS | WARNINGS | ERRORS} * - SHOW {MASTER | BINARY} LOGS, SHOW {MASTER | SLAVE} STATUS * - SLAVE {START | STOP}, INSTALL PLUGIN, UNINSTALL PLUGIN * * ... that's pretty much every *core* SQL statement - but not USE as you'll see below. * * Connector/C++ does not include a prepared statement emulation * * @link http://dev.mysql.com/doc/refman/5.1/en/c-api-prepared-statements.html */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++. You might not use it but directly include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include /* Connection parameter and sample data */ #include "examples.h" bool prepare_execute(boost::scoped_ptr< sql::Connection > & con, const char *sql); sql::Statement* emulate_prepare_execute(boost::scoped_ptr< sql::Connection > & con, const char *sql); using namespace std; int main(int argc, const char **argv) { static const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* Driver Manager */ sql::Driver *driver; /* sql::ResultSet.rowsCount() returns size_t */ size_t row; stringstream sql; stringstream msg; int i, num_rows; cout << boolalpha; cout << "1..1" << endl;; cout << "# Connector/C++ prepared statement example.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); /* The usage of USE is not supported by the prepared statement protocol */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("USE " + database); /* Prepared statement are unhandy for queries which you execute only once! prepare() will send your SQL statement to the server. The server will do a SQL syntax check, perform some static rewriting like eliminating dead expressions such as "WHERE 1=1" and simplify expressions like "WHERE a > 1 AND a > 2" to "WHERE a > 2". Then control gets back to the client and the server waits for execute() (or close()). On execute() another round trip to the server is done. In case you execute your prepared statement only once - like shown below - you get two round trips. But using "simple" statements - like above - means only one round trip. Therefore, the below is *bad* style. WARNING: Although its *bad* style, the example program will continue to do it to demonstrate the (ab)use of prepared statements (and to prove that you really can do more than SELECT with PS). */ boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("DROP TABLE IF EXISTS test")); prep_stmt->execute(); prepare_execute(con, "CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))"); cout << "#\t Test table created" << endl; /* The first useful example - prepare() once, execute() n + 1 times NOTE: The MySQL Server does not support named parameters. You have to use the placeholder syntax shown below. There is no emulation which would you allow to use named parameter like ':param1'. Use '?'. Parameters are 1-based. */ num_rows = 0; prep_stmt.reset(con->prepareStatement("INSERT INTO test(id, label) VALUES (?, ?)")); for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { prep_stmt->setInt(1, test_data[i].id); prep_stmt->setString(2, test_data[i].label); /* executeUpdate() returns the number of affected = inserted rows */ num_rows += prep_stmt->executeUpdate(); } if (EXAMPLE_NUM_TEST_ROWS != num_rows) { msg.str(""); msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, reported " << num_rows; throw runtime_error(msg.str()); } cout << "#\t Test table populated" << endl; /* We will reuse the SELECT a bit later... */ boost::scoped_ptr< sql::PreparedStatement > prep_select(con->prepareStatement("SELECT id, label FROM test ORDER BY id ASC")); cout << "#\t Running 'SELECT id, label FROM test ORDER BY id ASC'" << endl; boost::scoped_ptr< sql::ResultSet > res(prep_select->executeQuery()); row = 0; while (res->next()) { cout << "#\t\t Row " << row << " - id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row++; } res.reset(NULL); if (EXAMPLE_NUM_TEST_ROWS != row) { msg.str(""); msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, reported " << row; throw runtime_error(msg.str()); } cout << "#\t Simple PS 'emulation' for USE and another SELECT" << endl; stmt.reset(emulate_prepare_execute(con, string("USE " + database).c_str())); stmt.reset(emulate_prepare_execute(con, string("USE " + database).c_str())); stmt.reset(emulate_prepare_execute(con, "SELECT id FROM test ORDER BY id ASC")); res.reset(stmt->getResultSet()); if (res.get() != NULL) { row = 0; while (res->next()) { cout << "#\t\t Row " << row << " - id = " << res->getInt("id") << endl; row++; } res.reset(NULL); } stmt.reset(NULL); /* Running the SELECT again but fetching in reverse order */ cout << "#\t SELECT and fetching in reverse order" << endl; res.reset(prep_select->executeQuery()); row = res->rowsCount(); cout << "#\t\t res->getRowsCount() = " << res->rowsCount() << endl; if (res->rowsCount() != EXAMPLE_NUM_TEST_ROWS) { msg.str(""); msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, found " << res->rowsCount(); throw runtime_error(msg.str()); } /* Position the cursor after the last row */ cout << "#\t\t Position the cursor after the last row\n"; res->afterLast(); cout << "#\t\t res->isafterLast()\t= " << res->isAfterLast() << endl; cout << "#\t\t res->isLast()\t\t= " << res->isLast() << endl; if (!res->isAfterLast() || res->isLast()) throw runtime_error("Moving the cursor after the last row failed"); while (res->previous()) { cout << "#\t\t res->previous()\n"; cout << "#\t\t Row " << row << " - id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row--; } cout << "#\t\t Should be before the first\n"; cout << "#\t\t res->isFirst()\t\t= " << res->isFirst() << endl; cout << "#\t\t res->isBeforeFirst()\t= " << res->isBeforeFirst() << endl; if (res->isFirst() || !res->isBeforeFirst()) throw runtime_error("Cursor should be before first row"); /* Now that the cursor is before the first, fetch the first */ cout << "#\t\t Now that the cursor is before the first, fetch the first\n"; cout << "#\t\t calling next() to fetch first row" << endl; row++; res->next(); cout << "#\t\t res->isFirst()\t\t= " << res->isFirst() << endl; cout << "#\t\t Row " << row << " - id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row--; /* For more on cursors see resultset.cpp example */ /* Clean up */ res.reset(NULL); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); cout << "#done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << endl; cout << "# ERR: DbcException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what(), getErrorCode() and getSQLState() */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; if (e.getErrorCode() == 1047) { /* Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR) Message: Unknown command */ cout << "# ERR: Your server seems not to support PS at all because its MYSQL <4.1" << endl; } cout << "not ok 1 - examples/prepared_statement.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << endl; cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/prepared_statement.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/prepared_statement.cpp" << endl; return EXIT_SUCCESS; } bool prepare_execute(boost::scoped_ptr< sql::Connection > & con, const char *sql) { sql::PreparedStatement * prep_stmt; prep_stmt = con->prepareStatement(sql); prep_stmt->execute(); delete prep_stmt; return true; } sql::Statement* emulate_prepare_execute(boost::scoped_ptr< sql::Connection > & con, const char *sql) { sql::PreparedStatement *prep_stmt; sql::Statement *stmt = NULL; cout << "#\t\t 'emulation': " << sql << endl; try { prep_stmt = con->prepareStatement(sql); prep_stmt->execute(); cout << "#\t\t 'emulation': use of sql::PreparedStatement possible" << endl; /* safe upcast - PreparedStatement is derived from Statement */ stmt = prep_stmt; } catch (sql::SQLException &e) { /* Maybe the command is not supported by the MySQL Server? http://dev.mysql.com/doc/refman/5.1/en/error-messages-server.html Error: 1295 SQLSTATE: HY000 (ER_UNSUPPORTED_PS) Message: This command is not supported in the prepared statement protocol yet */ if (e.getErrorCode() != 1295) { // The MySQL Server should be able to prepare the statement // but something went wrong. Let the caller handle the error. throw ; } cout << "#\t\t 'emulation': ER_UNSUPPORTED_PS and fallback to sql::Statement" << endl; cout << "#\t\t ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; stmt = con->createStatement(); stmt->execute(sql); } return stmt; } mysql-connector-c++-1.1.7/examples/pthreads.cpp000644 015771 000012 00000015332 12645244436 022123 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Basic example of creating a stand alone program linked against Connector/C++ * * This example is not integrated into the Connector/C++ build environment. * You must run "make install" prior to following the build instructions * given here. * * To compile the standalone example on Linux try something like: * * /usr/bin/c++ * -o pthread * -I/usr/local/include/cppconn/ * -Wl,-Bdynamic -lmysqlcppconn -pthread * examples/pthreads.cpp * * To run the example on Linux try something similar to: * * LD_LIBRARY_PATH=/usr/local/lib/ ./pthread * * or: * * LD_LIBRARY_PATH=/usr/local/lib/ ./pthread host user password database * */ /* Standard C++ includes */ #include #include #include #include /* usleep() */ #include /* Threading stuff */ #include /* Include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include "mysql_connection.h" #include "mysql_driver.h" #include #include #include #include #define EXAMPLE_HOST "localhost" #define EXAMPLE_USER "root" #define EXAMPLE_PASS "" #define EXAMPLE_DB "test" struct st_worker_thread_param { sql::Driver *driver; sql::Connection *con; }; using namespace std; void* thread_one_action(void *arg); int thread_finished = 0; string url; string user; string pass; string database; /** * Usage example for Driver, Connection, (simple) Statement, ResultSet */ int main(int argc, const char **argv) { sql::Driver *driver; boost::scoped_ptr< sql::Connection > con; url = (argc >= 2) ? argv[1] : EXAMPLE_HOST; user = (argc >= 3) ? argv[2] : EXAMPLE_USER; pass = (argc >= 4) ? argv[3] : EXAMPLE_PASS; database = (argc >= 5) ? argv[4] : EXAMPLE_DB; int status; pthread_t thread_one; cout << endl; cout << "Main thread: Connector/C++ phthreads program example..." << endl; cout << endl; try { driver = sql::mysql::get_driver_instance(); /* Using the Driver to create a connection */ con.reset(driver->connect(url, user, pass)); con->setSchema(database); /* Worker thread */ cout << "Main thread: creating thread 1..." << endl; /* A little bloat. We don't want global scoped_ptr objects. Therefore we wrap the object in an object. An alternative would have been to use global sql::Driver, sql::Connection objects [plain objects and no scoped_ptr] but then we'd have to add bloat for making sure we explicitly delete them, e.g. in case of an exception. It is not nice in either case. Let's use parameter struct. */ struct st_worker_thread_param *param = new st_worker_thread_param; param->driver = driver; param->con = con.get(); status = pthread_create(&thread_one, NULL, thread_one_action, (void *)param); if (status != 0) throw std::runtime_error("Thread creation has failed"); status = pthread_join(thread_one, NULL); if (status != 0) throw std::runtime_error("Joining thread has failed"); while (thread_finished == 0) { /* The worker is using global resources which the main thread shall not free before the worker thread is done. For example, the worker thread is using the Connection object. */ cout << "Main thread: waiting for thread to finish fetching data..." << endl; usleep(300000); } delete param; cout << "Main thread: thread 1 has finished fetching data from MySQL..." << endl; } catch (sql::SQLException &e) { cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/connect.php" << endl; return EXIT_FAILURE; } cout << endl; cout << "Main thread: ... find more at http://www.mysql.com" << endl; cout << endl; return EXIT_SUCCESS; } void* thread_one_action(void *arg) { int status; boost::scoped_ptr< sql::Statement > stmt; boost::scoped_ptr< sql::ResultSet > res; struct st_worker_thread_param *handles = (struct st_worker_thread_param*) arg; /* NOTE: In every new thread you must call threadInit() *before* doing anything with the Connector. If you omit this step anything, including a crash, may happen. */ cout << endl; cout << "\tThread 1: driver->threadInit()" << endl; handles->driver->threadInit(); cout << "\tThread 1: ... statement object created" << endl; stmt.reset(handles->con->createStatement()); /* Sharing resultset among threads should be avoided. Its possible but requires further action from you. */ cout << "\tThread 1: ... running 'SELECT SLEEP(1), 'Welcome to Connector/C++' AS _message'" << endl; res.reset(stmt->executeQuery("SELECT SLEEP(1), 'Welcome to Connector/C++' AS _message")); cout << "\tThread 1: ... fetching result" << endl; while (res->next()) { cout << "\tThread 1: ... MySQL replies: " << res->getString("_message") << endl; cout << "\tThread 1: ... say it again, MySQL" << endl; cout << "\tThread 1: ... MySQL replies: " << res->getString(2) << endl; } cout << "\tThread 1: driver->threadEnd()" << endl; /* NOTE: You must call threadEnd() when the thread exits If you omit this step you get messages from the C Client Library like this: Error in my_thread_global_end(): 1 threads didn't exit */ handles->driver->threadEnd(); cout << endl; thread_finished = 1; return NULL; } mysql-connector-c++-1.1.7/examples/resultset.cpp000644 015771 000012 00000025102 12645244436 022337 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Basic example demonstrating scrolling through a result set * */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" static void validateResultSet(boost::scoped_ptr< sql::ResultSet > & res, struct _test_data *min, struct _test_data *max); using namespace std; int main(int argc, const char **argv) { static const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* Driver Manager */ sql::Driver *driver; /* sql::ResultSet.rowsCount() returns size_t */ stringstream sql; int i; struct _test_data min, max; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ result set.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); con->setSchema(database); /* Creating a "simple" statement - "simple" = not a prepared statement */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, label CHAR(1))"); cout << "#\t Test table created" << endl; /* Populate the test table with data */ min = max = test_data[0]; for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { /* Remember mnin/max values for further testing */ if (test_data[i].id < min.id) { min = test_data[i]; } if (test_data[i].id > max.id) { max = test_data[i]; } /* KLUDGE: You should take measures against SQL injections! */ sql.str(""); sql << "INSERT INTO test(id, label) VALUES ("; sql << test_data[i].id << ", '" << test_data[i].label << "')"; stmt->execute(sql.str()); } cout << "#\t Test table populated" << endl; /* This is an example how to fetch in reverse order using the ResultSet cursor. Every ResultSet object maintains a cursor, which points to its current row of data. The cursor is 1-based. The first row has the cursor position 1. NOTE: The Connector/C++ preview/alpha uses buffered results. THe driver will always fetch all data no matter how big the result set is! */ cout << "#\t Testing sql::Statement based resultset" << endl; { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC")); validateResultSet(res, &min, &max); } cout << "#" << endl; cout << "#\t Testing sql::PreparedStatment based resultset" << endl; { boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("SELECT id, label FROM test ORDER BY id ASC")); boost::scoped_ptr< sql::ResultSet > res(prep_stmt->executeQuery()); validateResultSet(res, &min, &max); } /* Clean up */ stmt->execute("DROP TABLE IF EXISTS test"); cout << "# done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; // Use what(), getErrorCode() and getSQLState() cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/resultset.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/resultset.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/resultset.cpp" << endl; return EXIT_SUCCESS; } static void validateRow(boost::scoped_ptr< sql::ResultSet > & res, struct _test_data *exp) { stringstream msg; cout << "#\t\t Fetching the first row, id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; if ((res->getInt("id") != exp->id) || (res->getString("label") != exp->label)) { msg.str("Wrong results"); msg << "Expected (" << exp->id << "," << exp->label << ")"; msg << " got (" << res->getInt("id") <<", " << res->getString("label") << ")"; throw runtime_error(msg.str()); } } static void validateResultSet(boost::scoped_ptr< sql::ResultSet > & res, struct _test_data *min, struct _test_data *max) { size_t row; cout << "#\t Selecting in ascending order but fetching in descending (reverse) order" << endl; /* Move the cursor after the last row - n + 1 */ res->afterLast(); if (true != res->isAfterLast()) throw runtime_error("Position should be after last row (1)"); row = res->rowsCount() - 1; /* Move the cursor backwards to: n, n - 1, ... 1, 0. Return true if rows are available. */ while (res->previous()) { cout << "#\t\t Row " << row << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row--; } /* The last call to res->previous() has moved the cursor before the first row Cursor position is 0, recall: rows are from 1 ... n */ cout << "#\t\t isBeforeFirst() = " << res->isBeforeFirst() << endl; cout << "#\t\t isFirst() = " << res->isFirst() << endl; if (!res->isBeforeFirst()) { throw runtime_error("Cursor should be positioned before the first row"); } /* Move the cursor forward again to position 1 - the first row */ res->next(); cout << "#\t Positioning cursor to 1 using next(), isFirst() = " << res->isFirst() << endl; validateRow(res, min); /* Move the cursor to position 0 = before the first row */ if (false != res->absolute(0)) { throw runtime_error("Call did not fail although its not allowed to move the cursor before the first row"); } cout << "#\t Positioning before first row using absolute(0), isFirst() = " << res->isFirst() << endl; /* Move the cursor forward to position 1 = the first row */ res->next(); validateRow(res, min); /* Move the cursor to position 0 = before the first row */ res->beforeFirst(); cout << "#\t Positioning cursor using beforeFirst(), isFirst() = " << res->isFirst() << endl; /* Move the cursor forward to position 1 = the first row */ res->next(); cout << "#\t\t Moving cursor forward using next(), isFirst() = " << res->isFirst() << endl; validateRow(res, min); cout << "#\t Finally, reading in descending (reverse) order again" << endl; /* Move the cursor after the last row - n + 1 */ res->afterLast(); row = res->rowsCount() - 1; /* Move the cursor backwards to: n, n - 1, ... 1, 0. Return true if rows are available.*/ while (res->previous()) { cout << "#\t\t Row " << row << ", getRow() " << res->getRow(); cout << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row--; } /* The last call to res->previous() has moved the cursor before the first row Cursor position is 0, recall: rows are from 1 ... n */ cout << "#\t\t isBeforeFirst() = " << res->isBeforeFirst() << endl; if (true != res->isBeforeFirst()) { throw runtime_error("Position should be 0 = before first row"); } cout << "#\t And in regular order..." << endl; res->beforeFirst(); if (true != res->isBeforeFirst()) { throw runtime_error("Cursor should be positioned before the first row"); } row = 0; while (res->next()) { cout << "#\t\t Row " << row << ", getRow() " << res->getRow(); cout << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row++; } cout << "#\t\t isAfterLast() = " << res->isAfterLast() << endl; if (true != res->isAfterLast()) { throw runtime_error("next() has returned false and the cursor should be after the last row"); } /* Move to the last entry using a negative offset for absolute() */ cout << "#\t Trying absolute(-1) to fetch last entry..." << endl; if (true != res->absolute(-1)) { throw runtime_error("Call did fail although -1 is valid"); } cout << "#\t\t isAfterLast() = " << res->isAfterLast() << endl; if (false != res->isAfterLast()) { throw runtime_error("Cursor should be positioned to the last row and not after the last row"); } cout << "#\t\t isLast() = " << res->isLast() << endl; if (true != res->isLast()) { throw runtime_error("Cursor should be positioned to the last row"); } validateRow(res, max); /* Another way to move after the last entry */ cout << "#\t Trying absolute(NUMROWS + 10) to move cursor after last row and fetch last entry..." << endl; if (false != res->absolute(res->rowsCount() + 10)) { throw runtime_error("Call did fail although parameter is valid"); } if (true != res->isAfterLast()) { throw runtime_error("Cursor should be positioned after the last row"); } cout << "#\t\t isLast() = " << res->isLast() << endl; if (false != res->isLast()) { throw runtime_error("Cursor should be positioned after the last row"); } try { res->getString(1); throw runtime_error("Fetching is possible although cursor is out of range"); } catch (sql::InvalidArgumentException &) { cout << "#\t\t OK, fetching not allowed when cursor is out of range..." << endl; } /* absolute(NUM_ROWS + 10) is internally aligned to NUM_ROWS + 1 = afterLastRow() */ res->previous(); validateRow(res, max); } mysql-connector-c++-1.1.7/examples/resultset_binary.cpp000644 015771 000012 00000013417 12645244436 023711 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Handling binary data using getString() * */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" using namespace std; int main(int argc, const char **argv) { static const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* Driver Manager */ sql::Driver *driver; /* sql::ResultSet.rowsCount() returns size_t */ stringstream sql; int i; struct _test_data min, max; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ result set.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); con->setSchema(database); /* Creating a "simple" statement - "simple" = not a prepared statement */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, label CHAR(1), col_binary BINARY(4), col_varbinary VARBINARY(10))"); cout << "#\t Test table created" << endl; /* Populate the test table with data */ min = max = test_data[0]; for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { /* Remember mnin/max values for further testing */ if (test_data[i].id < min.id) { min = test_data[i]; } if (test_data[i].id > max.id) { max = test_data[i]; } /* KLUDGE: You should take measures against SQL injections! */ sql.str(""); sql << "INSERT INTO test(id, label, col_binary, col_varbinary) VALUES ("; sql << test_data[i].id << ", '" << test_data[i].label << "', "; sql << "\"a\\0b\", '" << i * 5 << "\\0abc')"; stmt->execute(sql.str()); } cout << "#\t Test table populated" << endl; cout << "#\t Testing sql::Statement based resultset" << endl; { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT * FROM test ORDER BY id ASC")); int row = 0; while (res->next()) { cout << "#\t\t Row " << row << ", getRow() " << res->getRow(); cout << " id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'"; /* cout might "hide" \0 and other special characters from the output */ cout << ", col_binary = '" << res->getString("col_binary") << "'"; cout << ", col_varbinary = '" << res->getString("col_varbinary") << "'" << endl; /* fixed length column - length = size of the column! */ if (res->getString("col_binary").length() != 4) { throw runtime_error("BINARY(n) should return std::string of length n regardless how long the value stored in the column is."); } if (res->getString("col_binary").compare(0, 1, "a")) { throw runtime_error("First sign from BINARY(n) seems wrong"); } if (res->getString("col_binary").compare(2, 1, "b")) { throw runtime_error("Third sign from BINARY(n) seems wrong"); } if (res->getString("col_varbinary").length() != 5 && res->getString("col_varbinary").length() != 6) { throw runtime_error("VARBINARY(n) should return std::string of length n which holds the length of the actual column value."); } sql::ResultSetMetaData * meta = res->getMetaData(); cout << "#\t\t COLUMN_SIZE = " << meta->getColumnDisplaySize(3) << endl; row++; } } /* Clean up */ /* stmt->execute("DROP TABLE IF EXISTS test");*/ cout << "# done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; // Use what(), getErrorCode() and getSQLState() cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/resultset_binary.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/resultset_binary.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/resultset_binary.cpp" << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/resultset_meta.cpp000644 015771 000012 00000030434 12645244436 023351 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Example of sql::ResultSetMetaData - meta data of a result set * */ // Standard C++ includes #include #include #include #include #include /* Public interface of the MySQL Connector/C++. You might not use it but directly include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include /* Connection parameter and sample data */ #include "examples.h" static void printResultSetMetaData(boost::scoped_ptr< sql::ResultSet > &res, boost::scoped_ptr< sql::ResultSet > &ps_res); using namespace std; /** * Meta data of a (simple) statements result set - not prepared statements */ int main(int argc, const char **argv) { const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); stringstream sql; unsigned int i; int ret; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ resultset metadata..." << endl; try { /* Using the Driver to create a conection */ boost::scoped_ptr< sql::Connection > con(sql::mysql::get_driver_instance()->connect(url, user, pass)); con->setSchema(database); /* Create a test table demonstrating the use of sql::Statement.execute() */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))"); cout << "#\t Test table created" << endl; /* Populate the test table with data */ for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { // KLUDGE: You should take measures against SQL injections! // example.h contains the test data sql.str(""); sql << "INSERT INTO test(id, label) VALUES ("; sql << test_data[i].id << ", '" << test_data[i].label << "')"; stmt->execute(sql.str()); } cout << "#\t Test table populated" << endl; { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id AS column_alias, label FROM test AS table_alias LIMIT 1")); boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("SELECT id AS column_alias, label FROM test AS table_alias LIMIT 1")); boost::scoped_ptr< sql::ResultSet > ps_res(prep_stmt->executeQuery()); cout << "#\t SELECT id AS column_alias, label FROM test AS table_alias LIMIT 1" << endl; printResultSetMetaData(res, ps_res); } { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT 1.01, 'Hello world!'")); boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("SELECT 1.01, 'Hello world!'")); boost::scoped_ptr< sql::ResultSet > ps_res(prep_stmt->executeQuery()); cout << "#\t SELECT 1.01, 'Hello world!'" << endl; printResultSetMetaData(res, ps_res); } { boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("DESCRIBE test")); boost::scoped_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("DESCRIBE test")); boost::scoped_ptr< sql::ResultSet > ps_res(prep_stmt->executeQuery()); cout << "# \tDESCRIBE test" << endl; printResultSetMetaData(res, ps_res); } /* Clean up */ stmt->execute("DROP TABLE IF EXISTS test"); cout << "# done!" << endl; ret = EXIT_SUCCESS; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what(), getErrorCode() and getSQLState() */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; ret = EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; ret = EXIT_FAILURE; } if (ret != EXIT_SUCCESS) { cout << "not "; } cout << "ok 1 - examples/resultset_meta.cpp" << endl; return ret; } /** * Prints all meta data associated with an result set * */ static void printResultSetMetaData(boost::scoped_ptr< sql::ResultSet > &res, boost::scoped_ptr< sql::ResultSet > &ps_res) { /* ResultSetMetaData object */ sql::ResultSetMetaData * meta; sql::ResultSetMetaData * ps_meta; unsigned int column; if (res->rowsCount() == 0) { throw runtime_error("FAILURE - no rows"); } /* Get the meta data - we leave all the exception handling to the caller... */ meta = res->getMetaData(); ps_meta = ps_res->getMetaData(); cout << "#\t Printing result set meta data" << endl; cout << "#\t res->rowsCount() = " << res->rowsCount() << endl; if (res->rowsCount() != ps_res->rowsCount()) throw runtime_error("rowsCount() different for PS and non-PS"); cout << "#\t meta->getColumnCount() = " << meta->getColumnCount() << endl; if (meta->getColumnCount() != ps_meta->getColumnCount()) throw runtime_error("getColumnCount() different for PS and non-PS"); /* Dump information for every column NOTE: column indexing is 1-based not zero-based! */ for (column = 1; column <= meta->getColumnCount(); column++) { cout << "#\t\t Column " << column << "\t\t\t= " << meta->getColumnName(column); cout << "/" << ps_meta->getColumnName(column) << endl; if (meta->getColumnName(column) != ps_meta->getColumnName(column)) throw runtime_error("getColumnName different for PS and non-PS"); cout << "#\t\t meta->getCatalogName()\t\t= " << meta->getCatalogName(column); cout << "/" << ps_meta->getCatalogName(column) << endl; if (meta->getCatalogName(column) != ps_meta->getCatalogName(column)) throw runtime_error("getCatalogName different for PS and non-PS"); cout << "#\t\t meta->getColumnDisplaySize() = " << meta->getColumnDisplaySize(column); cout << "/" << ps_meta->getColumnDisplaySize(column) << endl; if (meta->getColumnDisplaySize(column) != ps_meta->getColumnDisplaySize(column)) throw runtime_error("getColumnDisplaySize different for PS and non-PS"); cout << "#\t\t meta->getColumnLabel()\t\t= " << meta->getColumnLabel(column); cout << "/" << ps_meta->getColumnLabel(column) << endl; if (meta->getColumnLabel(column) != ps_meta->getColumnLabel(column)) throw runtime_error("getColumnLabel different for PS and non-PS"); cout << "#\t\t meta->getColumnName()\t\t= " << meta->getColumnName(column); cout << "/" << ps_meta->getColumnName(column) << endl; if (meta->getColumnName(column) != ps_meta->getColumnName(column)) throw runtime_error("getColumnName different for PS and non-PS"); cout << "#\t\t meta->getColumnType()\t\t= " << meta->getColumnType(column); cout << "/" << ps_meta->getColumnType(column) << endl; if (meta->getColumnType(column) != ps_meta->getColumnType(column)) throw runtime_error("getColumnType different for PS and non-PS"); cout << "#\t\t meta->getColumnTypeName()\t= " << meta->getColumnTypeName(column); cout << "/" << ps_meta->getColumnTypeName(column) << endl; if (meta->getColumnTypeName(column) != ps_meta->getColumnTypeName(column)) throw runtime_error("getColumnTypeName different for PS and non-PS"); cout << "#\t\t meta->getPrecision()\t\t= " << meta->getPrecision(column); cout << "/" << ps_meta->getPrecision(column) << endl; if (meta->getPrecision(column) != ps_meta->getPrecision(column)) throw runtime_error("getPrecision different for PS and non-PS"); cout << "#\t\t meta->getScale()\t\t= " << meta->getScale(column); cout << "/" << ps_meta->getScale(column) << endl; if (meta->getScale(column) != ps_meta->getScale(column)) throw runtime_error("getScale different for PS and non-PS"); cout << "#\t\t meta->getSchemaName()\t\t= " << meta->getSchemaName(column); cout << "/" << ps_meta->getSchemaName(column) << endl; if (meta->getSchemaName(column) != ps_meta->getSchemaName(column)) throw runtime_error("getSchemaName different for PS and non-PS"); cout << "#\t\t meta->getTableName()\t\t= " << meta->getTableName(column); cout << "/" << ps_meta->getTableName(column) << endl; if (meta->getTableName(column) != ps_meta->getTableName(column)) throw runtime_error("getTableName different for PS and non-PS"); cout << "#\t\t meta->isAutoIncrement()\t= " << meta->isAutoIncrement(column); cout << "/" << ps_meta->isAutoIncrement(column) << endl; if (meta->isAutoIncrement(column) != ps_meta->isAutoIncrement(column)) throw runtime_error("isAutoIncrement different for PS and non-PS"); cout << "#\t\t meta->isCaseSensitive()\t= " << meta->isCaseSensitive(column); cout << "/" << ps_meta->isCaseSensitive(column) << endl; if (meta->isCaseSensitive(column) != ps_meta->isCaseSensitive(column)) throw runtime_error("isCaseSensitive different for PS and non-PS"); cout << "#\t\t meta->isCurrency()\t\t= " << meta->isCurrency(column); cout << "/" << ps_meta->isCurrency(column) << endl; if (meta->isCurrency(column) != ps_meta->isCurrency(column)) throw runtime_error("isCurrency different for PS and non-PS"); cout << "#\t\t meta->isDefinitelyWritable()\t= " << meta->isDefinitelyWritable(column); cout << "/" << ps_meta->isDefinitelyWritable(column) << endl; if (meta->isDefinitelyWritable(column) != ps_meta->isDefinitelyWritable(column)) throw runtime_error("isDefinitelyWritable different for PS and non-PS"); cout << "#\t\t meta->isNullable()\t\t= " << meta->isNullable(column); cout << "/" << ps_meta->isNullable(column) << endl; if (meta->isNullable(column) != ps_meta->isNullable(column)) throw runtime_error("isNullable different for PS and non-PS"); cout << "#\t\t meta->isReadOnly()\t\t= " << meta->isReadOnly(column); cout << "/" << ps_meta->isReadOnly(column) << endl; if (meta->isReadOnly(column) != ps_meta->isReadOnly(column)) throw runtime_error("isReadOnly different for PS and non-PS"); cout << "#\t\t meta->isSearchable()\t\t= " << meta->isSearchable(column); cout << "/" << ps_meta->isSearchable(column) << endl; if (meta->isSearchable(column) != ps_meta->isSearchable(column)) throw runtime_error("isSearchable different for PS and non-PS"); cout << "#\t\t meta->isSigned()\t\t= " << meta->isSigned(column); cout << "/" << ps_meta->isSigned(column) << endl; if (meta->isSigned(column) != ps_meta->isSigned(column)) throw runtime_error("isSigned different for PS and non-PS"); cout << "#\t\t meta->isWritable()\t\t= " << meta->isWritable(column); cout << "/" << ps_meta->isWritable(column) << endl; if (meta->isWritable(column) != ps_meta->isWritable(column)) throw runtime_error("isWritable different for PS and non-PS"); } try { res->close(); meta = res->getMetaData(); } catch (sql::SQLException &e) { cout << "#\t Excepted exception (I) when trying to get meta data after close:" << endl; cout << "#\t " << e.what() << endl; } try { ps_res->close(); ps_meta = ps_res->getMetaData(); } catch (sql::SQLException &e) { cout << "#\t Excepted exception (II) when trying to get meta data after close:" << endl; cout << "#\t " << e.what() << endl; } } mysql-connector-c++-1.1.7/examples/resultset_types.cpp000644 015771 000012 00000021562 12645244436 023571 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Basic example demonstrating how to check the type of a result set column * */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" #ifdef _WIN32 #define L64(x) x##i64 #else #define L64(x) x##LL #endif using namespace std; int main(int argc, const char **argv) { const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* Driver Manager */ sql::Driver *driver; struct _test_data min, max; int c_int1; bool c_bool1 = true, c_bool2; /* TODO: long long is not C++, its C99 !!! */ int64_t c_long1 = L64(9223372036854775807), c_long2; double c_double1 = -999.9999, c_double2; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ result set.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); con->setSchema(database); boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); /* Note that MySQL has its very own mapping from SQL type (e.g. BOOLEAN) specified in a SQL statement and type actually used. Check the MySQL manual - conversions are a common cause of false bug reports! Also, don't get confused by the precision of float/double columns. For precision math use DECIMAL! */ stmt->execute("CREATE TABLE test(id INT, label CHAR(1), c_bool BOOLEAN, " "c_long BIGINT, c_double DOUBLE, c_null INT DEFAULT NULL)"); cout << "#\t Test table created" << endl; boost::scoped_ptr< sql::PreparedStatement> prep_stmt( con->prepareStatement("INSERT INTO test(id, label, c_bool, c_long, " " c_double) VALUES (?, ?, ?, ?, ?)")); /* Populate the test table with data */ min = max = test_data[0]; for (unsigned int i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { /* Remember min/max for further testing */ if (test_data[i].id < min.id) { min = test_data[i]; } if (test_data[i].id > max.id) { max = test_data[i]; } prep_stmt->setInt(1, test_data[i].id); prep_stmt->setString(2, test_data[i].label); prep_stmt->setBoolean(3, c_bool1); prep_stmt->setInt64(4, c_long1); prep_stmt->setDouble(5, c_double1); prep_stmt->execute(); } cout << "#\t Test table populated" << endl; boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT id, label, c_bool, c_long, c_double, c_null FROM test ORDER BY id ASC")); while (res->next()) { /* sql::ResultSet.rowsCount() returns size_t */ size_t row = res->getRow() - 1; cout << "#\t\t Row " << res->getRow() << endl; cout << "#\t\t\t id INT = " << res->getInt("id") << endl; cout << "#\t\t\t id (as Integer) = " << res->getInt("id") << endl; cout << "#\t\t\t id (as String) = " << res->getString("id") << endl; cout << "#\t\t\t id (as Boolean) = " << res->getBoolean("id") << endl; cout << "#\t\t\t id (as Long) = " << res->getInt64("id") << endl; cout << "#\t\t\t id (as Double) = " << res->getDouble("id") << endl; cout << "#" << endl; if (test_data[row].id != res->getInt(1)) { throw runtime_error("Wrong results for column id"); } std::string c_string = res->getString(2); cout << "#\t\t\t label CHAR(1) = " << c_string << endl; cout << "#\t\t\t label (as Integer) = " << res->getInt(2) << endl; cout << "#\t\t\t label (as String) = " << res->getString(2) << endl; cout << "#\t\t\t label (as Boolean) = " << res->getBoolean(2) << endl; cout << "#\t\t\t label (as Long) = " << res->getInt64(2) << endl; cout << "#\t\t\t label (as Double) = " << res->getDouble(2) << endl; cout << "#" << endl; if (test_data[row].label != c_string) { throw runtime_error("Wrong result for column label"); } c_bool2 = res->getBoolean("c_bool"); cout << "#\t\t\t c_bool CHAR(1) = " << c_bool2 << endl; cout << "#\t\t\t c_bool (as Integer) = " << res->getInt(3) << endl; cout << "#\t\t\t c_bool (as String) = " << res->getString(3) << endl; cout << "#\t\t\t c_bool (as Boolean) = " << res->getBoolean(3) << endl; cout << "#\t\t\t c_bool (as Long) = " << res->getInt64(3) << endl; cout << "#\t\t\t c_bool (as Double) = " << res->getDouble(3) << endl; cout << "#" << endl; if (c_bool1 != c_bool2) { throw runtime_error("Wrong result for column c_bool"); } c_long2 = res->getInt64("c_long"); cout << "#\t\t\t c_long BIGINT = " << c_long2 << endl; cout << "#\t\t\t c_long (as Integer) = " << res->getInt("c_long") << endl; cout << "#\t\t\t c_long (as String) = " << res->getString("c_long") << endl; cout << "#\t\t\t c_long (as Boolean) = " << res->getBoolean("c_long") << endl; cout << "#\t\t\t c_long (as Long) = " << res->getInt64("c_long") << endl; cout << "#\t\t\t c_long (as Double) = " << res->getDouble("c_long") << endl; cout << "#" << endl; if (c_long1 != c_long2) { throw runtime_error("Wrong result for column c_long"); } c_double2 = res->getDouble("c_double"); cout << "#\t\t\t c_double DOUBLE = " << c_double2 << endl; cout << "#\t\t\t c_double (as Integer) = " << res->getInt("c_double") << endl; cout << "#\t\t\t c_double (as String) = " << res->getString("c_double") << endl; cout << "#\t\t\t c_double (as Boolean) = " << res->getBoolean("c_double") << endl; cout << "#\t\t\t c_double (as Long) = " << res->getInt64("c_double") << endl; cout << "#\t\t\t c_double (as Double) = " << res->getDouble("c_double") << endl; cout << "#\t\t\t c_double wasNull() = " << res->wasNull() << endl; cout << "#" << endl; if (c_double1 != c_double2) { throw runtime_error("Wrong result for column c_double"); } c_int1 = res->getInt("c_null"); cout << "#\t\t\t c_null INT DEFAULT NULL = " << c_int1; cout << " (isNull = " << res->isNull("c_null") << ")" << endl; cout << "#\t\t\t c_null (as Integer) = " << res->getInt("c_null") << endl; cout << "#\t\t\t c_null (as String) = " << res->getString("c_null") << endl; cout << "#\t\t\t c_null (as Boolean) = " << res->getBoolean("c_null") << endl; cout << "#\t\t\t c_null (as Long) = " << res->getInt64("c_null") << endl; cout << "#\t\t\t c_null (as Double) = " << res->getDouble("c_null") << endl; cout << "#\t\t\t c_null wasNull() = " << res->wasNull() << endl; cout << "#" << endl; if (!res->isNull(6) || !res->wasNull()) { throw runtime_error("isNull() or wasNull() has not reported NULL value of column c_null"); } } /* Clean up */ stmt->execute("DROP TABLE IF EXISTS test"); cout << "# done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what(), getErrorCode() and getSQLState() */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/resultset_types.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/resultset_types.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/resultset_types.cpp" << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/standalone_example.cpp000755 015771 000012 00000010244 12645244436 024154 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Basic example of creating a stand alone program linked against Connector/C++ * * This example is not integrated into the Connector/C++ build environment. * You must run "make install" prior to following the build instructions * given here. * * To compile the standalone example on Linux try something like: * * /usr/bin/c++ * -o standalone * -I/usr/local/include/cppconn/ * -Wl,-Bdynamic -lmysqlcppconn * examples/standalone_example.cpp * * To run the example on Linux try something similar to: * * LD_LIBRARY_PATH=/usr/local/lib/ ./standalone * * or: * * LD_LIBRARY_PATH=/usr/local/lib/ ./standalone host user password database * */ /* Standard C++ includes */ #include #include #include #include #include /* Include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include "mysql_connection.h" #include "mysql_driver.h" #include #include #include #include #define EXAMPLE_HOST "localhost" #define EXAMPLE_USER "root" #define EXAMPLE_PASS "" #define EXAMPLE_DB "test" using namespace std; /** * Usage example for Driver, Connection, (simple) Statement, ResultSet */ int main(int argc, const char **argv) { string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); cout << endl; cout << "Connector/C++ standalone program example..." << endl; cout << endl; try { sql::Driver * driver = sql::mysql::get_driver_instance(); /* Using the Driver to create a connection */ boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); con->setSchema(database); boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); boost::scoped_ptr< sql::ResultSet > res(stmt->executeQuery("SELECT 'Welcome to Connector/C++' AS _message")); cout << "\t... running 'SELECT 'Welcome to Connector/C++' AS _message'" << endl; while (res->next()) { cout << "\t... MySQL replies: " << res->getString("_message") << endl; cout << "\t... say it again, MySQL" << endl; cout << "\t....MySQL replies: " << res->getString(1) << endl; } } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; /* Use what() (derived from std::runtime_error) to fetch the error message */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; return EXIT_FAILURE; } cout << endl; cout << "... find more at http://www.mysql.com" << endl; cout << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/standalone_example_docs1.cpp000644 015771 000012 00000005173 12645244436 025247 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Standard C++ includes */ #include #include /* Include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include "mysql_connection.h" #include #include #include #include using namespace std; int main(void) { cout << endl; cout << "Running 'SELECT 'Hello World!' AS _message'..." << endl; try { sql::Driver *driver; sql::Connection *con; sql::Statement *stmt; sql::ResultSet *res; /* Create a connection */ driver = sql::mysql::get_driver_instance(); con = driver->connect("tcp://127.0.0.1:3306", "root", "root"); /* Connect to the MySQL test database */ con->setSchema("test"); stmt = con->createStatement(); res = stmt->executeQuery("SELECT 'Hello World!' AS _message"); while (res->next()) { cout << "\t... MySQL replies: "; /* Access column data by alias or column name */ cout << res->getString("_message") << endl; cout << "\t... MySQL says it again: "; /* Access column fata by numeric offset, 1 is the first column */ cout << res->getString(1) << endl; } delete res; delete stmt; delete con; } catch (sql::SQLException &e) { cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } cout << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/standalone_example_docs2.cpp000644 015771 000012 00000005661 12645244436 025252 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Standard C++ includes */ #include #include /* Include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h (and mysql_connection.h). This will reduce your build time! */ #include "mysql_connection.h" #include #include #include #include #include using namespace std; int main(void) { cout << endl; cout << "Let's have MySQL count from 10 to 1..." << endl; try { sql::Driver *driver; sql::Connection *con; sql::Statement *stmt; sql::ResultSet *res; sql::PreparedStatement *pstmt; /* Create a connection */ driver = sql::mysql::get_driver_instance(); con = driver->connect("tcp://127.0.0.1:3306", "root", "root"); /* Connect to the MySQL test database */ con->setSchema("test"); stmt = con->createStatement(); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); delete stmt; /* '?' is the supported placeholder syntax */ pstmt = con->prepareStatement("INSERT INTO test(id) VALUES (?)"); for (int i = 1; i <= 10; i++) { pstmt->setInt(1, i); pstmt->executeUpdate(); } delete pstmt; /* Select in ascending order */ pstmt = con->prepareStatement("SELECT id FROM test ORDER BY id ASC"); res = pstmt->executeQuery(); /* Fetch in reverse = descending order! */ res->afterLast(); while (res->previous()) cout << "\t... MySQL counts: " << res->getInt("id") << endl; delete res; delete pstmt; delete con; } catch (sql::SQLException &e) { cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } cout << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/examples/statement.cpp000644 015771 000012 00000012271 12645244436 022314 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * * Example of sql::Statement - "simple" (not prepared) statements * */ /* Standard C++ includes */ #include #include #include #include #include /* Public interface of the MySQL Connector/C++ */ #include /* Connection parameter and sample data */ #include "examples.h" using namespace std; /** * Example of statements - not to be confused with prepared statements */ int main(int argc, const char **argv) { static const string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); /* Driver Manager */ sql::Driver *driver; /* sql::ResultSet.rowsCount() returns size_t */ size_t row; stringstream sql; int i; bool ok; cout << boolalpha; cout << "1..1" << endl; cout << "# Connector/C++ (simple) statement example.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); boost::scoped_ptr< sql::Connection > con(driver->connect(url, user, pass)); con->setSchema(database); /* Creating a "simple" statement - "simple" = not a prepared statement */ boost::scoped_ptr< sql::Statement > stmt(con->createStatement()); /* Create a test table demonstrating the use of sql::Statement.execute() */ stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))"); cout << "#\t Test table created" << endl; /* Populate the test table with data */ for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { // KLUDGE: You should take measures against SQL injections! // example.h contains the test data sql.str(""); sql << "INSERT INTO test(id, label) VALUES ("; sql << test_data[i].id << ", '" << test_data[i].label << "')"; stmt->execute(sql.str()); } cout << "#\t Test table populated" << endl; /* NOTE: Use execute() instead of the more convenient executeQuery() See the other example file for executeQuery() and executeUpdate() examples However, if you are executing SQL dynamically, you might have to use execute() */ ok = stmt->execute("SELECT id, label FROM test ORDER BY id ASC"); cout << "#\t stmt->execute('SELECT id, label FROM test ORDER BY id ASC') = "; cout << ok << endl; if (ok == true) { /* The first result is a result set */ cout << "#\t\t Fetching results" << endl; /* NOTE: If stmt.getMoreResults() would be implemented already one would use a do { ... } while (stmt.getMoreResults()) loop */ boost::scoped_ptr< sql::ResultSet > res(stmt->getResultSet()); row = 0; while (res->next()) { cout << "#\t\t Row " << row << " - id = " << res->getInt("id"); cout << ", label = '" << res->getString("label") << "'" << endl; row++; } } else if (ok == false) { /* The first result is an update count */ throw runtime_error("Expecting regular result set"); } /* Clean up */ stmt->execute("DROP TABLE IF EXISTS test"); cout << "# done!" << endl; } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; // Use what(), getErrorCode() and getSQLState() cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; cout << "not ok 1 - examples/statement.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << EXAMPLE_FUNCTION << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/statement.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/statement.cpp" << endl; return EXIT_SUCCESS; } mysql-connector-c++-1.1.7/extract_build_info.php000644 015771 000012 00000021213 12645244436 022337 0ustar00pb2userwheel000000 000000 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This is an undocumented and unsupported utility script which we use to update http://forge.mysql.com/wiki/Connector_C%2B%2B_Binary_Builds. It scans our internal build logs and extracts the information which you can find in the README files contained in every binary distributions. Usage: php extract_build_info.php /path/to/build_logs/*.txt */ $regex = "/^\s*(c\+{0,2}?\s+compiler|cmake\s*version|mysql\s*version|cc|cflagscxx|cxxflags|ldflags|picopt)\s*(?::|=)\s*(.*)/i"; function printHTML($fname) { global $regex; $props = array(); $f = file($fname); foreach ($f as $line) { if (preg_match($regex, trim($line), $matches)) { $props[trim($matches[1])] = trim($matches[2]); } } echo "----------\n"; echo "$fname\n"; foreach($props as $k=>$v) { echo "$k$v\n"; } echo "----------\n"; } function printWiki($fname) { global $regex; static $rowno = 1; $core = array("C compiler" => true, "C++ compiler" => true, "CMake version" => true, "MySQL version" => true); $props = array(); $f = file($fname); foreach ($f as $line) { if (preg_match($regex, trim($line), $matches)) { $props[trim($matches[1])] = trim($matches[2]); } } $platform = ucfirst(substr(trim(basename($fname)), 0, -4)); $platform_mapping = array( 'Aix5.2-ppc32' => 'AIX 5.2 (POWER, 32bit)', 'Aix5.2-ppc64' => 'AIX 5.2 (POWER, 64-bit)', 'Aix5.3-ppc32' => 'AIX 5.3 (POWER, 32-bit)', 'Aix5.3-ppc64' => 'AIX 5.3 (POWER, 64-bit)', 'Freebsd6-x86_64' => 'FreeBSD 6.x (x86_64)', 'Freebsd6-x86' => 'FreeBSD 6.x (x86)', 'Freebsd7-x86_64' => 'FreeBSD 7.x (x86_64)', 'Freebsd7-x86' => 'FreeBSD 7.x (x86)', 'Hpux11.11-hppa32' => 'HP-UX 11.11 (PA-RISC 1.1, 32-bit only)', 'Hpux11.11-hppa64' => 'HP-UX 11.11 (PA-RISC 2.0, 64-bit only)', 'Hpux11.23-ia64' => 'HP-UX 11.23 (IA64, 64-bit)', 'I5os-ppc32' => 'i5/OS (POWER, 32-bit)', 'I5os-ppc64' => 'i5/OS (POWER, 64-bit)', 'Linux-ia64' => 'Linux (IA64)', 'Linux-x86_64' => 'Linux (AMD64 / Intel EM64T)', 'Linux-x86' => 'Linux (x86)', 'Linux-rhel4-ia64' => 'Red Hat Enterprise Linux 4 (IA64)', 'Linux-rhel4-x86_64'=> 'Red Hat Enterprise Linux 4 (AMD64 / Intel EM64T)', 'Linux-rhel4-x86' => 'Red Hat Enterprise Linux 4 (x86)', 'Linux-rhel5-ia64' => 'Red Hat Enterprise Linux 5 (IA64)', 'Linux-rhel5-x86_64'=> 'Red Hat Enterprise Linux 5 (AMD64 / Intel EM64T)', 'Linux-rhel5-x86' => 'Red Hat Enterprise Linux 5 (x86)', 'Linux-sles9-ia64' => 'SuSE Linux Enterprise Server 9 (IA64)', 'Linux-sles9-x86_64'=> 'SuSE Linux Enterprise Server 9 (AMD64 / Intel EM64T)', 'Linux-sles9-x86' => 'SuSE Linux Enterprise Server 9 (x86)', 'Linux-sles10-ia64' => 'SuSE Linux Enterprise Server 10 (IA64)', 'Linux-sles10-x86_64'=> 'SuSE Linux Enterprise Server 10 (AMD64 / Intel EM64T)', 'Linux-sles10-x86' => 'SuSE Linux Enterprise Server 10 (x86)', 'Macosx10.4-ppc32' => 'Mac OS X 10.4 (PowerPC, 32-bit)', 'Macosx10.4-ppc64' => 'Mac OS X 10.4 (PowerPC, 64-bit)', 'Macosx10.4-x86' => 'Mac OS X 10.4 (x86)', 'Macosx10.4-x86_64' => 'Mac OS X 10.4 (x86_64)', 'Macosx10.5-ppc32' => 'Mac OS X 10.5 (PowerPC, 32-bit)', 'Macosx10.5-ppc64' => 'Mac OS X 10.5 (PowerPC, 64-bit)', 'Macosx10.5-x86' => 'Mac OS X 10.5 (x86)', 'Macosx10.5-x86_64' => 'Mac OS X 10.5 (x86_64)', 'Solaris10-sparc32' => 'Solaris 10 (SPARC, 32-bit)', 'Solaris10-sparc64' => 'Solaris 10 (SPARC, 64-bit)', 'Solaris10-x86' => 'Solaris 10 (x86, 32-bit)', 'Solaris10-x86_64' => 'Solaris 10 (AMD64 / Intel EM64T, 64-bit)', 'Solaris9-sparc32' => 'Solaris 9 (SPARC, 32-bit)', 'Solaris9-sparc64' => 'Solaris 9 (SPARC, 64-bit)', 'Solaris9-x86' => 'Solaris 9 (x86, 32-bit)', 'Solaris9-x86_64' => 'Solaris 9 (AMD64 / Intel EM64T, 64-bit)', 'Solaris8-sparc32' => 'Solaris 8 (SPARC, 32-bit)', 'Solaris8-sparc64' => 'Solaris 8 (SPARC, 64-bit)', 'Solaris8-x86' => 'Solaris 8 (x86, 32-bit)', 'Solaris8-x86_64' => 'Solaris 8 (AMD64 / Intel EM64T, 64-bit)', 'Win32' => 'Windows', 'Winx64' => 'Windows x64', ); printf("|-\n"); printf("! bgcolor='%s' valign='top' colspan='5' align='center' |%s\n", ($rowno % 2) ? "#f0f0f0" : "#ffffff", (isset($platform_mapping[$platform])) ? $platform_mapping[$platform] : $platform); printf("|-\n"); foreach ($core as $k => $v) { switch ($k) { case 'CMake version': $props[$k] = trim(substr(trim($props[$k]), strlen("cmake version"))); switch ($props[$k]) { case '2.6-patch 2': $props[$k] = '2.6.2'; break; case '2.6-patch 3': $props[$k] = '2.6.3'; break; default: break; } break; case 'C compiler': if (substr($props[$k], 0, 3) == 'cc:') { $props[$k] = substr(trim($props[$k]), 3); } break; case 'C++ compiler': if (substr($props[$k], 0, 3) == 'CC:') { $props[$k] = substr(trim($props[$k]), 3); } break; default: if ($platform == 'Win32' || $platform == 'Winx64') { $props[$k] = 'See above!'; } break; } printf("| bgcolor='%s' valign='top'|%s\n", ($rowno % 2) ? "#f0f0f0" : "#ffffff", trim($props[$k])); unset($props[$k]); } printf("| bgcolor='%s' valign='top'|\n", ($rowno % 2) ? "#f0f0f0" : "#ffffff"); foreach ($props as $k => $v) { printf(" %s = %s\n", trim($k), trim($v)); } $rowno++; } ?>
{| class="wikitable" |- ! bgcolor="#d0d0d0" colspan="5" align="center" |Platform |- ! bgcolor="#d0d0d0"|C compiler ! bgcolor="#d0d0d0"|C++ compiler ! bgcolor="#d0d0d0"|CMake ! bgcolor="#d0d0d0"|MySQL ! bgcolor="#d0d0d0"|Settings $v) { for($i = 1; $i < $argc; $i++) { $platform = strtolower(substr(trim(basename($argv[$i])), 0, -4)); if ($v == $platform) { printWiki($argv[$i]); unset($argv[$i]); break; } } } ?> |} 1) { printf("ERROR?"); var_dump($argv); } ?>mysql-connector-c++-1.1.7/test/CJUnitTestsPort/BaseTestFixture.cpp000644 015771 000012 00000064056 12645244436 025566 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "BaseTestFixture.h" #include "../common/stringutils.h" namespace testsuite { static const String defaultHost= _T("127.0.0.1"); static const String defaultPort= _T("3306"); static const String defaultDb= _T("test"); static const String defaultLogin= _T("root"); static const String defaultPasswd= _T("root"); int TestFixtureCommon::instanceCount=1; Properties TestFixtureCommon::sqlProps; static const char * possiblePropertiesLocations[]={".." , "test/CJUnitTestsPort" , NULL //last should be NULL }; int TestFixtureCommon::propsLoaded=resources::LoadProperties("sql.properties" , sqlProps , possiblePropertiesLocations); Driver * TestFixtureCommon::driver=NULL; TestFixtureCommon::TestFixtureCommon() { init(); } void TestFixtureCommon::init() { host= TestsRunner::getStartOptions()->getString( "dbUrl" ); login= TestsRunner::getStartOptions()->getString( "dbUser" ); passwd= TestsRunner::getStartOptions()->getString( "dbPasswd" ); db= TestsRunner::getStartOptions()->getString( "dbSchema" ); } String TestFixtureCommon::extractVal(const String & sTableName , int count , Properties & sqlProps , Connection & conn) { String sKeyName; String insertString; String retStr; String parameters; List sToken; try { sKeyName=sTableName; sKeyName.append("_Insert"); insertString=sqlProps[ sKeyName ]; String::size_type openPar=insertString.find_first_of("(") + 1; parameters=insertString.substr( openPar, insertString.find_first_of(")", 1) - openPar); StringUtils::split(sToken, parameters, ","); retStr=sToken[ count - 1]; if (sTableName == "Bit_Tab" || sTableName == "Boolean_Tab") { if (retStr == "1") { retStr="true"; } else if (retStr == "0") { retStr="false"; } } } catch (std::exception & e) { logErr(String("Exception ") + e.what()); FAIL("Call to extractVal is Failed!"); } return retStr; } void TestFixtureCommon::logMsg(String message) { TestsListener::messagesLog() << message << std::endl; } void TestFixtureCommon::logErr(String message) { TestsListener::errorsLog() << message << std::endl; /*new Throwable().printStackTrace();*/ } String TestFixtureCommon::randomString() { srand((unsigned) time(NULL)); int length=(rand() % 32); String buf, ch("a"); buf.resize(length); for (int i=0; i < length; i++) { ch.assign(static_cast (1), static_cast ('a' + rand() % 26)); buf.append(ch); } return buf; } /** value_object methods */ value_object::value_object() : wasNull(true) { } value_object::value_object(const sql::ResultSet * rs, int colNum) : asString(rs->getString(colNum)) { wasNull=rs->wasNull(); } bool value_object::isNull() const { return wasNull; } int value_object::intValue() const { return StringUtils::toInt(asString, wasNull); } float value_object::floatValue() const { return StringUtils::toFloat(asString, wasNull); } long long value_object::longValue() const { return StringUtils::toLong(asString, wasNull); } value_object * getObject(sql::ResultSet * rs, int colNum) { return new value_object(rs, colNum); } /* few temporary hacks*/ bool value_object::instanceof(value_type type) { if (type < vtLast) { switch (type) { case vtByte: return true; case vtFloat: case vtDouble: { long long llValue=longValue(); if (llValue != 0) { double dValue=doubleValue(); return ( dValue > llValue ? dValue - llValue : llValue - dValue) > 0.001; } } default: return false; } } return false; } /** * Creates a new BaseTestFixture object. * * @param name * The name of the JUnit test case */ BaseTestFixture::BaseTestFixture(const String & name) : super (name), TestFixtureCommon (), myInstanceNumber (0), conn (NULL), pstmt(NULL), stmt(NULL), rs(NULL), /*dbClass ( "sql::mysql::Driver"),*/ hasSps(true) { this->myInstanceNumber=instanceCount++; } void BaseTestFixture::createStandardTable(standard_tables table) { try { switch (table) { case TABLE_CTSTABLE1: createTable("ctstable1", "(TYPE_ID int(11) NOT NULL default '0', TYPE_DESC varchar(32) default NULL, PRIMARY KEY (TYPE_ID)) ENGINE=InnoDB"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (1,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (2,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (3,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (4,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (5,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (6,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (7,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (8,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (9,NULL)"); this->stmt->executeUpdate("INSERT INTO ctstable1 VALUES (10,NULL)"); break ; case TABLE_CTSTABLE2: createStandardTable(TABLE_CTSTABLE1); createTable("ctstable2", "(KEY_ID int(11) NOT NULL DEFAULT '0', COF_NAME varchar(32) DEFAULT NULL, PRICE float DEFAULT NULL, TYPE_ID int(11) DEFAULT NULL, PRIMARY KEY (KEY_ID), KEY TYPE_ID (TYPE_ID), CONSTRAINT ctstable2_ibfk_1 FOREIGN KEY (TYPE_ID) REFERENCES ctstable1 (TYPE_ID)) ENGINE=InnoDB"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (2,'Continue-2',2,2)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (3,'COFFEE-3',3,2)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (4,'COFFEE-4',4,3)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (5,'COFFEE-5',5,3)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (6,'COFFEE-6',6,3)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (7,'COFFEE-7',7,4)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (8,'COFFEE-8',8,4)"); this->stmt->executeUpdate("INSERT INTO ctstable2 VALUES (9,'COFFEE-9',9,4)"); break; case TABLE_INTEGERTAB: createTable("Integer_Tab", "(MAX_VAL int(11) default NULL, MIN_VAL int(11) default NULL, NULL_VAL int(11) default NULL) ENGINE=InnoDB"); break; case TABLE_BITTAB: createTable("Bit_Tab", "(MAX_VAL tinyint(1) default NULL, MIN_VAL tinyint(1) default NULL, NULL_VAL tinyint(1) default NULL) ENGINE=InnoDB"); break; case TABLE_DOUBLETAB: createTable("Double_Tab", "(MAX_VAL double default NULL, MIN_VAL double default NULL, NULL_VAL double default NULL) ENGINE=InnoDB"); break; case TABLE_BIGINTTAB: createTable("Bigint_Tab", "(MAX_VAL bigint(20) default NULL, MIN_VAL bigint(20) default NULL, NULL_VAL bigint(20) default NULL) ENGINE=InnoDB"); break; case TABLE_CHARTAB: createTable("Char_Tab", "(COFFEE_NAME char(30) default NULL, NULL_VAL char(30) default NULL) ENGINE=InnoDB"); break; case TABLE_VARCHARTAB: createTable("Varchar_Tab", "(COFFEE_NAME varchar(30) default NULL, NULL_VAL varchar(30) default NULL) ENGINE=InnoDB"); break; case TABLE_FLOATTAB: createTable("Float_Tab", "(MAX_VAL float default NULL, MIN_VAL float default NULL, NULL_VAL float default NULL) ENGINE=InnoDB"); break; case TABLE_SMALLINTTAB: createTable("Smallint_Tab", "(MAX_VAL smallint(6) default NULL, MIN_VAL smallint(6) default NULL, NULL_VAL smallint(6) default NULL) ENGINE=InnoDB"); break; case TABLE_LONGVARCHARNULLTAB: createTable("Longvarcharnull_Tab", "(NULL_VAL mediumtext) ENGINE=InnoDB"); break; } } catch (sql::SQLException &e) { logErr(e.what()); fail(e.what(), __FILE__, __LINE__); } } /* throws SQLException & */ void BaseTestFixture::createSchemaObject(String objectType, String objectName, String columnsAndOtherStuff) { this->createdObjects.push_back(objectType); this->createdObjects.push_back(objectName); dropSchemaObject(objectType, objectName); String createSql(_T("CREATE ")); /* createSql.resize(objectName.length() + objectType.length() + columnsAndOtherStuff.length() + 10);*/ createSql.append(objectType); createSql.append(" "); createSql.append(objectName); createSql.append(" "); createSql.append(columnsAndOtherStuff); this->stmt->executeUpdate(createSql); } /* throws SQLException & */ void BaseTestFixture::createFunction(String functionName, String functionDefn) { createSchemaObject("FUNCTION", functionName, functionDefn); } /* throws SQLException & */ void BaseTestFixture::dropFunction(String functionName) { dropSchemaObject("FUNCTION", functionName); } /* throws SQLException & */ void BaseTestFixture::createProcedure(String procedureName, String procedureDefn) { createSchemaObject("PROCEDURE", procedureName, procedureDefn); } /* throws SQLException & */ void BaseTestFixture::dropProcedure(String procedureName) { dropSchemaObject("PROCEDURE", procedureName); } /* throws SQLException & */ void BaseTestFixture::createTable(String tableName, String columnsAndOtherStuff) { createSchemaObject("TABLE", tableName, columnsAndOtherStuff); } /* throws SQLException & */ void BaseTestFixture::dropTable(String tableName) { dropSchemaObject("TABLE", tableName); } /* throws SQLException & */ void BaseTestFixture::dropSchemaObject(String objectType, String objectName) { this->stmt->execute("SET foreign_key_checks = 0"); this->stmt->executeUpdate(String("DROP ") + objectType + " IF EXISTS " + objectName); this->stmt->execute("SET foreign_key_checks = 1"); } /* throws SQLException & */ sql::Connection * BaseTestFixture::getAdminConnection() { return getAdminConnectionWithProps(Properties()); } /* throws SQLException & */ sql::Connection * BaseTestFixture::getAdminConnectionWithProps(Properties props) { if (driver) { return driver->connect(host, /*port,*/ login, passwd); //adminUrl, props); } else { return NULL; } } /* getConnectionWith Props are legacy. Currently not used. Require changes in order to work */ /* throws SQLException & */ sql::Connection * BaseTestFixture::getConnectionWithProps(const String & propsList) { return getConnectionWithProps(host, propsList); } /* throws SQLException & */ sql::Connection * BaseTestFixture::getConnectionWithProps(const String & url , const String & propsList) { Properties props; List keyValuePairs; StringUtils::split(keyValuePairs, propsList, _T(","), false); for (Iterator iter=keyValuePairs.begin(); iter != keyValuePairs.end(); ++iter) { String kvp= *iter; List splitUp; StringUtils::split(splitUp, kvp, _T("="), false); String value; for (unsigned i=1; i < splitUp.size(); i++) { if (i != 1) { value.append(_T("=")); } value.append(splitUp[ i ]); } props[ StringUtils::trim(splitUp[ 0 ]) ]=value; } return getConnectionWithProps(url, props); } /** * Returns a new connection with the given properties * * @param props * the properties to use (the URL will come from the standard for * this testcase). * * @return a new connection using the given properties. * * @throws SQLException & * DOCUMENT ME! */ /* throws SQLException & */ sql::Connection * BaseTestFixture::getConnectionWithProps(const Properties & props) { return driver ? driver->connect(host, /*port,*/ login, passwd) : NULL; //dbUrl, props); } /* throws SQLException & */ sql::Connection * BaseTestFixture::getConnectionWithProps(const String & url, const Properties & props) { return driver ? driver->connect(host, /*port,*/ login, passwd) : NULL; //dbUrl, props); } /** * Returns the per-instance counter (for messages when multi-threading * stress tests) * * @return int the instance number */ int BaseTestFixture::getInstanceNumber() { return this->myInstanceNumber; } /* throws SQLException & */ String BaseTestFixture::getMysqlVariable(Connection & c , const String & variableName) { value_object value(getSingleIndexedValueWithQuery(c, 2, "SHOW VARIABLES LIKE '" + variableName + "'")); if (!value.isNull()) { if (value.instanceof(value_object::vtByte)) { // workaround for bad 4.1.x bugfix - c/j legacy comment return value.toString(); //new String((byte[]) value); } } return value.toString(); } /** * Returns the named MySQL variable from the currently connected server. * * @param variableName * the name of the variable to return * * @return the value of the given variable, or NULL if it doesn't exist * * @throws SQLException & * if an error occurs */ /* throws SQLException & */ String BaseTestFixture::getMysqlVariable(const String & variableName) { return getMysqlVariable(this->conn, variableName); } /** * Returns the properties that represent the default URL used for * connections for all testcases. * * @return properties parsed from sql::mysql::testsuite.url * * @throws SQLException & * if parsing fails */ /* throws SQLException & */ /* we currently don't use neither urls, nor properties - commented out*/ /*template Properties BaseTestFixture::getPropertiesFromTestsuiteUrl() { Properties props = new NonRegisteringDriver().parseURL(dbUrl, NULL); String hostname = props[ NonRegisteringDriver.HOST_PROPERTY_KEY ]; if ( hostname.size() == 0 ) { props.insert(Properties::value_type(NonRegisteringDriver.HOST_PROPERTY_KEY, _T("localhost") )); } else if ( hostname.substr(0,1) == _T(":") ) { props.insert(Properties::value_type(NonRegisteringDriver.HOST_PROPERTY_KEY, _T( "localhost" ) ) ); props.insert( Properties::value_type( NonRegisteringDriver.PORT_PROPERTY_KEY, hostname .substr(1) ) ); } String portNumber = props[ NonRegisteringDriver.PORT_PROPERTY_KEY ]; if (portNumber.size() == 0 ) { props.insert( Properties::value_type( NonRegisteringDriver.PORT_PROPERTY_KEY, _T("3306") ) ); } return props; }*/ /* throws SQLException & */ int BaseTestFixture::getRowCount(const String & tableName) { ResultSet countRs; try { countRs.reset(this->stmt->executeQuery("SELECT COUNT(*) FROM " + tableName)); countRs->next(); return countRs->getInt(1); } catch (...) { } return -1; } /* throws SQLException & */ value_object BaseTestFixture::getSingleIndexedValueWithQuery(Connection & c, int columnIndex, const String & query) { ResultSet valueRs; Statement svStmt; try { svStmt.reset(c->createStatement()); valueRs.reset(svStmt->executeQuery(query)); if (!valueRs->next()) { return value_object(); } return value_object(valueRs.get(), columnIndex); } catch (...) { } return value_object(); } /* throws SQLException & */ value_object BaseTestFixture::getSingleIndexedValueWithQuery(int columnIndex, const String & query) { return getSingleIndexedValueWithQuery(this->conn, columnIndex, query); } /* throws SQLException & */ value_object BaseTestFixture::getSingleValue(const String & tableName, const String & columnName, const String & whereClause) { return getSingleValueWithQuery(String("SELECT ") + columnName + " FROM " + tableName + ((whereClause.size() > 0) ? "" : " " + whereClause)); } /* throws SQLException & */ value_object BaseTestFixture::getSingleValueWithQuery(const String & query) { return getSingleIndexedValueWithQuery(1, query); } bool BaseTestFixture::isAdminConnectionConfigured() { return false/*System.getProperty(ADMIN_CONNECTION_PROPERTY_NAME) != NULL*/; } /* throws SQLException & */ bool BaseTestFixture::isServerRunningOnWindows() { return (getMysqlVariable("datadir").find_first_of('\\') != String::npos); } void BaseTestFixture::logDebug(const String & message) { // TODO: add possibility to turn on debug messages in command line if (false) logMsg(message); } /** In conn/j tests newTempBinaryFile used to be in prepared statement's setBinaryStream. It's not supported by conn/c++ (so far), so - commented out */ /* File BaseTestFixture::newTempBinaryFile(String name, long size) { File tempFile = File.createTempFile(name, "tmp"); tempFile.deleteOnExit(); cleanupTempFiles(tempFile, name); FileOutputStream fos = new FileOutputStream(tempFile); BufferedOutputStream bos = new BufferedOutputStream(fos); for (long i = 0; i < size; i++) { bos.write((byte) i); } bos.close(); ASSERT(tempFile.exists()); ASSERT_EQUALS(size, tempFile.length()); return tempFile; }*/ bool BaseTestFixture::runLongTests() { return runTestIfSysPropDefined("sql::mysql::testsuite.runLongTests"); } /** * Checks whether a certain system property is defined, in order to * run/not-run certain tests * * @param propName * the property name to check for * * @return true if the property is defined. */ bool BaseTestFixture::runTestIfSysPropDefined(const String & propName) { //String prop = System.getProperty(propName); return true; //(prop != NULL) && (prop.length() > 0); } bool BaseTestFixture::runMultiHostTests() { return true; //!runTestIfSysPropDefined(NO_MULTI_HOST_PROPERTY_NAME); } void BaseTestFixture::selectDb( Statement & st ) { st->execute( String("USE ") + (db.length() > 0 ? db : defaultDb)); } /** * Creates resources used by all tests. * * @throws Exception * if an error occurs. */ /* throws Exception */ void BaseTestFixture::setUp() { this->createdObjects.clear(); try { this->conn.reset( getConnection() ); } catch (sql::SQLException & sqle) { logErr(String("Couldn't get connection") + sqle.what()); throw sqle; } this->stmt.reset(this->conn->createStatement()); try { //doesn't currently make sense in c/c++ /*if (host.find("mysql") != String::npos) { this->rs.reset(this->stmt->executeQuery("SELECT VERSION()")); this->rs->next(); logDebug("Connected to " + this->rs->getString(1)); //this->rs->close(); this->rs.reset(); } else {*/ String tmp( "Connected to " ); DatabaseMetaData meta(this->conn->getMetaData()); tmp.append( meta->getDatabaseProductName() ); tmp.append( " / " ); tmp.append( meta->getDatabaseProductVersion() ); logDebug( tmp ); } catch (sql::SQLException & sqle) { logErr(sqle.what()); } if (this->rs.get() != NULL) this->rs->close(); DatabaseMetaData dbmd(conn->getMetaData()); hasSps=dbmd->supportsStoredProcedures(); selectDb( stmt ); } sql::Connection * BaseTestFixture::getConnection() { //Properties props = new Properties(); //props.setProperty("jdbcCompliantTruncation", "false"); //props.setProperty("runningCTS13", "true"); if (driver == NULL) { driver= sql::mysql::get_driver_instance(); logMsg(String(_T("Done: loaded ")) + driver->getName()); } if (host.length() == 0) { host=defaultHost; if (login.length() == 0) { login=defaultLogin; passwd=defaultPasswd; } } return driver->connect(host, /*port,*/ login, passwd); } /** * Destroys resources created during the test case. * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void BaseTestFixture::tearDown() { rs.reset(); for (int i=0; i < static_cast (this->createdObjects.size() - 1); i+=2) { try { dropSchemaObject(this->createdObjects[ i ], this->createdObjects[ i + 1 ]); } catch (sql::SQLException &) { } } stmt.reset(); pstmt.reset(); conn.reset(); } /** * Checks whether the database we're connected to meets the given version * minimum * * @param major * the major version to meet * @param minor * the minor version to meet * * @return bool if the major/minor is met * * @throws SQLException & * if an error occurs. */ /* throws SQLException & */ bool BaseTestFixture::versionMeetsMinimum(unsigned int major, unsigned int minor, unsigned int subminor) { return ( conn->getMetaData()->getDatabaseMajorVersion() >= major && conn->getMetaData()->getDatabaseMinorVersion() >= minor && conn->getMetaData()->getDatabasePatchVersion() >= subminor ); /*(dynamic_cast (this->conn))->versionMeetsMinimum( major, minor, subminor);*/ } /*template bool BaseTestFixture::isClassAvailable(String classname) { try { Class.forName(classname); return true; } catch (ClassNotFoundException e) { return false; } }*/ /** (almost) Same reasons as for createTempFile - for commenting out */ /* void BaseTestFixture::cleanupTempFiles(const File exampleTempFile, const String tempfilePrefix) { File tempfilePath = exampleTempFile.getParentFile(); File[] possibleFiles = tempfilePath.listFiles(new FilenameFilter() { public bool accept(File dir, String name) { return (name.find_first_of(tempfilePrefix) != -1 && !exampleTempFile.getName().equals(name)); }}); for (int i = 0; i < possibleFiles.length; i++) { try { possibleFiles[i].delete(); } catch (Throwable t) { // ignore, we're only making a best effort cleanup attempt here } } }*/ /* throws Exception */ void BaseTestFixture::assertResultSetsEqual(ResultSet & control, ResultSet & test) { int controlNumCols=control->getMetaData()->getColumnCount(); int testNumCols=test->getMetaData()->getColumnCount(); ASSERT_EQUALS(controlNumCols, testNumCols); while (control->next()) { test->next(); for (int i=0; i < controlNumCols; i++) { Object controlObj(getObject(control.get(), i + 1)); Object testObj(getObject(test.get(), i + 1)); if (controlObj.get() == NULL) { ASSERT(testObj.get() == NULL); } else { ASSERT(testObj.get() != NULL); } /** don't really have getFloat ** if (controlObj->instanceof( value_object::vtFloat )) { ASSERT_EQUALS_EPSILON(((float)controlObj).floatValue(), ((float)testObj).floatValue(), 0.1); } else*/ if (controlObj->instanceof(value_object::vtDouble)) { ASSERT_EQUALS_EPSILON(controlObj->doubleValue(), testObj->doubleValue(), 0.1); } else { ASSERT_EQUALS(controlObj->toString(), testObj->toString()); } } } ASSERT(!test->next()); } void BaseTestFixture::initTable(const String & sTableName , Properties & _sqlProps , Connection & _conn) { String execString; String sKeyName; String binarySize; String varbinarySize; String createString; String createString1; String createString2; Statement statement; try { clearTable(sTableName, _conn); logMsg("deleted rows from table " + sTableName); } catch (sql::SQLException & e) { logMsg("Exception encountered deleting rows from table: " + sTableName + ": " + e.what()); } try { statement.reset(_conn->createStatement()); if ( ( sTableName.find( "Binary_Tab" ) == 0 ) ) { binarySize=_sqlProps[ "binarySize" ]; logMsg("Binary Table Size : " + binarySize); String insertString=_sqlProps[ "Binary_Tab_Insert" ]; logMsg("Insert String " + insertString); logMsg("Adding rows to the table"); statement->executeUpdate(insertString); logMsg("Successfully inserted the row"); } else if ( ( sTableName.find( "Varbinary_Tab" ) == 0 ) ) { varbinarySize=_sqlProps[ ("varbinarySize") ]; TestsListener::messagesLog() << "Varbinary Table Size : " << varbinarySize << std::endl; String insertString=_sqlProps[ "Varbinary_Tab_Insert" ]; logMsg("Insert String " + insertString); logMsg("Adding rows to the table"); statement->executeUpdate(insertString); logMsg("Successfully inserted the row"); } else { logMsg("Adding rows to the table" + sTableName); sKeyName=sTableName; sKeyName.append("_Insert"); logMsg("sKeyName :" + sKeyName); execString=_sqlProps[ sKeyName ]; statement->executeUpdate(execString); logMsg("Rows added to the table " + sTableName); } } catch (sql::SQLException & e) { logErr("sql::DbcException creating the Table" + sTableName); logErr(e.what()); throw e; } catch (std::exception &) { logErr("Setup Failed!"); exit(1); } } void BaseTestFixture::clearTable(const String & sTableName , Connection & _conn) { logMsg("dropTab"); String sTag=sTableName; sTag.append("_Delete"); String removeString=sqlProps[ sTag ]; logMsg("Executable String " + removeString); Statement _stmt(_conn->createStatement()); _stmt->executeUpdate(removeString); _stmt->close(); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/BaseTestFixture.h000644 015771 000012 00000024761 12645244436 025232 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _BASE_TEST_FIXTURE_ #define _BASE_TEST_FIXTURE_ #include #include #include "resources.h" #include #include "../framework/framework.h" #include "../common/ccppTypes.h" #include "../common/stringutils.h" #define MESSAGE(msg) TestsListener::messagesLog() << msg << std::endl; /** * Base class for all test cases. Creates connections, statements, etc. and * closes them. * * @author Mark Matthews * @version $Id: BaseTestCase.java 5440 2006-06-27 17:00:53 +0000 (Tue, 27 Jun * 2006) mmatthews $ */ namespace testsuite { typedef boost::scoped_ptr Connection; typedef boost::scoped_ptr PreparedStatement; typedef boost::scoped_ptr Statement; typedef boost::scoped_ptr ResultSet; typedef sql::Driver Driver; typedef sql::ResultSetMetaData * ResultSetMetaData; typedef sql::DatabaseMetaData * DatabaseMetaData; class value_object { private: String asString; bool wasNull; public: enum value_type { vtDouble=0, vtFloat, vtByte, vtLast }; value_object(); value_object(const sql::ResultSet *, int colNum); bool isNull() const; String toString() const { return asString; } int intValue() const; float floatValue() const; long long longValue() const; /** Based on correspondent methods implementation in the mysql_resultset class */ double doubleValue() const { return floatValue(); } bool booleanValue() const { return intValue() != 0; } //Little hack bool instanceof(value_type type); }; typedef boost::scoped_ptr Object; value_object * getObject(sql::ResultSet * rs, int colNum); // TODO: Move everything from TestFixtureCommon to BaseTestFixture struct TestFixtureCommon { TestFixtureCommon(); String extractVal(const String & sTableName , int count , Properties & sqlProps , Connection & conn); static void logMsg(String message); void logErr(String message); static String randomString(); protected: void init(); static const String NO_MULTI_HOST_PROPERTY_NAME; String host; String port; String login; String passwd; String db; static int instanceCount; static int propsLoaded; static Properties sqlProps; static Driver *driver; }; /************************************************************************/ /* */ /************************************************************************/ class BaseTestFixture : public TestSuite, public TestFixtureCommon { typedef TestSuite super; List createdObjects; /** My instance number */ int myInstanceNumber; protected: /** Connection to server, initialized in setUp() Cleaned up in tearDown(). */ Connection conn; /** The driver to use */ String dbClass; /** * PreparedStatement to be used in tests, not initialized. Cleaned up in * tearDown(). */ PreparedStatement pstmt; /** * Statement to be used in tests, initialized in setUp(). Cleaned up in * tearDown(). */ Statement stmt; /** * ResultSet to be used in tests, not initialized. Cleaned up in tearDown(). */ ResultSet rs; bool hasSps; enum standard_tables { TABLE_CTSTABLE1 = 0, TABLE_CTSTABLE2, TABLE_INTEGERTAB, TABLE_BITTAB, TABLE_DOUBLETAB, TABLE_BIGINTTAB, TABLE_CHARTAB, TABLE_VARCHARTAB, TABLE_FLOATTAB, TABLE_SMALLINTTAB, TABLE_LONGVARCHARNULLTAB }; /** * Standard SQL tables shared by many tests */ void createStandardTable(standard_tables table); /* throws SQLException */ void createSchemaObject(String objectType, String objectName, String columnsAndOtherStuff); /* throws SQLException */ void createFunction(String functionName, String functionDefn); /* throws SQLException */ void dropFunction(String functionName); /* throws SQLException */ void createProcedure(String procedureName, String procedureDefn); /* throws SQLException */ void dropProcedure(String procedureName); /* throws SQLException */ void createTable(String tableName, String columnsAndOtherStuff); /* throws SQLException */ void dropTable(String tableName); /* throws SQLException */ void dropSchemaObject(String objectType, String objectName); sql::Connection * getConnection(); /* throws SQLException */ sql::Connection * getAdminConnection(); /* throws SQLException */ sql::Connection * getAdminConnectionWithProps(Properties props); /* throws SQLException */ sql::Connection * getConnectionWithProps(const String & propsList); /* throws SQLException */ sql::Connection * getConnectionWithProps(const String & url, const String & propsList); /** * Returns a new connection with the given properties * * @param props * the properties to use (the URL will come from the standard for * this testcase). * * @return a new connection using the given properties. * * @throws SQLException * DOCUMENT ME! */ /* throws SQLException */ sql::Connection * getConnectionWithProps(const Properties & props); /* throws SQLException */ sql::Connection * getConnectionWithProps(const String & url, const Properties & props); /** * Returns the per-instance counter (for messages when multi-threading * stress tests) * * @return int the instance number */ int getInstanceNumber(); /* throws SQLException */ String getMysqlVariable(Connection & c, const String & variableName); /** * Returns the named MySQL variable from the currently connected server. * * @param variableName * the name of the variable to return * * @return the value of the given variable, or NULL if it doesn't exist * * @throws SQLException * if an error occurs */ /* throws SQLException */ String getMysqlVariable(const String & variableName); /** * Returns the properties that represent the default URL used for * connections for all testcases. * * @return properties parsed from com.mysql.jdbc.testsuite.url * * @throws SQLException * if parsing fails */ /* throws SQLException */ /*Properties getPropertiesFromTestsuiteUrl() ;*/ /* throws SQLException */ int getRowCount(const String & tableName); /* throws SQLException */ value_object getSingleIndexedValueWithQuery(Connection & c, int columnIndex, const String & query); /* throws SQLException */ value_object getSingleIndexedValueWithQuery(int columnIndex, const String & query); /* throws SQLException */ value_object getSingleValue(const String & tableName, const String & columnName, const String & whereClause); /* throws SQLException */ value_object getSingleValueWithQuery(const String & query); bool isAdminConnectionConfigured(); /* throws SQLException */ bool isServerRunningOnWindows(); /* throws IOException */ /*File newTempBinaryFile(String name, long size) ;*/ bool runLongTests(); /** * Checks whether a certain system property is defined, in order to * run/not-run certain tests * * @param propName * the property name to check for * * @return true if the property is defined. */ bool runTestIfSysPropDefined(const String & propName); bool runMultiHostTests(); /** * Checks whether the database we're connected to meets the given version * minimum * * @param major * the major version to meet * @param minor * the minor version to meet * * @return boolean if the major/minor is met * * @throws SQLException * if an error occurs. */ /* throws SQLException */ bool versionMeetsMinimum(unsigned int major , unsigned int minor , unsigned int subminor= 0 ); /*bool isClassAvailable (String classname);*/ /* See comments in cpp file*/ /*void cleanupTempFiles(const File exampleTempFile, const String tempfilePrefix) ;*/ /* throws Exception */ void assertResultSetsEqual(ResultSet & control, ResultSet & test); void initTable(const String & sTableName, Properties & sqlProps , Connection & conn); void clearTable(const String & sTableName, Connection & conn); public: /** * Creates a new BaseTestCase object. * * @param name * The name of the JUnit test case */ BaseTestFixture (const String & name); void logDebug (const String & message); void selectDb ( Statement & st ); /** * Creates resources used by all tests. * * @throws Exception * if an error occurs. */ /* throws Exception */ virtual void setUp(); /** * Destroys resources created during the test case. * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ virtual void tearDown(); }; } /* Macros to use instead of one of junit assertEquals calls */ #define MyAssertEquals(str, a, b) ASSERT_MESSAGE(a==b, str) // Redefining TEST_FIXTURE #ifdef TEST_FIXTURE #undef TEST_FIXTURE #endif #define TEST_FIXTURE( theFixtureClass ) typedef theFixtureClass TestSuiteClass;\ theFixtureClass( const String & name ) \ : BaseTestFixture( name ) #endif // _BASE_TEST_FIXTURE_ mysql-connector-c++-1.1.7/test/CJUnitTestsPort/CMakeLists.txt000644 015771 000012 00000006077 12645244436 024540 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # IF(WIN32) LINK_DIRECTORIES(../framework/$(ConfigurationName)) SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn test_framework) # ADD_DEFINITIONS("-D_SECURE_SCL") ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") ELSEIF(NOT WIN32) SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn test_framework) ENDIF(WIN32) IF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(MY_GCOV_LINK_LIBRARIES gcov) ENDIF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) ADD_DEFINITIONS("-DWE_HAVE_DATATYPE_AGAIN") IF(MYSQLCPPCONN_TEST_NOT_IMPLEMENTED) ADD_DEFINITIONS("-DINCLUDE_NOT_IMPLEMENTED_METHODS=1") ENDIF(MYSQLCPPCONN_TEST_NOT_IMPLEMENTED) SET(jdbctests_sources ccpptests.cpp BaseTestFixture.cpp ../common/stringutils.cpp resources.cpp regression/EscapeProcessorRegressionTest.cpp compliance/ConnectionTest.cpp compliance/DatabaseMetaDataTest.cpp compliance/StatementTest.cpp compliance/ResultSetMetadataTest.cpp compliance/PreparedStatementTest.cpp simple/BlobTest.cpp regression/BlobRegressionTest.cpp regression/PreparedStatementRegressionTest.cpp simple/TransactionTest.cpp regression/SubqueriesRegressionTest.cpp compliance/UnbufferedRsStmtTest.cpp ) # It's convinient for VS users to have headers as part of project IF(WIN32) SET(jdbctests_sources ${jdbctests_sources} BaseTestFixture.h ../common/stringutils.h resources.h regression/EscapeProcessorRegressionTest.h compliance/ConnectionTest.h compliance/DatabaseMetaDataTest.h compliance/StatementTest.h compliance/ResultSetMetadataTest.h compliance/PreparedStatementTest.h simple/BlobTest.h regression/BlobRegressionTest.h regression/PreparedStatementRegressionTest.h simple/TransactionTest.h regression/SubqueriesRegressionTest.h compliance/UnbufferedRsStmtTest.h ) ENDIF(WIN32) ADD_EXECUTABLE(CJUnitTestsPort ${jdbctests_sources}) TARGET_LINK_LIBRARIES(CJUnitTestsPort ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring C/J junit tests port") mysql-connector-c++-1.1.7/test/CJUnitTestsPort/README000644 015771 000012 00000004470 12645244436 022653 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ This directory contains JDBC compliance tests and other tests ported from our JDBC test suite. All tests are build as part of a reqular build of the driver. The tests are compiled into one single binary "CJUnitTestsPort" located in the directory of this README file. Before running the tests you need to load a SQL dump into your test database. The dump is located in the directory of this README file: # mysql < cts.sql Now you can invoke the test binary: # CJUnitTestsPort The test will try to connect to the MySQL server on the host "127.0.0.1" on port 3306 using TCP/IP and try to select the database "test" using the database user "root" and the password "root" You can pass other connection parameters to the test binary just like you can with the examples from the examples/ directory. The syntax is like: # CJUnitTestsPort tcp://[:] [username] [password] [database] For example, to connect to 192.168.2.22 on port 3307, try: # CJUnitTestsPort tcp://192.168.2.22:3307 user password database Other possible start options are: --verbose - to output contents of messages/errors log --timer - to automatically time all tests runs. --verbose is needed for custom timers. The 1.0.2alpha release should pass about 95% of the tests. mysql-connector-c++-1.1.7/test/CJUnitTestsPort/ccpptests.cpp000644 015771 000012 00000005554 12645244437 024514 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../framework/test_runner.h" #include "../framework/start_options.h" #include "../framework/test_tapOutputter.h" #include "../framework/test_filter.h" #include int main(int argc, char** argv) { const String::value_type * unnamedStartParams[]= { "dbUrl" , "dbUser" , "dbPasswd" , "dbSchema" , NULL }; Properties defaultStringValues; defaultStringValues.insert( Properties::value_type( "dbUrl" , "tcp://127.0.0.1:3306" ) ); defaultStringValues.insert( Properties::value_type( "dbUser" , "root" ) ); defaultStringValues.insert( Properties::value_type( "dbPasswd", "root" ) ); defaultStringValues.insert( Properties::value_type( "dbSchema", "test" ) ); defaultStringValues.insert( Properties::value_type( "filter" , "" ) ); std::map defaultBoolValues; testsuite::StartOptions options( unnamedStartParams, & defaultStringValues , & defaultBoolValues ); options.parseParams( argc, argv ); testsuite::FiltersSuperposition filter( options.getString( "filter" ) ); /* std::cerr << "BlobTest: " << (filter.Admits( "BlobTest" ) ? "Admitted" : "Filtered Out" ) << std::endl; return 0;*/ /*std::cerr << options.getString( "dbUrl" ) << std::endl; std::cerr << options.getString( "dbUser" ) << std::endl; std::cerr << options.getString( "dbPasswd" ) << std::endl; std::cerr << options.getString( "dbSchema" ) << std::endl; std::cerr << options.getBool( "verbose" ) << std::endl; std::cerr << options.getBool( "timer" ) << std::endl; std::cerr << options.getBool( "dont-use-is" ) << std::endl; return 0;*/ testsuite::TestsRunner & testsRunner=testsuite::TestsRunner::theInstance(); testsRunner.setStartOptions ( & options ); testsRunner.setTestsFilter ( filter ); return testsRunner.runTests() ? EXIT_SUCCESS : EXIT_FAILURE; } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/ConnectionTest.cpp000644 015771 000012 00000043460 12645244437 027553 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Ported JDBC compliance connection tests * Most of them don't really make sense in c++ */ #include "driver/mysql_statement.h" #include "driver/mysql_metadata.h" #include "ConnectionTest.h" namespace testsuite { namespace compliance { /* * @testName: testClose * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The Close method closes the connection object and the close() * method does not return any value. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a Connection object and call close() method * and call isClosed() method and it should return a true value * */ /* throws Exception */ void ConnectionTest::testClose() { bool closeFlag=false; Connection con /*= NULL*/; con.reset(getConnection()); logMsg("Calling Close() method "); con->close(); closeFlag=con->isClosed(); if (closeFlag) { logMsg("close method closes the Connection object "); } else { logErr("close method does not close the Connection object"); FAIL("Call to Close is Failed!"); } } /* * @testName: testCreateStatement01 * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The createStatement() method returns a Statement object that * will produce non-scrollable and non-updatable result set. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call createStatement() * method and call instanceof to check * It should return a Statement object */ /* throws Exception */ void ConnectionTest::testCreateStatement01() { Statement statemt /*= NULL*/; logMsg("Calling createStatement() method "); statemt.reset(conn->createStatement()); if (dynamic_cast (statemt.get()) != NULL) { logMsg("createStatement method creates a Statement object"); } else { logErr( "createStatement method does not create a Statement object"); FAIL("Call to createStatement is Failed!"); } statemt->close(); } /* * @testName: testGetCatalog * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition) * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The getCatalog() method returns a String object; the string * represents the connection object's catalog name and null if there * is none. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call getCatalog() method * It should return a String value The getCatalogs() method in * Databasemeta data object will return a Resultset object that contains * the catalog name in the column TABLE_CAT .The String returned by * Connection.getCatalog() method will be checked against these * column values. */ /** Changing it to used getSchema()/getSchemas, that have been just introduced. Reverting is possible. Probably should have tests both for getSchema and getCatalog */ /* throws Exception */ void ConnectionTest::testGetCatalog() { String catalogName; String url; String retValue; String extValue; bool flag=false; logMsg("Calling getSchema() method "); //retValue = conn->getCatalog(); retValue=conn->getSchema(); logMsg(String("Catalog Name ") + retValue); if (retValue.size() > 0) { rs.reset(dbmd->getSchemas()); while (rs->next()) { //extValue = rs->getString("TABLE_CAT"); extValue=rs->getString("TABLE_SCHEM"); logMsg(String("Catalog Name ") + extValue); if (retValue == extValue) { flag=true; break; } } if (flag) { logMsg(String("getCatalog returns the Catalog name") + retValue); } else { logErr("getCatalog does not return the catalog name"); FAIL("Call to getCatalog is Failed!"); } } else { logMsg("getCatalog returns a empty String Object"); } } /* * @testName: testGetMetaData * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition) * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The getMetaData method returns a DatabaseMetaData object. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call getMetaData() * method and call instanceof method to check * It should return a DatabaseMetaData object * */ /* throws Exception * As many others here - doesn't make much sense in c++. changed it * to cast to implementation class */ void ConnectionTest::testGetMetaData() { logMsg("Calling getMetaData() method "); DatabaseMetaData rsmd(conn->getMetaData()); if (rsmd != NULL) { logMsg("getMetaData returns the DatabaseMetaData object "); } else { logErr( "getMetaData does not return the DatabaseMetaData object"); FAIL("Call to getMetaData is Failed!"); } } /* * @testName: testGetTransactionIsolation * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The getTransactionIsolation method returns an int value and must * be equal to the value of TRANSACTION_NONE or * TRANSACTION_READ_COMMITTED or TRANSACTION_READ_UNCOMMITTED * or TRANSACTION_REPEATABLE_READ or TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call getTransactionIsolation() method * It should return a Integer value and must be equal to the value of * TRANSACTION_NONE or TRANSACTION_READ_COMMITTED or * TRANSACTION_READ_UNCOMMITTED or TRANSACTION_REPEATABLE_READ or * TRANSACTION_SERIALIZABLE which is default set by the driver * * */ /* throws Exception */ void ConnectionTest::testGetTransactionIsolation() { int transIsolateVal=0; logMsg("Calling getTransactionIsolation() method "); transIsolateVal=conn->getTransactionIsolation(); if (transIsolateVal == sql::TRANSACTION_NONE) { TestsListener::messagesLog() << "getTransactionIsolation method returns Transaction Isolation mode as " << transIsolateVal << std::endl; } else if (transIsolateVal == sql::TRANSACTION_READ_COMMITTED) { TestsListener::messagesLog() << "getTransactionIsolation method returns Transaction Isolation mode as " << transIsolateVal << std::endl; } else if (transIsolateVal == sql::TRANSACTION_READ_UNCOMMITTED) { TestsListener::messagesLog() << "getTransactionIsolation method returns Transaction Isolation mode as " << transIsolateVal << std::endl; } else if (transIsolateVal == sql::TRANSACTION_REPEATABLE_READ) { TestsListener::messagesLog() << "getTransactionIsolation method returns Transaction Isolation mode as " << transIsolateVal << std::endl;; } else if (transIsolateVal == sql::TRANSACTION_SERIALIZABLE) { TestsListener::messagesLog() << "getTransactionIsolation method returns Transaction Isolation mode as " << transIsolateVal << std::endl; } else { logErr("getTransactionIsolation method returns an invalid value"); FAIL("Call to getTransactionIsolation is Failed!"); } } /* * @testName: testIsClosed01 * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The isClosed method returns a boolean value; true if the * connection is closed or false if it is still open. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call isClosed() method * It should return a boolean value and the value should be * equal to false * */ /* throws Exception */ void ConnectionTest::testIsClosed01() { bool closeFlag=false; Connection con /*= NULL*/; con.reset(getConnection()); logMsg("Calling isClosed Method"); closeFlag=con->isClosed(); if (!closeFlag) { logMsg(String("isClosed method returns ") + (closeFlag ? "true" : "false")); } else { logErr("isClosed method returns an invalid value"); FAIL("Call to isClosed is Failed!"); } con->close(); } /* * @testName: testIsClosed02 * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The isClosed method returns a boolean value; true if the * connection is closed or false if it is still open. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call close() method * and call isClosed() method * It should return a boolean value and the value should be * equal to true * */ /* throws Exception */ void ConnectionTest::testIsClosed02() { bool closeFlag=false; Connection con /*= NULL*/; con.reset(getConnection()); con->close(); logMsg("Calling isClosed() method "); closeFlag=con->isClosed(); if (closeFlag) { logMsg(String("isClosed method returns ") + (closeFlag ? "true" : "false")); } else { logErr("isClosed method returns an invalid value"); FAIL("Call to isClosed is Failed!"); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testIsReadOnly * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The isReadOnly method returns a boolean value; true if the * connection is in read-only mode and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call setReadOnly(boolean b) * method and call isReadOnly() method * It should return a boolean value that is been set * */ /* throws Exception */ void ConnectionTest::testIsReadOnly() { bool errorFlag=true; logMsg("invoking the setReadOnly method"); conn->setReadOnly(false); logMsg("Calling isReadOnly() method "); if (conn->isReadOnly()) { errorFlag=true; } else { errorFlag=false; } if (!errorFlag) { logMsg("isReadOnly method is Successful"); } else { logErr("isReadOnly method returns an invalid value"); FAIL("Call to isReadOnly is Failed!"); } } #endif /* * @testName: testNativeSQL * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition) * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The nativeSQL(String sql) method returns a String object * representing the native form of a sql. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a Connection object and call nativeSQL(String sql) method * It should return a String value which represents native SQL * grammar implementation of the SQL statement if the driver supports * else it returns the actual SQL statement as a String.This is checked * by using instanceof method */ /* throws Exception */ void ConnectionTest::testNativeSQL() { String sSqlStmt; String nativeSql; sSqlStmt=sqlProps["Escape_Seq_Query"]; logMsg(String("SQL Statement with Escape Syntax") + sSqlStmt); logMsg("Calling nativeSQL method "); nativeSql=conn->nativeSQL(sSqlStmt); if (nativeSql.size() > 0) { logMsg(String("nativeSQL method returns : ") + nativeSql); } else { logErr( "nativeSQL method does not return the System native SQL grammar"); FAIL("Call to nativeSQL is Failed!"); } } /** * @see junit.framework.TestCase#setUp() */ /* throws Exception */ void ConnectionTest::setUp() { super::setUp(); dbmd= conn->getMetaData(); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/ConnectionTest.h000644 015771 000012 00000033405 12645244437 027216 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /* #include "cppconn/connection.h" #include "cppconn/metadata.h" #include "cppconn/resultset.h" #include "cppconn/exception.h" #include "cppconn/statement.h"*/ /** * @author mmatthew * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ namespace testsuite { namespace compliance { class ConnectionTest : public BaseTestFixture { private: typedef BaseTestFixture super; DatabaseMetaData dbmd; protected: /** * @see junit.framework.TestCase#setUp() */ /* throws std::runtime_error * */ void setUp(); public: /** * Constructor for ConnectionTest. * @param name */ TEST_FIXTURE(ConnectionTest) { TEST_CASE(testClose); TEST_CASE(testCreateStatement01); TEST_CASE(testGetCatalog); TEST_CASE(testGetMetaData); TEST_CASE(testGetTransactionIsolation); TEST_CASE(testIsClosed01); TEST_CASE(testIsClosed02); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS TEST_CASE(testIsReadOnly); #endif TEST_CASE(testNativeSQL); } /* * @testName: testClose * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The Close method closes the connection object and the close() * method does not return any value. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a Connection object and call close() method * and call isClosed() method and it should return a true value * */ /* throws std::runtime_error * */ void testClose(); /* * @testName: testCreateStatement01 * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The createStatement() method returns a Statement object that * will produce non-scrollable and non-updatable result set. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call createStatement() * method and call instanceof to check * It should return a Statement object */ /* throws std::runtime_error * */ void testCreateStatement01(); /* * @testName: testGetCatalog * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition) * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The getCatalog() method returns a String object; the string * represents the connection object's catalog name and null if there * is none. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call getCatalog() method * It should return a String value The getCatalogs() method in * Databasemeta data object will return a Resultset object that contains * the catalog name in the column TABLE_CAT .The String returned by * Connection.getCatalog() method will be checked against these * column values. */ /* throws std::runtime_error * */ void testGetCatalog(); /* * @testName: testGetMetaData * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition) * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The getMetaData method returns a DatabaseMetaData object. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call getMetaData() * method and call insctanceof method to check * It should return a DatabaseMetaData object * */ /* throws std::runtime_error * */ void testGetMetaData(); /* * @testName: testGetTransactionIsolation * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The getTransactionIsolation method returns an int value and must * be equal to the value of TRANSACTION_NONE or * TRANSACTION_READ_COMMITTED or TRANSACTION_READ_UNCOMMITTED * or TRANSACTION_REPEATABLE_READ or TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call getTransactionIsolation() method * It should return a Integer value and must be equal to the value of * TRANSACTION_NONE or TRANSACTION_READ_COMMITTED or * TRANSACTION_READ_UNCOMMITTED or TRANSACTION_REPEATABLE_READ or * TRANSACTION_SERIALIZABLE which is default set by the driver * * */ /* throws std::runtime_error * */ void testGetTransactionIsolation(); /* * @testName: testIsClosed01 * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The isClosed method returns a boolean value; true if the * connection is closed or false if it is still open. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call isClosed() method * It should return a boolean value and the value should be * equal to false * */ /* throws std::runtime_error * */ void testIsClosed01(); /* * @testName: testIsClosed02 * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2) * * The isClosed method returns a boolean value; true if the * connection is closed or false if it is still open. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call close() method * and call isClosed() method * It should return a boolean value and the value should be * equal to true * */ /* throws std::runtime_error * */ void testIsClosed02(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testIsReadOnly * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition). * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The isReadOnly method returns a boolean value; true if the * connection is in read-only mode and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a Connection object and call setReadOnly(boolean b) * method and call isReadOnly() method * It should return a boolean value that is been set * */ /* throws std::runtime_error * */ void testIsReadOnly(); #endif /* * @testName: testNativeSQL * * @assertion: A Connection object represents a Connection in a database. * A Connection session includes the SQL Statements that are * executed and the results that are returned over that connection. * (See section 11.1 of JDBC 2.0 API Reference & Tutorial second * edition) * * The JDBC drivers must provide accurate and complete * metadata through the Connection.getMetaData() method. (See * section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) * specification v1.2). * * The nativeSQL(String sql) method returns a String object * representing the native form of a sql. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a Connection object and call nativeSQL(String sql) method * It should return a String value which represents native SQL * grammar implementation of the SQL statement if the driver supports * else it returns the actual SQL statement as a String.This is checked * by using instanceof method */ /* throws std::runtime_error * */ void testNativeSQL(); }; REGISTER_FIXTURE(ConnectionTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/DatabaseMetaDataTest.cpp000644 015771 000012 00001535457 12645244437 030576 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "DatabaseMetaDataTest.h" namespace testsuite { namespace compliance { /* * @testName: testAllProceduresAreCallable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The allProceduresAreCallable method must return a boolean value; * true if the user has the security rights of calling all the * procedures returned by the method getProcedures and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the allProceduresAreCallable() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testAllProceduresAreCallable() { logMsg("Calling allProceduresAreCallable on DatabaseMetaData"); bool retValue=dbmd->allProceduresAreCallable(); if (retValue) { logMsg( "allProceduresAreCallable method called by the current user"); } else { logMsg( "allProceduresAreCallable method not called by the current user"); } } /* * @testName: testAllTablesAreSelectable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave * as specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The allTablesAreSelectable method must return a boolean value; * true if the user can use a SELECT statement with all the * tables returned by the method getTables and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the allTablesAreSelectable() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testAllTablesAreSelectable() { logMsg("Calling allTablesAreSelectable on DatabaseMetaData"); bool retValue=dbmd->allTablesAreSelectable(); if (retValue) { logMsg( "allTablesAreSelectable method SELECTed by the current user"); } else { logMsg( "allTablesAreSelectable method not SELECTed by the current user"); } } /* * @testName: testDataDefinitionCausesTransactionCommit * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The dataDefinitionCausesTransactionCommit() method must return * a boolean value; true if the data definition statement within a * transaction is forced the transaction to commit and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the dataDefinitionCausesTransactionCommit() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testDataDefinitionCausesTransactionCommit() { logMsg( "Calling DatabaseMetaData.dataDefinitionCausesTransactionCommit"); bool retValue=dbmd->dataDefinitionCausesTransactionCommit(); if (retValue) { logMsg( "Data definition statement forces the transaction to commit"); } else { logMsg( "Data definition statement does not forces the transaction to commit"); } } /* * @testName: testDataDefinitionIgnoredInTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The dataDefinitionIgnoredInTransactions() method must return a * boolean value; true if a data definition statement within a * transaction is ignored and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the dataDefinitionIgnoredInTransactions() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testDataDefinitionIgnoredInTransactions() { logMsg( "Calling DatabaseMetaData.dataDefinitionIgnoredInTransactions"); bool retValue=dbmd->dataDefinitionIgnoredInTransactions(); if (retValue) { logMsg("Data definition statement is ignored in a transaction"); } else { logMsg( "Data definition statement is not ignored in a transaction"); } } /* * @testName: testDeletesAreDetected1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The deletesAreDetected(int resType) method must return a * boolean value; true if changes are detected by the resultset type * and false otherwise. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the deletesAreDetected() method on that object with the * result set type as sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testDeletesAreDetected1() { logMsg( "Calling DatabaseMetaData.deletesAreDetected(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->deletesAreDetected(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Visible row delete can be detected for TYPE_FORWARD_ONLY"); } else { logMsg( "Visible row delete cannot be detected for TYPE_FORWARD_ONLY"); } } /* * @testName: testDeletesAreDetected2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The deletesAreDetected(int resType) method must return a * boolean value; true if changes are detected by the resultset type * and false otherwise. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the deletesAreDetected() method on that object with the * result set type as sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testDeletesAreDetected2() { logMsg( "Calling DatabaseMetaData.deletesAreDetected(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->deletesAreDetected(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Visible row delete can be detected for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Visible row delete cannot be detected for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testDeletesAreDetected3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The deletesAreDetected(int resType) method must return a * boolean value; true if changes are detected by the resultset type * and false otherwise. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the deletesAreDetected() method on that object with the * result set type as sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testDeletesAreDetected3() { logMsg( "Calling DatabaseMetaData.deletesAreDetected(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->deletesAreDetected(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Visible row delete can be detected for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Visible row delete cannot be detected for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testDoesMaxRowSizeIncludeBlobs * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The doesMaxRowSizeIncludeBlobs() method must return a boolean * value; true if maximum row size includes LONGVARCHAR and * LONGVARBINARY blobs and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the doesMaxRowSizeIncludeBlobs() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testDoesMaxRowSizeIncludeBlobs() { logMsg("Calling DatabaseMetaData.doesMaxRowSizeIncludeBlobs"); bool retValue=dbmd->doesMaxRowSizeIncludeBlobs(); if (retValue) { logMsg("MaxRowSize includes blobs"); } else { logMsg("MaxRowSize does not include blobs"); } } /* * @testName: testGetBestRowIdentifier1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier1() { logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowTemporary with NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::DatabaseMetaData::bestRowTemporary, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg( "getBestRowIdentifier with scope bestRowTemporary did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetBestRowIdentifier2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier2() { logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowTransaction with NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::DatabaseMetaData::bestRowTransaction, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg( "getBestRowIdentifier with scope bestRowTransaction did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetBestRowIdentifier3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier3() { logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowSession with NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::DatabaseMetaData::bestRowSession, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg( "getBestRowIdentifier with scope bestRowSession did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetBestRowIdentifier4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier4() { logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowTemporary without NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::ResultSet::TYPE_SCROLL_SENSITIVE, false)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg( "getBestRowIdentifier with scope bestRowTemporary did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetBestRowIdentifier5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier5() { logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowTransaction without NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::DatabaseMetaData::bestRowTransaction, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg( "getBestRowIdentifier with scope bestRowTransaction did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetBestRowIdentifier6 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object * */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier6() { logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowSession without NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::DatabaseMetaData::bestRowSession, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg( "getBestRowIdentifier with scope bestRowSession did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetBestRowIdentifier7 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetBestRowIdentifier7() { List sColumnNames; sColumnNames.push_back("SCOPE"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("DATA_TYPE"); sColumnNames.push_back("TYPE_NAME"); sColumnNames.push_back("COLUMN_SIZE"); sColumnNames.push_back("BUFFER_LENGTH"); sColumnNames.push_back("DECIMAL_DIGITS"); sColumnNames.push_back("PSEUDO_COLUMN"); bool test_status=true; logMsg( "Calling DatabaseMetaData.getBestRowIdentifier with scope bestRowSession without NULLable columns"); ResultSet oRet_ResultSet(dbmd->getBestRowIdentifier(sCatalogName, sSchemaName, sFtable, sql::DatabaseMetaData::bestRowSession, true)); test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getBestRowIdentifier7 Failed!"); } } /* * @testName: testGetCatalogSeparator * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCatalogSeparator() method must return a String value * representing the separator string. (See JDK 1.2.2 API * documentation) * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.getCatalogSeparator() on that object. * It should return a String and NULL if it is not supported. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetCatalogSeparator() { logMsg("Calling DatabaseMetaData.getCatalogSeparator"); String sRetValue=dbmd->getCatalogSeparator(); if (sRetValue.empty()) { logMsg("getCatalogSeparator is not supported"); } else { logMsg(String("getCatalogSeparator returns ") + sRetValue); } } /* * @testName: testGetCatalogTerm * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCatalogTerm() method must return a String object containing * the vendor term for "catalog". (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getCatalogTerm() method on that object. * It should return a String and NULL if it cannot be returned. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetCatalogTerm() { logMsg("Calling getCatalogTerm on DatabaseMetaData"); String sRetValue=dbmd->getCatalogTerm(); if (sRetValue.empty()) { logMsg( "getCatalogTerm method does not returns the vendor's preferred term for catalog "); } else { logMsg(String("getCatalogTerm method returns: ") + sRetValue); } } /* * @testName: testGetCatalogs * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCatalogs() method must return a ResultSet object with each * row representing a catalog name available in the database. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getCatalogs() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetCatalogs() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); bool test_status=true; logMsg("Calling DatabaseMetaData.getCatalogs"); ResultSet oRet_ResultSet(dbmd->getCatalogs()); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getCatalogs Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(1) + ","); if (sRetStr == "") { logMsg("getCatalogs did not return any catalog names"); } else { logMsg("The Catalog names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetColumnPrivileges * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * getColumnPrivileges(String ctlg,String sch,String tab,String colpat) * method must return a ResultSet object with each row is a * description of a column's privileges. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getColumnPrivileges() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetColumnPrivileges() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); sColumnNames.push_back("TABLE_SCHEM"); sColumnNames.push_back("TABLE_NAME"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("GRANTOR"); sColumnNames.push_back("GRANTEE"); sColumnNames.push_back("PRIVILEGE"); sColumnNames.push_back("IS_GRANTABLE"); bool test_status=true; logMsg("Calling DatabaseMetaData.getColumnPrivileges"); String tmp("%"); ResultSet oRet_ResultSet(dbmd->getColumnPrivileges(sCatalogName, sSchemaName, sFtable, tmp)); test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getColumnPrivileges Failed!"); } if (oRet_ResultSet->next()) { logMsg("getColumnPrivileges returned some column names"); } else { logMsg("getColumnPrivileges did not return any column names"); } } /* * @testName: testGetColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getColumns(String clg,String schp,String tnpat,String colNamepat) * method must return a ResultSet object with each row is a * description of a table column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getColumns() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetColumns() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); sColumnNames.push_back("TABLE_SCHEM"); sColumnNames.push_back("TABLE_NAME"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("DATA_TYPE"); sColumnNames.push_back("TYPE_NAME"); sColumnNames.push_back("COLUMN_SIZE"); sColumnNames.push_back("BUFFER_LENGTH"); sColumnNames.push_back("DECIMAL_DIGITS"); sColumnNames.push_back("NUM_PREC_RADIX"); sColumnNames.push_back("NULLABLE"); sColumnNames.push_back("REMARKS"); sColumnNames.push_back("COLUMN_DEF"); sColumnNames.push_back("SQL_DATA_TYPE"); sColumnNames.push_back("SQL_DATETIME_SUB"); sColumnNames.push_back("CHAR_OCTET_LENGTH"); sColumnNames.push_back("ORDINAL_POSITION"); sColumnNames.push_back("IS_NULLABLE"); bool test_status=true; logMsg("Calling DatabaseMetaData.getColumns"); String tmp("%"); ResultSet oRet_ResultSet(dbmd->getColumns(sCatalogName, sSchemaName, tmp, tmp)); test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getColumns Failed!"); } if (oRet_ResultSet->next()) { logMsg("getColumns returned some column names"); } else { logMsg("getColumns did not return any column names"); } } /* * @testName: testGetCrossReference * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCrossReference(Str prcalg,Str prsch,Str prtab,Str foclg,Str fosch,Str fotab) * method must return a ResultSet object with each row is a * description of a foreign key column in a foreign key table. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getCrossReference() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetCrossReference() { List sColumnNames; sColumnNames.push_back("PKTABLE_CAT"); sColumnNames.push_back("PKTABLE_SCHEM"); sColumnNames.push_back("PKTABLE_NAME"); sColumnNames.push_back("PKCOLUMN_NAME"); sColumnNames.push_back("FKTABLE_CAT"); sColumnNames.push_back("FKTABLE_SCHEM"); sColumnNames.push_back("FKTABLE_NAME"); sColumnNames.push_back("FKCOLUMN_NAME"); sColumnNames.push_back("KEY_SEQ"); sColumnNames.push_back("UPDATE_RULE"); sColumnNames.push_back("DELETE_RULE"); sColumnNames.push_back("FK_NAME"); sColumnNames.push_back("PK_NAME"); sColumnNames.push_back("DEFERRABILITY"); bool test_status=true; logMsg("Calling DatabaseMetaData.getCrossReference"); ResultSet oRet_ResultSet(dbmd->getCrossReference(sCatalogName, sSchemaName, sPtable, sCatalogName, sSchemaName, sFtable)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getCrossReference Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(8) + ","); if (sRetStr == "") { logMsg("getCrossReference did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetDatabaseProductName * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDatabaseProductName method must return a String object * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDatabaseProductName() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDatabaseProductName() { logMsg("Calling getDatabaseProductName on DatabaseMetaData"); String sRetValue=dbmd->getDatabaseProductName(); if (sRetValue.empty()) { logMsg( "getDatabaseProductName method does not returns database product name "); } else { logMsg(String("getDatabaseProductName method returns: ") + sRetValue); } } /* * @testName: testGetDatabaseProductVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDatabaseProductVersion method must return a String object * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDatabaseProductVersion() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDatabaseProductVersion() { logMsg("Calling getDatabaseProductVersion on DatabaseMetaData"); String sRetValue=dbmd->getDatabaseProductVersion(); if (sRetValue.empty()) { logMsg( "getDatabaseProductVersion method does not returns a database product version "); } else { logMsg("getDatabaseProductVersion method returns: " + sRetValue); } } /* * @testName: testGetDefaultTransactionIsolation * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getDefaultTransactionIsolation() method must return an integer * value; the value representing the default Transaction Isolation. * The value can be any one of the following TRANSACTION_NONE, * TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getDefaultTransactionIsolation() method. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDefaultTransactionIsolation() { logMsg("Calling DatabaseMetaData.getDefaultTransactionIsolation"); int nRetval=dbmd->getDefaultTransactionIsolation(); if ((nRetval != sql::TRANSACTION_NONE) && (nRetval != sql::TRANSACTION_READ_UNCOMMITTED) && (nRetval != sql::TRANSACTION_READ_COMMITTED) && (nRetval != sql::TRANSACTION_REPEATABLE_READ) && (nRetval != sql::TRANSACTION_SERIALIZABLE)) { logErr( "getDefaultTransactionIsolation returns an invalid value" + nRetval); FAIL("Call to getDefaultTransactionIsolation is Failed!"); } else { logMsg( "getDefaultTransactionIsolation returns a valid Isolation level" + nRetval); } } /* * @testName: testGetDriverMajorVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverMajorVersion method must return a integer value * representing the driver major version. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverMajorVersion() method * It should return a Integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDriverMajorVersion() { logMsg("Calling getDriverMajorVersion on DatabaseMetaData"); int drMajorVersion=dbmd->getDriverMajorVersion(); if (drMajorVersion >= 0) { logMsg("getDriverMajorVersion method returns: " + drMajorVersion); } else { logMsg(" getDriverMajorVersion method returns a negative value"); } } /* * @testName: testGetDriverMinorVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverMinorVersion method must return a integer value * representing the driver major version. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverMinorVersion() method * It should return a Integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDriverMinorVersion() { logMsg("Calling getDriverMinorVersion on DatabaseMetaData"); int drMinorVersion=dbmd->getDriverMinorVersion(); if (drMinorVersion >= 0) { logMsg(" getDriverMinorVersion method returns: " + drMinorVersion); } else { logMsg( " getDriverMinorVersion method returns a negative value: " + drMinorVersion); } } /* * @testName: testGetDriverName * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverName method must return a String object * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverName() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDriverName() { logMsg("Calling getDriverName on DatabaseMetaData"); String sRetValue=dbmd->getDriverName(); if (sRetValue.empty()) { logMsg( "getDriverName method does not returns a Driver Name "); } else { logMsg(String("getDriverName method returns: ") + sRetValue); } } /* * @testName: testGetDriverVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverVersion method must return a String object * representing the driver version including its major and minor * version numbers. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverVersion() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetDriverVersion() { logMsg("Calling getDriverVersion on DatabaseMetaData"); String sRetValue=dbmd->getDriverVersion(); if (sRetValue.empty()) { logMsg( "getDriverVersion method does not returns a Driver Version "); } else { logMsg(String("getDriverVersion returns: ") + sRetValue); } } /* * @testName: testGetExportedKeys * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getExportedKeys(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of a foreign key that reference a table's primary * key columns. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getExportedKeys() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetExportedKeys() { List sColumnNames; sColumnNames.push_back("PKTABLE_CAT"); sColumnNames.push_back("PKTABLE_SCHEM"); sColumnNames.push_back("PKTABLE_NAME"); sColumnNames.push_back("PKCOLUMN_NAME"); sColumnNames.push_back("FKTABLE_CAT"); sColumnNames.push_back("FKTABLE_SCHEM"); sColumnNames.push_back("FKTABLE_NAME"); sColumnNames.push_back("FKCOLUMN_NAME"); sColumnNames.push_back("KEY_SEQ"); sColumnNames.push_back("UPDATE_RULE"); sColumnNames.push_back("DELETE_RULE"); sColumnNames.push_back("FK_NAME"); sColumnNames.push_back("PK_NAME"); sColumnNames.push_back("DEFERRABILITY"); bool test_status=true; logMsg("Calling DatabaseMetaData.getExportedKeys"); ResultSet oRet_ResultSet(dbmd->getExportedKeys(sCatalogName, sSchemaName, sPtable)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getExportedKeys Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(8) + ","); if (sRetStr == "") { logMsg("getExportedKeys did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetExtraNameCharacters * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getExtraNameCharacters() method must return a String object * containing the extra characters; (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getExtraNameCharacters() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetExtraNameCharacters() { logMsg("Calling getExtraNameCharacters on DatabaseMetaData"); String sRetValue=dbmd->getExtraNameCharacters(); if (sRetValue.empty()) { logMsg( "getExtraNameCharacters method does not returns the string containing the extra characters "); } else { logMsg(String("getExtraNameCharacters method returns: ") + sRetValue); } } /* * @testName: testGetIdentifierQuoteString * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIdentifierQuoteString() method must return a String * object representing the quoting string or a space if the database * does not support quoting identifiers. A JDBC Compliant driver * always uses a double quote character ("). (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getIdentifierQuoteString() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetIdentifierQuoteString() { logMsg("Calling getIdentifierQuoteString on DatabaseMetaData"); String sRetValue=dbmd->getIdentifierQuoteString(); if (sRetValue == "") { logMsg("The database does not support quoting identifiers"); } else /*if (dynamic_cast( sRetValue ) != NULL)*/ { logMsg(String("getIdentifierQuoteString method returns ") + sRetValue); } /* else if (sRetValue == NULL) { logErr("getIdentifierQuoteString returns an Invalid value"); FAIL("Call to getIdentfierQuoteString is Failed!"); }*/ } /* * @testName: testGetImportedKeys * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getImportedKeys(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of a primary key columns that are referenced by a * table's foreign key columns. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getImportedKeys() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetImportedKeys() { List sColumnNames; sColumnNames.push_back("PKTABLE_CAT"); sColumnNames.push_back("PKTABLE_SCHEM"); sColumnNames.push_back("PKTABLE_NAME"); sColumnNames.push_back("PKCOLUMN_NAME"); sColumnNames.push_back("FKTABLE_CAT"); sColumnNames.push_back("FKTABLE_SCHEM"); sColumnNames.push_back("FKTABLE_NAME"); sColumnNames.push_back("FKCOLUMN_NAME"); sColumnNames.push_back("KEY_SEQ"); sColumnNames.push_back("UPDATE_RULE"); sColumnNames.push_back("DELETE_RULE"); sColumnNames.push_back("FK_NAME"); sColumnNames.push_back("PK_NAME"); sColumnNames.push_back("DEFERRABILITY"); bool test_status=true; logMsg("Calling DatabaseMetaData.getImportedKeys"); ResultSet oRet_ResultSet(dbmd->getImportedKeys(sCatalogName, sSchemaName, sFtable)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getImportedKeys Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(4) + ","); if (sRetStr == "") { logMsg("getImportedKeys did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetIndexInfo1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetIndexInfo1() { logMsg( "Calling DatabaseMetaData.getIndexInfo with approximate data and without accurate results"); ResultSet oRet_ResultSet(dbmd->getIndexInfo(sCatalogName, sSchemaName, sFtable, true, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(6) + ","); if (sRetStr == "") { logMsg("getIndexInfo did not return any index names"); } else { logMsg("The index names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetIndexInfo2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetIndexInfo2() { logMsg( "Calling DatabaseMetaData.getIndexInfo with approximate data and with accurate results"); ResultSet oRet_ResultSet(dbmd->getIndexInfo(sCatalogName, sSchemaName, sFtable, true, false)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(6) + ","); if (sRetStr == "") { logMsg("getIndexInfo did not return any index names"); } else { logMsg("The index names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetIndexInfo3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetIndexInfo3() { logMsg( "Calling DatabaseMetaData.getIndexInfo without approximate data and with accurate results"); ResultSet oRet_ResultSet(dbmd->getIndexInfo(sCatalogName, sSchemaName, sFtable, false, false)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(6) + ","); if (sRetStr == "") { logMsg("getIndexInfo did not return any index names"); } else { logMsg("The index names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetIndexInfo4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetIndexInfo4() { logMsg( "Calling DatabaseMetaData.getIndexInfo without approximate data and without accurate results"); ResultSet oRet_ResultSet(dbmd->getIndexInfo(sCatalogName, sSchemaName, sFtable, false, true)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(6) + ","); if (sRetStr == "") { logMsg("getIndexInfo did not return any index names"); } else { logMsg("The index names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetIndexInfo5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetIndexInfo5() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); sColumnNames.push_back("TABLE_SCHEM"); sColumnNames.push_back("TABLE_NAME"); sColumnNames.push_back("NON_UNIQUE"); sColumnNames.push_back("INDEX_QUALIFIER"); sColumnNames.push_back("INDEX_NAME"); sColumnNames.push_back("TYPE"); sColumnNames.push_back("ORDINAL_POSITION"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("ASC_OR_DESC"); sColumnNames.push_back("CARDINALITY"); sColumnNames.push_back("PAGES"); sColumnNames.push_back("FILTER_CONDITION"); bool test_status=true; logMsg( "Calling DatabaseMetaData.getIndexInfo without approximate data and without accurate results"); ResultSet oRet_ResultSet(dbmd->getIndexInfo(sCatalogName, sSchemaName, sFtable, false, true)); test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getCrossReference Failed!"); } } /* * @testName: testGetMaxBinaryLiteralLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxBinaryLiteralLength() method must return a integer * value; the value representing the maximum number of hex * characters; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxBinaryLiteralLength() method on that object. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxBinaryLiteralLength() { logMsg("Calling DatabaseMetaData.getMaxBinaryLiteralLength"); int nRetval=dbmd->getMaxBinaryLiteralLength(); if (nRetval < 0) { logErr("getMaxBinaryLiteralLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxBinaryLiteralLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxCatalogNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxCatalogNameLength() method must return an integer * value; the value representing the maximum catalog name length * that is allowed; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxCatalogNameLength() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxCatalogNameLength() { logMsg("Calling DatabaseMetaData.getMaxCatalogNameLength"); int nRetval=dbmd->getMaxCatalogNameLength(); if (nRetval < 0) { logErr("getMaxCatalogNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxCatalogNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxCharLiteralLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxCharLiteralLength() method must return a integer * value; the value representing the maximum number of * characters; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxCharLiteralLength() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxCharLiteralLength() { logMsg("Calling DatabaseMetaData.getMaxCharLiteralLength"); int nRetval=dbmd->getMaxCharLiteralLength(); if (nRetval < 0) { logErr("getMaxCharLiteralLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxCharLiteralLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxColumnNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnNameLength() method must return a integer * value; the value representing the maximum number of * characters allowed as column name length; 0 if there is no limit * or the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnNameLength() method on that object. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxColumnNameLength() { logMsg("Calling DatabaseMetaData.getMaxColumnNameLength"); int nRetval=dbmd->getMaxColumnNameLength(); if (nRetval < 0) { logErr("getMaxColumnNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxColumnNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxColumnsInGroupBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInGroupBy() method must return a integer * value; the value representing the maximum number of * columns in a GROUP BY clause; 0 if there is no limit or * the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInGroupBy() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxColumnsInGroupBy() { logMsg("Calling DatabaseMetaData.getMaxColumnsInGroupBy"); int nRetval=dbmd->getMaxColumnsInGroupBy(); if (nRetval < 0) { logErr("getMaxColumnsInGroupBy returns a negative value"); } else { TestsListener::messagesLog() << "getMaxColumnsInGroupBy returns " << nRetval << std::endl; } } /* * @testName: testGetMaxColumnsInIndex * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInIndex() method must return a integer * value; the value representing the maximum number of * columns in Index; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInIndex() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxColumnsInIndex() { logMsg("Calling DatabaseMetaData.getMaxColumnsInIndex"); int nRetval=dbmd->getMaxColumnsInIndex(); if (nRetval < 0) { logErr("getMaxColumnsInIndex returns a negative value"); } else { TestsListener::messagesLog() << "getMaxColumnsInIndex returns " << nRetval << std::endl; } } /* * @testName: testGetMaxColumnsInOrderBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInOrderBy() method must return a integer * value; the value representing the maximum number of columns * in a ORDER BY clause; 0 if there is no limit or the limit is * unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInOrderBy() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxColumnsInOrderBy() { logMsg("Calling DatabaseMetaData.getMaxColumnsInOrderBy"); int nRetval=dbmd->getMaxColumnsInOrderBy(); if (nRetval < 0) { logErr("getMaxColumnsInOrderBy returns a negative value"); } else { TestsListener::messagesLog() << "getMaxColumnsInOrderBy returns " << nRetval << std::endl; } } /* * @testName: testGetMaxColumnsInSelect * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInSelect() method must return a integer * value; the value representing the maximum number of columns in * a SELECT list; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInSelect() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxColumnsInSelect() { logMsg("Calling DatabaseMetaData.getMaxColumnsInSelect"); int nRetval=dbmd->getMaxColumnsInSelect(); if (nRetval < 0) { logErr("getMaxColumnsInSelect returns a negative value"); } else { TestsListener::messagesLog() << "getMaxColumnsInSelect returns " << nRetval << std::endl; } } /* * @testName: testGetMaxColumnsInTable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInTable() method must return a integer * value; the value representing the maximum number of columns * in a Table; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInTable() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxColumnsInTable() { logMsg("Calling DatabaseMetaData.getMaxColumnsInTable"); int nRetval=dbmd->getMaxColumnsInTable(); if (nRetval < 0) { logErr("getMaxColumnsInTable returns a negative value"); } else { TestsListener::messagesLog() << "getMaxColumnsInTable returns " << nRetval << std::endl; } } /* * @testName: testGetMaxConnections * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxConnections() method must return a integer * value; the value representing the maximum number of active * connections at a time in a database; 0 if there is no limit or * the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxConnections() method on that object. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxConnections() { logMsg("Calling DatabaseMetaData.getMaxConnections"); int nRetval=dbmd->getMaxConnections(); if (nRetval < 0) { logErr("getMaxConnections returns a negative value"); } else { TestsListener::messagesLog() << "getMaxConnections returns " << nRetval << std::endl; } } /* * @testName: testGetMaxCursorNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxCursorNameLength() method must return a integer * value; the value representing the maximum cursor name length * in bytes; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxCursorNameLength() method on that object. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxCursorNameLength() { logMsg("Calling DatabaseMetaData.getMaxCursorNameLength"); int nRetval=dbmd->getMaxCursorNameLength(); if (nRetval < 0) { logErr("getMaxCursorNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxCursorNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxIndexLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxIndexLength() method must return a integer * value; the value representing the maximum index length in * bytes; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxIndexLength() method on that object. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxIndexLength() { logMsg("Calling DatabaseMetaData.getMaxIndexLength"); int nRetval=dbmd->getMaxIndexLength(); if (nRetval < 0) { logErr("getMaxIndexLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxIndexLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxProcedureNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxProcedureNameLength() method must return a integer * value; the value representing the maximum procedure name length * that is allowed; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxProcedureNameLength() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxProcedureNameLength() { logMsg("Calling DatabaseMetaData.getMaxProcedureNameLength"); int nRetval=dbmd->getMaxProcedureNameLength(); if (nRetval < 0) { logErr("getMaxProcedureNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxProcedureNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxRowSize * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxRowSize() method must return a integer * value; the value representing the maximum length of a single row * in bytes; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxRowSize() method on that object. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxRowSize() { logMsg("Calling DatabaseMetaData.getMaxRowSize"); int nRetval=dbmd->getMaxRowSize(); if (nRetval < 0) { logErr("getMaxRowSize returns a negative value"); } else { TestsListener::messagesLog() << "getMaxRowSize returns " << nRetval << std::endl; } } /* * @testName: testGetMaxSchemaNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxSchemaNameLength() method must return a integer * value; the value representing the maximum schema name length that * is allowed; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxSchemaNameLength() method on that object. * It should return an integer value. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxSchemaNameLength() { logMsg("Calling DatabaseMetaData.getMaxSchemaNameLength"); int nRetval=dbmd->getMaxSchemaNameLength(); if (nRetval < 0) { logErr("getMaxSchemaNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxSchemaNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxStatementLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxStatementLength() method must return an integer * value; the value representing the maximum number of characters * allowed in SQL statement; 0 if there is no limit or the limit is * unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxStatementLength() method. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxStatementLength() { logMsg("Calling DatabaseMetaData.getMaxStatementLength"); int nRetval=dbmd->getMaxStatementLength(); if (nRetval < 0) { logErr("getMaxStatementLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxStatementLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxStatements * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxStatements method must return an integer * value; the value representing the maximum number of statements * that can be open at one time to the database; 0 if there is no limit * or the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxStatements() method. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxStatements() { logMsg("Calling DatabaseMetaData.getMaxStatements"); int nRetval=dbmd->getMaxStatements(); if (nRetval < 0) { logErr("getMaxStatements returns a negative value"); } else { TestsListener::messagesLog() << "getMaxStatements returns " << nRetval << std::endl; } } /* * @testName: testGetMaxTableNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxTableNameLength() method must return an integer * value; the value representing the maximum number of characters * allowed in a table name; 0 if there is no limit or the limit * is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxTableNameLength() method. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxTableNameLength() { logMsg("Calling DatabaseMetaData.getMaxTableNameLength"); int nRetval=dbmd->getMaxTableNameLength(); if (nRetval < 0) { logErr("getMaxTableNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxTableNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetMaxTablesInSelect * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxTablesInSelect() method must return an integer * value; the value representing the maximum number of tables in * SELECT clause; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxTablesInSelect() method. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxTablesInSelect() { logMsg("Calling DatabaseMetaData.getMaxTablesInSelect"); int nRetval=dbmd->getMaxTablesInSelect(); if (nRetval < 0) { logErr("getMaxTablesInSelect returns a negative value"); } else { TestsListener::messagesLog() << "getMaxTablesInSelect returns " << nRetval << std::endl; } } /* * @testName: testGetMaxUserNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxUserNameLength() method must return an integer * value; the value representing the maximum of characters allowed * in a user name; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxUserNameLength() method. * It should return an integer value * */ /* throws Exception */ void DatabaseMetaDataTest::testGetMaxUserNameLength() { logMsg("Calling DatabaseMetaData.getMaxUserNameLength"); int nRetval=dbmd->getMaxUserNameLength(); if (nRetval < 0) { logErr("getMaxUserNameLength returns a negative value"); } else { TestsListener::messagesLog() << "getMaxUserNameLength returns " << nRetval << std::endl; } } /* * @testName: testGetNumericFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getNumericFunctions() method must return a String object * that is a comma separated list of math functions; These are * the X/Open CLI math function names used in the JDBC function * escape clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getNumericFunctions() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetNumericFunctions() { logMsg("Calling getNumericFunctions on DatabaseMetaData"); String sRetValue=dbmd->getNumericFunctions(); if (sRetValue.empty()) { logMsg( "getNumericFunctions method does not returns the comma-separated list of math functions "); } else { logMsg(String("getNumericFunctions method returns: ") + sRetValue); } } /* * @testName: testGetPrimaryKeys * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getPrimaryKeys(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of the given table's primary key column(s). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getPrimaryKeys() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetPrimaryKeys() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); sColumnNames.push_back("TABLE_SCHEM"); sColumnNames.push_back("TABLE_NAME"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("KEY_SEQ"); sColumnNames.push_back("PK_NAME"); bool test_status=true; logMsg("Calling DatabaseMetaData.getPrimaryKeys"); ResultSet oRet_ResultSet(dbmd->getPrimaryKeys(sCatalogName, sSchemaName, sFtable)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getPrimaryKeys Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(4) + ","); if (sRetStr == "") { logMsg("getPrimaryKeys did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetProcedureColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getProcedureColumns(Str ctlg,Str schp,String prp,String colpa) * method must return a ResultSet object with each row describes * the information like parameter for the stored procedure, * return value of the stored procedure, etc., * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getProcedureColumns() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetProcedureColumns() { if (hasSps) { List sColumnNames; sColumnNames.push_back("PROCEDURE_CAT"); sColumnNames.push_back("PROCEDURE_SCHEM"); sColumnNames.push_back("PROCEDURE_NAME"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("COLUMN_TYPE"); sColumnNames.push_back("DATA_TYPE"); sColumnNames.push_back("TYPE_NAME"); sColumnNames.push_back("PRECISION"); sColumnNames.push_back("LENGTH"); sColumnNames.push_back("SCALE"); sColumnNames.push_back("RADIX"); sColumnNames.push_back("NULLABLE"); sColumnNames.push_back("REMARKS"); bool test_status=true; logMsg("Calling DatabaseMetaData.getProcedureColumns"); String tmp("%"); ResultSet oRet_ResultSet(dbmd->getProcedureColumns(sCatalogName, sSchemaName, tmp, tmp)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg( "Columns return are not same either in order or name"); FAIL("Call to getProcedureColumns Failed!"); } if (oRet_ResultSet->next()) { logMsg("getProcedureColumns returned some column names"); } else { logMsg( "getProcedureColumns did not return any column names"); } } } #endif /* * @testName: testGetProcedureTerm * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getProcedureTerm() method must return a String object * containing the vendor term for "procedure". (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getProcedureTerm() method on that object. * It should return a String and NULL if it cannot be generated.; * */ /* throws Exception */ void DatabaseMetaDataTest::testGetProcedureTerm() { logMsg("Calling getProcedureTerm on DatabaseMetaData"); String sRetValue=dbmd->getProcedureTerm(); if (sRetValue.empty()) { logMsg( "getProcedureTerm method does not returns the vendor's preferred term for procedure "); } else { logMsg(String("getProcedureTerm method returns: ") + sRetValue); } } /* * @testName: testGetProcedures * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getProcedures(String catg, String schemapat, String procpat) * method must return a ResultSet object where catg is the catalog * name, schemapat is schema pattern and procpat is procedure name * pattern. Each row of the ResultSet is the description of the. * stored procedure. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getProcedures() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetProcedures() { if (!this->hasSps) { return; } List sColumnNames; sColumnNames.push_back("PROCEDURE_CAT"); sColumnNames.push_back("PROCEDURE_SCHEM"); sColumnNames.push_back("PROCEDURE_NAME"); sColumnNames.push_back("RESERVED1"); sColumnNames.push_back("RESERVED2"); sColumnNames.push_back("RESERVED3"); sColumnNames.push_back("REMARKS"); sColumnNames.push_back("PROCEDURE_TYPE"); bool statusColumnCount= true; bool statusColumnMatch= true; int iColumnNamesLength= static_cast(sColumnNames.size()); logMsg("Calling DatabaseMetaData.getProcedures"); String tmp("%"); ResultSet oRet_ResultSet(dbmd->getProcedures(sCatalogName, sSchemaName, tmp)); String sRetStr; sRetStr=""; ResultSetMetaData rsmd(oRet_ResultSet->getMetaData()); int iCount=rsmd->getColumnCount(); TestsListener::messagesLog() << "Minimum Column Count is:" << iColumnNamesLength << std::endl; if (iColumnNamesLength <= iCount) { iCount=iColumnNamesLength; statusColumnCount=true; } else { statusColumnCount=false; } logMsg("Comparing Column Names..."); while (iColumnNamesLength > 0) { if ((iCount < 4) || (iCount > 6)) { if (ciString(sColumnNames[iColumnNamesLength - 1].c_str()) == rsmd->getColumnName(iCount).c_str()) { statusColumnMatch=true; } else { statusColumnMatch=false; break; } } iCount--; iColumnNamesLength--; } if ((statusColumnCount == false) || (statusColumnMatch == false)) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getProcedures Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(3) + ","); if (sRetStr == "") { logMsg("getProcedures did not return any procedure names"); } else { logMsg("The Procedure names returned are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetSQLKeywords * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSQLKeywords() method must return a String object that is * comma separated list of keywords used by the database that are * not also SQL-92 keywords.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSQLKeywords() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetSQLKeywords() { logMsg("Calling getSQLKeywords on DatabaseMetaData"); String sRetValue=dbmd->getSQLKeywords(); if (sRetValue.empty()) { logMsg( "getSQLKeywords method does not returns the list of SQLKeywords "); } else { logMsg(String("getSQLKeywords method returns: ") + sRetValue); } } /* * @testName: testGetSchemaTerm * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSchemaTerm() method must return a String object representing * the vendor term for "schema". (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSchemaTerm() method on that object. * It should return a String and NULL if it cannot be generated. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetSchemaTerm() { logMsg("Calling getSchemaTerm on DatabaseMetaData"); String sRetValue=dbmd->getSchemaTerm(); if (sRetValue.empty()) { logMsg( "getSchemaTerm method does not returns the vendor's preferred term for schema "); } else { logMsg(String("getSchemaTerm method returns: ") + sRetValue); } } /* * @testName: testGetSchemas * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSchemas() method must return a ResultSet object, with each row * representing a schema name available in the database * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getSchemas() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetSchemas() { List sColumnNames; sColumnNames.push_back("TABLE_SCHEM"); bool test_status=true; logMsg("Calling DatabaseMetaData.getSchemas"); ResultSet oRet_ResultSet(dbmd->getSchemas()); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getSchemas Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(1) + ","); if (sRetStr == "") { logMsg("getSchemas did not return any schema names"); } else { logMsg("The Schema names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetSearchStringEscape * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSystemFunctions() method must return a String object * used to escape wildcard characters; (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSearchStringEscape() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetSearchStringEscape() { logMsg("Calling getSearchStringEscape on DatabaseMetaData"); String sRetValue=dbmd->getSearchStringEscape(); if (sRetValue.empty()) { logMsg( "getSearchStringEscape method does not returns the string used to escape wildcard characters "); } else { logMsg(String("getSearchStringEscape method returns: ") + sRetValue); } } /* * @testName: testGetStringFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getStringFunctions() method must return a String object * that is a comma separated list of string functions; These are * the X/Open CLI string function names used in the JDBC function * escape clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getStringFunctions() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetStringFunctions() { logMsg("Calling getStringFunctions on DatabaseMetaData"); String sRetValue=dbmd->getStringFunctions(); if (sRetValue.empty()) { logMsg( "getStringFunctions method does not returns the comma-separated list of string functions "); } else { logMsg(String("getStringFunctions method returns: ") + sRetValue); } } /* * @testName: testGetSystemFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSystemFunctions() method must return a String object * that is a comma separated list of string functions; These are * the X/Open CLI system function names used in the JDBC function * escape clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSystemFunctions() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetSystemFunctions() { logMsg("Calling getSystemFunctions on DatabaseMetaData"); String sRetValue=dbmd->getSystemFunctions(); if (sRetValue.empty()) { logMsg( "getSystemFunctions methd does not returns the comma-separated list of system functions "); } else { logMsg(String("getSystemFunctions method returns: ") + sRetValue); } } /* * @testName: testGetTablePrivileges * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * getTablePrivileges(String clg,String schpat,String tabnamepat) * method must return a ResultSet object with each row is a * description of the access rights for a table. (See JDK 1.2.2 * API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTablePrivileges() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetTablePrivileges() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); sColumnNames.push_back("TABLE_SCHEM"); sColumnNames.push_back("TABLE_NAME"); sColumnNames.push_back("GRANTOR"); sColumnNames.push_back("GRANTEE"); sColumnNames.push_back("PRIVILEGE"); sColumnNames.push_back("IS_GRANTABLE"); bool test_status=true; logMsg("Calling DatabaseMetaData.getTablePrivileges"); ResultSet oRet_ResultSet(dbmd->getTablePrivileges(sCatalogName, sSchemaName, sFtable)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getTablePrivileges Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(6) + ","); if (sRetStr == "") { logMsg("getTablePrivileges did not return any privileges"); } else { logMsg("The privileges returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetTableTypes * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getTableTypes() method must return a ResultSet object with each * row representing a table type available in the DBMS. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTableTypes() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetTableTypes() { List sColumnNames; sColumnNames.push_back("TABLE_TYPE"); bool test_status=true; logMsg("Calling DatabaseMetaData.getTableTypes"); ResultSet oRet_ResultSet(dbmd->getTableTypes()); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getTableTypes Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(1) + ","); if (sRetStr == "") { logMsg("getTableTypes did not return any table types"); } else { logMsg("The Table Types returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetTables * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getTables() method must return a ResultSet object * with each row is a description of the table * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTables() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetTables() { List sColumnNames; sColumnNames.push_back("TABLE_CAT"); sColumnNames.push_back("TABLE_SCHEM"); sColumnNames.push_back("TABLE_NAME"); sColumnNames.push_back("TABLE_TYPE"); sColumnNames.push_back("REMARKS"); bool test_status=true; logMsg("Calling DatabaseMetaData.getTables"); String tmp("%"); std::list< sql::SQLString > tmp2; ResultSet oRet_ResultSet(dbmd->getTables(sCatalogName, sSchemaName, tmp, tmp2)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getTables Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(3) + ","); if (sRetStr == "") { logMsg("getTables did not return any table names"); } else { logMsg("The Table names returned are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetTimeDateFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSystemFunctions method must return a String object * that is a comma separated list of time and date functions; * These are the X/Open CLI time and date function names used * in the JDBC function escape clause. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getTimeDateFunctions() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetTimeDateFunctions() { logMsg("Calling getTimeDateFunctions on DatabaseMetaData"); String sRetValue=dbmd->getTimeDateFunctions(); if (sRetValue.empty()) { logMsg( "getTimeDateFunctions method does not returns the comma-separated list of time and date functions "); } else { logMsg(String("getTimeDateFunctions method returns: ") + sRetValue); } } /* * @testName: testGetTypeInfo * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getTypeInfo() method must return a ResultSet object with each * row is a description of a local DBMS type. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTypeInfo() method on that object. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetTypeInfo() { List sColumnNames; sColumnNames.push_back("TYPE_NAME"); sColumnNames.push_back("DATA_TYPE"); sColumnNames.push_back("PRECISION"); sColumnNames.push_back("LITERAL_PREFIX"); sColumnNames.push_back("LITERAL_SUFFIX"); sColumnNames.push_back("CREATE_PARAMS"); sColumnNames.push_back("NULLABLE"); sColumnNames.push_back("CASE_SENSITIVE"); sColumnNames.push_back("SEARCHABLE"); sColumnNames.push_back("UNSIGNED_ATTRIBUTE"); sColumnNames.push_back("FIXED_PREC_SCALE"); sColumnNames.push_back("AUTO_INCREMENT"); sColumnNames.push_back("LOCAL_TYPE_NAME"); sColumnNames.push_back("MINIMUM_SCALE"); sColumnNames.push_back("MAXIMUM_SCALE"); sColumnNames.push_back("SQL_DATA_TYPE"); sColumnNames.push_back("SQL_DATETIME_SUB"); sColumnNames.push_back("NUM_PREC_RADIX"); bool statusColumnMatch= true; bool statusColumnCount= true; String sRetStr(""); int iColumnNamesLength= static_cast(sColumnNames.size()); logMsg("Calling DatabaseMetaData.getTypeInfo"); ResultSet oRet_ResultSet(dbmd->getTypeInfo()); ResultSetMetaData rsmd(oRet_ResultSet->getMetaData()); int iCount=rsmd->getColumnCount(); TestsListener::messagesLog() << "Minimum Column Count is:" << iColumnNamesLength << std::endl; if (iColumnNamesLength > iCount) { statusColumnCount=false; } else if (iColumnNamesLength < iCount) { iCount=iColumnNamesLength; statusColumnCount=true; } else { statusColumnCount=true; } logMsg("Comparing Column Names..."); while (iColumnNamesLength > 0) { if (ciString(sColumnNames[iColumnNamesLength - 1].c_str()) == rsmd->getColumnName(iCount).c_str()) { statusColumnMatch=true; } else { statusColumnMatch=false; break; } iCount--; iColumnNamesLength--; } if ((statusColumnMatch == false) && (statusColumnCount == true)) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getTypeInfo Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(1) + ","); if (sRetStr == "") { logMsg("getTypeInfo did not return any type names"); } else { logMsg(String("The Type names returned are : ") + sRetStr); } } /* * @testName: testGetUDTs * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getUDTs() method must return a ResultSet object with each * row is a description of a UDT (User Defined Type). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getUDTs() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetUDTs() { logMsg("Calling DatabaseMetaData.getUDTs"); String tmp("%"); std::list tmp2; ResultSet oRet_ResultSet(dbmd->getUDTs(sCatalogName, sSchemaName, tmp, tmp2)); String sRetStr; sRetStr=""; while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(3) + ","); if (sRetStr == "") { logMsg("getUDTs did not return any user defined types"); } else { logMsg("The type names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testGetUDTs01 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getUDTs() method must return a ResultSet object with each * row is a description of a UDT (User Defined Type). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getUDTs() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. * */ /* throws Exception */ void DatabaseMetaDataTest::testGetUDTs01() { List sColumnNames; sColumnNames.push_back("TYPE_CAT"); sColumnNames.push_back("TYPE_SCHEM"); sColumnNames.push_back("TYPE_NAME"); sColumnNames.push_back("CLASS_NAME"); sColumnNames.push_back("DATA_TYPE"); sColumnNames.push_back("REMARKS"); bool statusColumnMatch=true; bool statusColumnCount=true; String sRetStr; sRetStr=""; int iColumnNamesLength= static_cast( sColumnNames.size() ); logMsg("Calling DatabaseMetaData.getUDTs"); String tmp("%"); std::list tmp2; ResultSet oRet_ResultSet(dbmd->getUDTs(sCatalogName, sSchemaName, tmp, tmp2)); ResultSetMetaData rsmd(oRet_ResultSet->getMetaData()); int iCount=rsmd->getColumnCount(); TestsListener::messagesLog() << "Minimum Column Count is:" << iColumnNamesLength << std::endl; if (iColumnNamesLength > iCount) { statusColumnCount=false; logMsg("Different number of columns"); } else if (iColumnNamesLength < iCount) { iCount = iColumnNamesLength; } logMsg("Comparing Column Names..."); while (iColumnNamesLength > 0) { if (ciString(sColumnNames[iColumnNamesLength - 1].c_str()) == rsmd->getColumnName(iCount).c_str()) { statusColumnMatch=true; } else { statusColumnMatch=false; logMsg("Different columns, dumping expected and returned"); logMsg(sColumnNames[iColumnNamesLength - 1]); logMsg(rsmd->getColumnName(iCount)); break; } --iCount; --iColumnNamesLength; } if ((statusColumnMatch == false) && (statusColumnCount == true)) { logMsg("Column names or order wrong."); FAIL("Call to getUDTs Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(3) + ","); if (sRetStr == "") { logMsg("getUDTs did not return any user defined types"); } else { logMsg("The type names returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetURL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave * as specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getURL method must return a String object representing the * URL for the database; null if it cannot be generated. * (See JDK 1.2.2 API documentation). * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getURL() method * It should return a String or null if it cannot be generated * */ /* throws Exception */ void DatabaseMetaDataTest::testGetURL() { logMsg("Calling getURL on DatabaseMetaData"); String sRetValue=dbmd->getURL(); if (sRetValue.empty()) { logMsg("getURL method return a NULL value "); } else { logMsg(String("getURL method returns: ") + sRetValue); } } #endif /* * @testName: testGetUserName * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getUserName method must return a String object representing * the Username of the database. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getUserName() method * It should return a String * */ /* throws Exception */ void DatabaseMetaDataTest::testGetUserName() { logMsg("Calling getUserName on DatabaseMetaData"); String sRetValue=dbmd->getUserName(); if (sRetValue.empty()) { logMsg("getUserName method does not returns user name "); } else { logMsg(String("getUserName method returns: ") + sRetValue); } } /* * @testName: testGetVersionColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getVersionColumns(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of a table column that is automatically updated * whenever a value in a row is updated. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getVersionColumns() method on that object. * It should return a ResultSet object.Compare the column names * Validate the column names and column ordering. */ /* throws Exception */ void DatabaseMetaDataTest::testGetVersionColumns() { List sColumnNames; sColumnNames.push_back("SCOPE"); sColumnNames.push_back("COLUMN_NAME"); sColumnNames.push_back("DATA_TYPE"); sColumnNames.push_back("TYPE_NAME"); sColumnNames.push_back("COLUMN_SIZE"); sColumnNames.push_back("BUFFER_LENGTH"); sColumnNames.push_back("DECIMAL_DIGITS"); sColumnNames.push_back("PSEUDO_COLUMN"); bool test_status=true; logMsg("Calling DatabaseMetaData.getVersionColumns"); ResultSet oRet_ResultSet(dbmd->getVersionColumns(sCatalogName, sSchemaName, sFtable)); String sRetStr; sRetStr=""; test_status=columnCompare(sColumnNames, oRet_ResultSet); if (test_status == false) { logMsg("Columns return are not same either in order or name"); FAIL("Call to getVersionColumns Failed!"); } while (oRet_ResultSet->next()) sRetStr+=(oRet_ResultSet->getString(2) + ","); if (sRetStr == "") { logMsg("getVersionColumns did not return any columns"); } else { logMsg("The columns returned Are : " + sRetStr.substr(0, sRetStr.length() - 1)); } } /* * @testName: testInsertsAreDetected1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The insertsAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowInserted returns * true when called on a ResultSet object with a given type that * contains visible row insertion; false if the method * ResultSet.rowInserted returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the insertsAreDetected() method on that object with the * result set type as sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testInsertsAreDetected1() { logMsg( "Calling DatabaseMetaData.insertsAreDetected(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->insertsAreDetected(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Visible row insert can be detected for TYPE_FORWARD_ONLY"); } else { logMsg( "Visible row insert cannot be detected for TYPE_FORWARD_ONLY"); } } /* * @testName: testInsertsAreDetected2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The insertsAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowInserted returns * true when called on a ResultSet object with a given type that * contains visible row insertion; false if the method * ResultSet.rowInserted returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the insertsAreDetected() method on that object with the * result set type as sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testInsertsAreDetected2() { logMsg( "Calling DatabaseMetaData.insertsAreDetected(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->insertsAreDetected(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Visible row insert can be detected for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Visible row insert cannot be detected for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testInsertsAreDetected3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The insertsAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowInserted returns * true when called on a ResultSet object with a given type that * contains visible row insertion; false if the method * ResultSet.rowInserted returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the insertsAreDetected() method on that object with the * result set type as sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testInsertsAreDetected3() { logMsg( "Calling DatabaseMetaData.insertsAreDetected(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->insertsAreDetected(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Visible row insert can be detected for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Visible row insert cannot be detected for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testIsCatalogAtStart * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The isCatalogAtStart() method must return a boolean value; * true if the catalog name appears at the start of a fully * qualified table name; false if it appears at the end. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the isCatalogAtStart() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testIsCatalogAtStart() { logMsg("Calling isCatalogAtStart on DatabaseMetaData"); bool retValue=dbmd->isCatalogAtStart(); if (retValue) { logMsg( "isCatalogAtStart metohd returns catalog appear at the start"); } else { logMsg( "isCatalogAtStart metohd returns catalog appear at the end"); } } /* * @testName: testIsReadOnly * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isReadOnly method must return a boolean value; true if * the database is in read-only mode and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the isReadOnly() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testIsReadOnly() { logMsg("Calling isReadOnly on DatabaseMetaData"); bool retValue=dbmd->isReadOnly(); if (retValue) { logMsg("IsReadOnly method is in read-only mode"); } else { logMsg("IsReadOnly method is not in read-only mode"); } } /* * @testName: testNullPlusNonNullIsNull * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The nullPlusNonNullIsNull() method must return a boolean value; * true if the concatenation of a NULL value and a non-NULL value * results in a NULL value and false otherwise. A JDBC compliant * driver must always return true. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullPlusNonNullIsNull() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testNullPlusNonNullIsNull() { logMsg("Calling nullPlusNonNullIsNull on DatabaseMetaData"); bool retValue=dbmd->nullPlusNonNullIsNull(); if (retValue) { logMsg( "nullPlusNonNullIsNull method returns a NULL value for the concatenations between NULL and non-NULL"); } else { logMsg( "nullPlusNonNullIsNull method does not returns a NULL value for the concatenations between NULL and non-NULL"); FAIL("nullPlusNonNullIsNull method should always return true!"); } } /* * @testName: testNullsAreSortedAtEnd * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedAtEnd method must return a boolean value; * true if NULL values are sorted at the end regardless of the * sort order and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedAtEnd() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testNullsAreSortedAtEnd() { logMsg("Calling NullsAreSortedAtEnd on DatabaseMetaData"); bool retValue=dbmd->nullsAreSortedAtEnd(); if (retValue) { logMsg( "nullsAreSortedAtEnd method returns NULL values sorted at the end"); } else { logMsg( "nullsAreSortedAtEnd method returns NULL values not sorted at the end"); } } /* * @testName: testNullsAreSortedAtStart * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedAtStart method must return a boolean value; * true if NULL values are sorted at the start regardless of the * sort order and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedAtStart() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testNullsAreSortedAtStart() { logMsg("Calling nullsAreSortedAtStart on DatabaseMetaData"); bool retValue=dbmd->nullsAreSortedAtStart(); if (retValue) { logMsg( "nullsAreSortedAtStart method returns NULL values sorted at the start"); } else { logMsg( "nullsAreSortedAtStart method returns NULL values not sorted at the start"); } } /* * @testName: testNullsAreSortedHigh * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedHigh method must return a boolean value; * true if NULL values are sorted high and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedHigh() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testNullsAreSortedHigh() { logMsg("Calling nullsAreSortedHigh on DatabaseMetaData"); bool retValue=dbmd->nullsAreSortedHigh(); if (retValue) { logMsg( "nullsAreSortedHigh method returns NULL values sorted high"); } else { logMsg( "nullsAreSortedHigh method returns NULL values not sorted high"); } } /* * @testName: testNullsAreSortedLow * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedLow method must return a boolean value; * true if NULL values are sorted low and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedLow() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testNullsAreSortedLow() { logMsg("Calling nullsAreSortedLow on DatabaseMetaData"); bool retValue=dbmd->nullsAreSortedLow(); if (retValue) { logMsg( "nullsAreSortedLow method returns NULL values sorted low"); } else { logMsg( "nullsAreSortedLow method returns NULL values not sorted low"); } } /* * @testName: testOthersDeletesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersDeletesAreVisible(int resType) method must return a * boolean value; true if a rows deleted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherDeletesAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersDeletesAreVisible1() { logMsg( "Calling DatabaseMetaData.othersDeletesAreVisible(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->othersDeletesAreVisible(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Deletes made by others are visible for TYPE_FORWARD_ONLY"); } else { logMsg( "Deletes made by others are not visible for TYPE_FORWARD_ONLY"); } } /* * @testName: testOthersDeletesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersDeletesAreVisible(int resType) method must return a * boolean value; true if a rows deleted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherDeletesAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersDeletesAreVisible2() { logMsg( "Calling DatabaseMetaData.othersDeletesAreVisible(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->othersDeletesAreVisible(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Deletes made by others are visible for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Deletes made by others are not visible for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testOthersDeletesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersDeletesAreVisible(int resType) method must return a * boolean value; true if a rows deleted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherDeletesAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersDeletesAreVisible3() { logMsg( "Calling DatabaseMetaData.othersDeletesAreVisible(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->othersDeletesAreVisible(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Deletes made by others are visible for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Deletes made by others are not visible for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testOthersInsertsAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersInsertsAreVisible(int resType) method must return a * boolean value; true if a rows inserted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherInsertsAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersInsertsAreVisible1() { logMsg( "Calling DatabaseMetaData.othersInsertsAreVisible(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->othersInsertsAreVisible(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Inserts made by others are visible for TYPE_FORWARD_ONLY"); } else { logMsg( "Inserts made by others are not visible for TYPE_FORWARD_ONLY"); } } /* * @testName: testOthersInsertsAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersInsertsAreVisible(int resType) method must return a * boolean value; true if a rows inserted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherInsertsAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersInsertsAreVisible2() { logMsg( "Calling DatabaseMetaData.othersInsertsAreVisible(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->othersInsertsAreVisible(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Inserts made by others are visible for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Inserts made by others are not visible for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testOthersInsertsAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersInsertsAreVisible(int resType) method must return a * boolean value; true if a rows inserted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherInsertsAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersInsertsAreVisible3() { logMsg( "Calling DatabaseMetaData.othersInsertsAreVisible(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->othersInsertsAreVisible(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Inserts made by others are visible for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Inserts made by others are not visible for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testOthersUpdatesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersUpdatesAreVisible(int resType) method must return a * boolean value; true if a rows updated by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherUpdatesAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersUpdatesAreVisible1() { logMsg( "Calling DatabaseMetaData.othersUpdatesAreVisible(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->othersUpdatesAreVisible(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Updates made by others are visible for TYPE_FORWARD_ONLY"); } else { logMsg( "Updates made by others are not visible for TYPE_FORWARD_ONLY"); } } /* * @testName: testOthersUpdatesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersUpdatesAreVisible(int resType) method must return a * boolean value; true if a rows updated by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherUpdatesAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersUpdatesAreVisible2() { logMsg( "Calling DatabaseMetaData.othersUpdatesAreVisible(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->othersUpdatesAreVisible(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Updates made by others are visible for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Updates made by others are not visible for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testOthersUpdatesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersUpdatesAreVisible(int resType) method must return a * boolean value; true if a rows updated by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherUpdatesAreVisible(int resType) method on that * object with sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOthersUpdatesAreVisible3() { logMsg( "Calling DatabaseMetaData.othersUpdatesAreVisible(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->othersUpdatesAreVisible(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Updates made by others are visible for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Updates made by others are not visible for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testOwnDeletesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownDeletesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own deletions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownDeletesAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnDeletesAreVisible1() { logMsg( "Calling DatabaseMetaData.ownDeletesAreVisible(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->ownDeletesAreVisible(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Result Set's own deletes are visible for TYPE_FORWARD_ONLY"); } else { logMsg( "Result Set's own deletes are not visible for TYPE_FORWARD_ONLY"); } } /* * @testName: testOwnDeletesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownDeletesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own deletions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownDeletesAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnDeletesAreVisible2() { logMsg( "Calling DatabaseMetaData.ownDeletesAreVisible(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->ownDeletesAreVisible(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Result Set's own deletes are visible for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Result Set's own deletes are not visible for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testOwnDeletesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownDeletesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own deletions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownDeletesAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnDeletesAreVisible3() { logMsg( "Calling DatabaseMetaData.ownDeletesAreVisible(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->ownDeletesAreVisible(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Result Set's own deletes are visible for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Result Set's own deletes are not visible for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testOwnInsertsAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownInsertsAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own insertions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownInsertsAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnInsertsAreVisible1() { logMsg( "Calling DatabaseMetaData.ownInsertsAreVisible(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->ownInsertsAreVisible(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Result Set's own inserts are visible for TYPE_FORWARD_ONLY"); } else { logMsg( "Result Set's own inserts are not visible for TYPE_FORWARD_ONLY"); } } /* * @testName: testOwnInsertsAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownInsertsAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own insertions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownInsertsAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnInsertsAreVisible2() { logMsg( "Calling DatabaseMetaData.ownInsertsAreVisible(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->ownInsertsAreVisible(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Result Set's own inserts are visible for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Result Set's own inserts are not visible for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testOwnInsertsAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownInsertsAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own insertions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownInsertsAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnInsertsAreVisible3() { logMsg( "Calling DatabaseMetaData.ownInsertsAreVisible(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->ownInsertsAreVisible(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Result Set's own inserts are visible for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Result Set's own inserts are not visible for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testOwnUpdatesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownUpdatesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own updates are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownUpdatesAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnUpdatesAreVisible1() { logMsg( "Calling DatabaseMetaData.ownUpdatesAreVisible(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->ownUpdatesAreVisible(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Result Set's own updates are visible for TYPE_FORWARD_ONLY"); } else { logMsg( "Result Set's own updates are not visible for TYPE_FORWARD_ONLY"); } } /* * @testName: testOwnUpdatesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownUpdatesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own updates are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownUpdatesAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnUpdatesAreVisible2() { logMsg( "Calling DatabaseMetaData.ownUpdatesAreVisible(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->ownUpdatesAreVisible(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Result Set's own updates are visible for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Result Set's own updates are not visible for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testOwnUpdatesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownUpdatesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own updates are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownUpdatesAreVisible(int resType) method on that object * with sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testOwnUpdatesAreVisible3() { logMsg( "Calling DatabaseMetaData.ownUpdatesAreVisible(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->ownUpdatesAreVisible(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Result Set's own updates are visible for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Result Set's own updates are not visible for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testStoresLowerCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The storesLowerCaseIdentifiers method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-insensitive and stores them as all lowercases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesLowerCaseIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testStoresLowerCaseIdentifiers() { logMsg("Calling storesLowerCaseIdentifiers on DatabaseMetaData"); bool retValue=dbmd->storesLowerCaseIdentifiers(); if (retValue) { logMsg( "storesLowerCaseIdentifiers method returns unquoted SQL identifiers stored as lower case"); } else { logMsg( "storesLowerCaseIdentifiers returns unquoted SQL identifiers not stored as lower case"); } } /* * @testName: testStoresLowerCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesLowerCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers * in SQLstatements as case-insensitive and stores them as all * lower cases in its metadata tables and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesLowerCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testStoresLowerCaseQuotedIdentifiers() { logMsg( "Calling storesLowerCaseQuotedIdentifiers on DatabaseMetaData"); bool retValue=dbmd->storesLowerCaseQuotedIdentifiers(); if (retValue) { logMsg( "storesLowerCaseQuotedIdentifiers method returns SQL identifiers stored as lower case"); } else { logMsg( "storesLowerCaseQuotedIdentifiers method returns SQL identifiers not stored as lower case"); } } /* * @testName: testStoresMixedCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesMixedCaseIdentifiers() method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-insensitive and stores them as all mixed cases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesMixedCaseIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testStoresMixedCaseIdentifiers() { logMsg("Calling storesMixedCaseIdentifiers on DatabaseMetaData"); bool retValue=dbmd->storesMixedCaseIdentifiers(); if (retValue) { logMsg( "storesMixedCaseIdentifiers method returns unquoted SQL identifiers stored as mixed case"); } else { logMsg( "storesMixedCaseIdentifiers method returns unquoted SQL identifiers not stored as mixed case"); } } /* * @testName: testStoresMixedCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesMixedCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers in SQL * statements as case-insensitive and stores them as all mixed cases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesMixedCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testStoresMixedCaseQuotedIdentifiers() { logMsg( "Calling storesMixedCaseQuotedIdentifiers on DatabaseMetaData"); bool retValue=dbmd->storesMixedCaseQuotedIdentifiers(); if (retValue) { logMsg( "storesMixedCaseQuotedIdentifiers method returns SQL identifiers stored as mixed case"); } else { logMsg( "storesMixedCaseQuotedIdentifiers method returns SQL identifiers not stored as mixed case"); } } /* * @testName: testStoresUpperCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The storesUpperCaseIdentifiers method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-insensitive and stores them as all uppercases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesUpperCaseIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testStoresUpperCaseIdentifiers() { logMsg("Calling storesUpperCaseIdentifiers on DatabaseMetaData"); bool retValue=dbmd->storesUpperCaseIdentifiers(); if (retValue) { logMsg( "storesUpperCaseIdentifiers method returns unquoted SQL identifiers stored as upper case"); } else { logMsg( "storesUpperCaseIdentifiers method returns unquoted SQL identifiers not stored as upper case"); } } /* * @testName: testStoresUpperCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesUpperCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers in SQL * statements as case-insensitive and stores them as all upper cases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesUpperCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testStoresUpperCaseQuotedIdentifiers() { logMsg( "Calling storesUpperCaseQuotedIdentifiers on DatabaseMetaData"); bool retValue=dbmd->storesUpperCaseQuotedIdentifiers(); if (retValue) { logMsg( "storesUpperCaseQuotedIdentifiers method returns SQL identifiers stored as upper case"); } else { logMsg( "storesUpperCaseQuotedIdentifiers method returns SQL identifiers not stored as upper case"); } } /* * @testName: testSupportsANSI92EntryLevelSQL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsANSI92EntryLevelSQL() method must return a boolean * value; true if the database supports ANSI92 entry level SQL * grammar and false otherwise. All JDBC Compliant drivers must * return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsANSI92EntryLevelSQL() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsANSI92EntryLevelSQL() { logMsg("Calling supportsANSI92EntryLevelSQL on DatabaseMetaData"); bool retValue=dbmd->supportsANSI92EntryLevelSQL(); if (retValue) { logMsg("supportsANSI92EntryLevelSQL method is supported"); } else { logMsg("supportsANSI92EntryLevelSQL method is not supported"); } } /* * @testName: testSupportsANSI92FullSQL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsANSI92FullSQL() method must return a boolean value * true if the database supports ANSI92 Full SQL grammar and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsANSI92FullSQL() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsANSI92FullSQL() { bool retValue=dbmd->supportsANSI92FullSQL(); logMsg("Calling supportsANSI92FullSQL on DatabaseMetaData"); if (retValue) { logMsg("supportsANSI92FullSQL method is supported"); } else { logMsg("supportsANSI92FullSQL method is not supported"); } } /* * @testName: testSupportsANSI92IntermediateSQL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsANSI92IntermediateSQL() method must return a boolean * value; true if the database supports ANSI92 Intermediate SQL * grammar and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsANSI92IntermediateSQL() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsANSI92IntermediateSQL() { logMsg("Calling supportsANSI92IntermediateSQL on DatabaseMetaData"); bool retValue=dbmd->supportsANSI92IntermediateSQL(); if (retValue) { logMsg("supportsANSI92IntermediateSQL method is supported"); } else { logMsg("supportsANSI92IntermediateSQL method is not supported"); } } /* * @testName: testSupportsAlterTableWithAddColumn * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsAlterTableWithAddColumn() method must return a * boolean value; true if the database supports ALTER TABLE * with add Column and false otherwise (See JDK 1.2.2 API * documentation). * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsAlterTableWithAddColumn() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsAlterTableWithAddColumn() { logMsg( "Calling supportsAlterTableWithAddColumn on DatabaseMetaData"); bool retValue=dbmd->supportsAlterTableWithAddColumn(); if (retValue) { logMsg("supportsAlterTableWithAddColumn is supported"); } else { logMsg("supportsAlterTableWithAddColumn is not supported"); } } /* * @testName: testSupportsAlterTableWithDropColumn * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsAlterTableWithDropColumn() method must return a * boolean value; true if the database supports ALTER TABLE * with drop column and false otherwise (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsAlterTableWithDropColumn() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsAlterTableWithDropColumn() { logMsg( "Calling supportsAlterTableWithDropColumn on DatabaseMetaData"); bool retValue=dbmd->supportsAlterTableWithDropColumn(); if (retValue) { logMsg("supportsAlterTableWithDropColumn is supported"); } else { logMsg("supportsAlterTableWithDropColumn is not supported"); } } /* * @testName: testSupportsBatchUpdates * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsBatchUpdates() method must return a boolean * value; true if the driver supports batch updates and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsBatchUpdates() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsBatchUpdates() { logMsg("Calling DatabaseMetaData.supportsBatchUpdates"); bool retValue=dbmd->supportsBatchUpdates(); if (retValue) { logMsg("supportsBatchUpdates is supported"); } else { logMsg("supportsBatchUpdates is not supported"); } } /* * @testName: testSupportsCatalogsInDataManipulation * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInDataManipulation() method must return a * boolean value; true if the database supports using a catalog name * in a data manipulation statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsCatalogsInDataManipulation()on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCatalogsInDataManipulation() { logMsg( "Calling DatabaseMetaData.supportsCatalogsInDataManipulation"); bool retValue=dbmd->supportsCatalogsInDataManipulation(); if (retValue) { logMsg("supportsCatalogsInDataManipulation is supported"); } else { logMsg("supportsCatalogsInDataManipulation is not supported"); } } /* * @testName: testSupportsCatalogsInIndexDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInIndexDefinitions() method must return a * boolean value; true if the database supports using a catalog name * in a index definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * Call the supportsCatalogsInIndexDefinitions() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCatalogsInIndexDefinitions() { logMsg( "Calling DatabaseMetaData.supportsCatalogsInIndexDefinitions"); bool retValue=dbmd->supportsCatalogsInIndexDefinitions(); if (retValue) { logMsg("supportsCatalogsInIndexDefinitions is supported"); } else { logMsg("supportsCatalogsInIndexDefinitions is not supported"); } } /* * @testName: testSupportsCatalogsInPrivilegeDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInPrivilegeDefinitions() method must return a * boolean value; true if the database supports using a catalog name * in a privilege definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsCatalogsInPrivilegeDefinitions() method on that * object. It should return a boolean value; either true or false * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCatalogsInPrivilegeDefinitions() { logMsg( "Calling DatabaseMetaData.supportsCatalogsInPrivilegeDefinitions"); bool retValue=dbmd->supportsCatalogsInPrivilegeDefinitions(); if (retValue) { logMsg("supportsCatalogsInPrivilegeDefinitions is supported"); } else { logMsg( "supportsCatalogsInPrivilegeDefinitions is not supported"); } } /* * @testName: testSupportsCatalogsInProcedureCalls * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInProcedureCalls() method must return a * boolean value; true if the database supports using a catalog name * in a procedure call statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsCatalogsInProcedureCalls() on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCatalogsInProcedureCalls() { logMsg("Calling DatabaseMetaData.supportsCatalogsInProcedureCalls"); bool retValue=dbmd->supportsCatalogsInProcedureCalls(); if (retValue) { logMsg("supportsCatalogsInProcedureCalls is supported"); } else { logMsg("supportsCatalogsInProcedureCalls is not supported"); } } /* * @testName: testSupportsCatalogsInTableDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInTableDefinitions() method must return a * boolean value; true if the database supports using a catalog name * in a table definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * Call the supportsCatalogsInTableDefinitions() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCatalogsInTableDefinitions() { logMsg( "Calling DatabaseMetaData.supportsCatalogsInTableDefinitions()"); bool retValue=dbmd->supportsCatalogsInTableDefinitions(); if (retValue) { logMsg("supportsCatalogsInTableDefinitions is supported"); } else { logMsg("supportsCatalogsInTableDefinitions is not supported"); } } /* * @testName: testSupportsColumnAliasing * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsColumnAliasing() method must return a * boolean value; true if the database supports column aliasing * and false otherwise. A JDBC compliant driver must always return * true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsColumnAliasing() method * It should return a true value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsColumnAliasing() { logMsg("Calling supportsColumnAliasing on DatabaseMetaData"); bool retValue=dbmd->supportsColumnAliasing(); if (retValue) { logMsg("supportsColumnAliasing is supported"); } else { logMsg("supportsColumnAliasing is not supported"); FAIL("supportsColumnAliasing should always return true!"); } } /* * @testName: testSupportsConvert * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert() method must return a boolean value; * true if the database supports the scalar function CONVERT for * for the conversion of one JDBC type to another and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert() { logMsg("Calling supportsConvert on DatabaseMetaData"); bool retValue=dbmd->supportsConvert(); if (retValue) { logMsg("supportsConvert method is supported"); } else { logMsg("supportsConvert method is not supported"); } } /* * @testName: testSupportsConvert01 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(ARRAY, VARCHAR) method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert01() { logMsg( "Calling supportsConvert(ARRAY, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::ARRAY , sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(ARRAY, VARCHAR) method is supported"); } else { logMsg("supportsConvert(ARRAY, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(ARRAY, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert02 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIGINT, VARCHAR) method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert02() { logMsg("Calling supportsConvert(BIGINT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::BIGINT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(BIGINT, VARCHAR) method is supported"); } else { logMsg("supportsConvert(BIGINT, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(BIGINT, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert03 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BINARY, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert03() { #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::BINARY, sql::DataType::VARCHAR); logMsg( "Calling supportsConvert(BINARY, VARCHAR) on DatabaseMetaData"); if (retValue) { logMsg("supportsConvert(BINARY, VARCHAR) method is supported"); } else { logMsg("supportsConvert(BINARY, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(BINARY, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert04 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation). * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert04() { logMsg("Calling supportsConvert(BIT, VARCHAR) on DatabaseMetaData"); bool retValue=dbmd->supportsConvert(sql::DataType::BIT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(BIT, VARCHAR) method is supported"); } else { logMsg("supportsConvert(BIT, VARCHAR) method is not supported"); } } /* * @testName: testSupportsConvert05 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BLOB, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert05() { logMsg("Calling supportsConvert(BLOB, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::BLOB, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(BLOB, VARCHAR) method is supported"); } else { logMsg("supportsConvert(BLOB, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(BLOB, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert06 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(CHAR, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert06() { logMsg("Calling supportsConvert(CHAR, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::CHAR, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(CHAR, VARCHAR) method is supported"); } else { logMsg("supportsConvert(CHAR, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(CHAR, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert07 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(CLOB, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert07() { logMsg("Calling supportsConvert(CLOB, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::CLOB, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(CLOB, VARCHAR) method is supported"); } else { logMsg("supportsConvert(CLOB, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(CLOB, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert08 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DATE, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert08() { logMsg("Calling supportsConvert(DATE, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DATE, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(DATE, VARCHAR) method is supported"); } else { logMsg("supportsConvert(DATE, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(DATE, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert09 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DECIMAL, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert09() { logMsg("Calling supportsConvert(DECIMAL, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DECIMAL, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(DECIMAL, VARCHAR) method is supported"); } else { logMsg("supportsConvert(DECIMAL, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(DECIMAL, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert10 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DISTINCT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert10() { logMsg( "Calling supportsConvert(DISTINCT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DISTINCT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(DISTINCT, VARCHAR) method is supported"); } else { logMsg("supportsConvert(DISTINCT, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(DISTINCT, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert11 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DOUBLE, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert11() { logMsg( "Calling supportsConvert(DOUBLE, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DOUBLE, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(DOUBLE, VARCHAR) method is supported"); } else { logMsg("supportsConvert(DOUBLE, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(DOUBLE, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert12 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(FLOAT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert12() { logMsg( "Calling supportsConvert(FLOAT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::FLOAT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(FLOAT, VARCHAR) method is supported"); } else { logMsg("supportsConvert(FLOAT, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(FLOAT, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert13 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(INTEGER, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert13() { logMsg( "Calling supportsConvert(INTEGER, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::INTEGER, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(INTEGER, VARCHAR) method is supported"); } else { logMsg("supportsConvert(INTEGER, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(INTEGER, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert14 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(JAVA_OBJECT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* Doesn't make sense in C/C++*/ /* void DatabaseMetaDataTest::testSupportsConvert14() { logMsg( "Calling supportsConvert(JAVA_OBJECT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue = dbmd->supportsConvert(sql::DataType::JAVA_OBJECT, sql::DataType::VARCHAR); if (retValue) { logMsg( "supportsConvert(JAVA_OBJECT, VARCHAR) method is supported"); } else { logMsg("supportsConvert(JAVA_OBJECT, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(JAVA_OBJECT, VARCHAR) method is not supported"); #endif } */ /* * @testName: testSupportsConvert15 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(LONGVARBINARY, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert15() { logMsg( "Calling supportsConvert(LONGVARBINARY, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::LONGVARBINARY, sql::DataType::VARCHAR); if (retValue) { logMsg( "supportsConvert(LONGVARBINARY, VARCHAR) method is supported"); } else { logMsg("supportsConvert(LONGVARBINARY, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(LONGVARBINARY, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert16 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(LONGVARCHAR, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert16() { logMsg( "Calling supportsConvert(LONGVARCHAR, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::LONGVARCHAR, sql::DataType::VARCHAR); if (retValue) { logMsg( "supportsConvert(LONGVARCHAR, VARCHAR) method is supported"); } else { logMsg("supportsConvert(LONGVARCHAR, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(LONGVARCHAR, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert17 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(NULL, VARCHAR) on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert17() { logMsg("Calling supportsConvert(NULL, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::SQLNULL, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(NULL, VARCHAR) method is supported"); } else { logMsg("supportsConvert(NULL, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(NULL, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert18 * @assertion: The DatabaseMetaData provides information about the database * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(NUMERIC, VARCHAR) method on that object * It should return a boolean value; either true or false * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert18() { logMsg( "Calling supportsConvert(NUMERIC, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::NUMERIC, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(NUMERIC, VARCHAR) method is supported"); } else { logMsg("supportsConvert(NUMERIC, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(NUMERIC, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert19 * @assertion: The DatabaseMetaData provides information about the database * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(OTHER, VARCHAR) method on that object * It should return a boolean value; either true or false * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert19() { logMsg( "Calling supportsConvert(OTHER, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::OTHER, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(OTHER, VARCHAR) method is supported"); } else { logMsg("supportsConvert(OTHER, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(OTHER, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert20 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(REAL, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert20() { logMsg("Calling supportsConvert(REAL, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::REAL, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(REAL, VARCHAR) method is supported"); } else { logMsg("supportsConvert(REAL, VARCHAR) method is not supported"); } #else logMsg("supportsConvert(REAL, VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert21 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(REF, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert21() { logMsg("Calling supportsConvert(REF, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::REF, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(REF VARCHAR) method is supported"); } else { logMsg("supportsConvert(REF VARCHAR) method is not supported"); } #else logMsg("supportsConvert(REF VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert22 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(SMALLINT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert22() { logMsg("Calling supportsConvert(SMALLINT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::SMALLINT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(SMALLINT VARCHAR) method is supported"); } else { logMsg("supportsConvert(SMALLINT VARCHAR) method is not supported"); } #else logMsg("supportsConvert(SMALLINT VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert23 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(STRUCT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert23() { logMsg("Calling supportsConvert(STRUCT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::STRUCT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(STRUCT VARCHAR) method is supported"); } else { logMsg("supportsConvert(STRUCT VARCHAR) method is not supported"); } #else logMsg("supportsConvert(STRUCT VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert24 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TIME, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert24() { logMsg("Calling supportsConvert(TIME, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::TIME, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(TIME VARCHAR) method is supported"); } else { logMsg("supportsConvert(TIME VARCHAR) method is not supported"); } #else logMsg("supportsConvert(TIME VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert25 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TIMESTAMP, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert25() { logMsg("Calling supportsConvert(TIMESTAMP, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::TIMESTAMP, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(TIMESTAMP VARCHAR) method is supported"); } else { logMsg("supportsConvert(TIMESTAMP VARCHAR) method is not supported"); } #else logMsg("supportsConvert(TIMESTAMP VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert26 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TINYINT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert26() { logMsg("Calling supportsConvert(TINYINT, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::TINYINT, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(TINYINT VARCHAR) method is supported"); } else { logMsg("supportsConvert(TINYINT VARCHAR) method is not supported"); } #else logMsg("supportsConvert(TINYINT VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert27 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(VARBINARY, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert27() { logMsg("Calling supportsConvert(VARBINARY, VARCHAR) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::VARBINARY, sql::DataType::VARCHAR); if (retValue) { logMsg("supportsConvert(VARBINARY VARCHAR) method is supported"); } else { logMsg("supportsConvert(VARBINARY VARCHAR) method is not supported"); } #else logMsg("supportsConvert(VARBINARY VARCHAR) method is not supported"); #endif } /* * @testName: testSupportsConvert28 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIGINT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert28() { logMsg("Calling supportsConvert(BIGINT, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::BIGINT, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(BIGINT, INTEGER) method is supported"); } else { logMsg("supportsConvert(BIGINT, INTEGER) method is not supported"); } #else logMsg("supportsConvert(BIGINT, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert29 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert29() { logMsg("Calling supportsConvert(BIT, INTEGER) on DatabaseMetaData"); bool retValue=dbmd->supportsConvert(sql::DataType::BIT, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(BIT, INTEGER) method is supported"); } else { logMsg("supportsConvert(BIT, INTEGER) method is not supported"); } } /* * @testName: testSupportsConvert30 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DATE, INTEGER) method onn that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert30() { logMsg("Calling supportsConvert(DATE, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DATE, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(DATE, INTEGER) method is supported"); } else { logMsg("supportsConvert(DATE, INTEGER) method is not supported"); } #else logMsg("supportsConvert(DATE, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert31 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DECIMAL, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert31() { logMsg("Calling supportsConvert(DECIMAL, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DECIMAL, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(DECIMAL, INTEGER) method is supported"); } else { logMsg("supportsConvert(DECIMAL, INTEGER) method is not supported"); } #else logMsg("supportsConvert(DECIMAL, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert32 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DOUBLE, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert32() { logMsg("Calling supportsConvert(DOUBLE, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::DOUBLE, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(DOUBLE, INTEGER) method is supported"); } else { logMsg("supportsConvert(DOUBLE, INTEGER) method is not supported"); } #else logMsg("supportsConvert(DOUBLE, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert33 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(FLOAT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert33() { logMsg("Calling supportsConvert(FLOAT, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_ALL_DATATYPES_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::FLOAT, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(FLOAT, INTEGER) method is supported"); } else { logMsg("supportsConvert(FLOAT, INTEGER) method is not supported"); } #else logMsg("supportsConvert(FLOAT, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert34 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(NUMERIC, INTEGER) method on that object. * It should return a boolean value; true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert34() { logMsg("Calling supportsConvert(NUMERIC, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::NUMERIC, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(NUMERIC, INTEGER) method is supported"); } else { logMsg("supportsConvert(NUMERIC, INTEGER) method is not supported"); } #else logMsg("supportsConvert(NUMERIC, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert35 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(REAL, INTEGER) method on that object. * It should return a boolean value; either true false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert35() { logMsg("Calling supportsConvert(REAL, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::REAL, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(REAL, INTEGER) method is supported"); } else { logMsg("supportsConvert(REAL, INTEGER) method is not supported"); } #else logMsg("supportsConvert(REAL, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert36 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(SMALLINT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert36() { logMsg("Calling supportsConvert(SMALLINT, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::SMALLINT, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(SMALLINT, INTEGER) method is supported"); } else { logMsg("supportsConvert(SMALLINT, INTEGER) method is not supported"); } #else logMsg("supportsConvert(SMALLINT, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsConvert37 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TINYINT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsConvert37() { logMsg("Calling supportsConvert(TINYINT, INTEGER) on DatabaseMetaData"); #ifdef WE_HAVE_DATATYPE_AGAIN bool retValue=dbmd->supportsConvert(sql::DataType::TINYINT, sql::DataType::INTEGER); if (retValue) { logMsg("supportsConvert(TINYINT, INTEGER) method is supported"); } else { logMsg("supportsConvert(TINYINT, INTEGER) method is not supported"); } #else logMsg("supportsConvert(TINYINT, INTEGER) method is not supported"); #endif } /* * @testName: testSupportsCoreSQLGrammar * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCoreSQLGrammar() method must return a boolean value * true if the database supports the ODBC core SQL grammar and * false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsCoreSQLGrammar() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCoreSQLGrammar() { logMsg("Calling supportsCoreSQLGrammar on DatabaseMetaData"); bool retValue=dbmd->supportsCoreSQLGrammar(); if (retValue) { logMsg("supportsCoreSQLGrammar method is supported"); } else { logMsg("supportsCoreSQLGrammar method is not supported"); } } /* * @testName: testSupportsCorrelatedSubqueries * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCorrelatedSubqueries() method must return a * boolean value; true if the database supports correlated subqueries * and false otherwise. A JDBC Compliant driver always returns true. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsCorrelatedSubqueries() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsCorrelatedSubqueries() { logMsg("Calling DatabaseMetaData.supportsCorrelatedSubqueries"); bool retValue=dbmd->supportsCorrelatedSubqueries(); if (retValue) { logMsg("supportsCorrelatedSubqueries is supported"); } else { logMsg("supportsCorrelatedSubqueries is not supported"); } } /* * @testName: testSupportsDataDefinitionAndDataManipulationTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsDataDefinitionAndDataManipulationTransactions method * must return a boolean value; true if both data definition and * data manipulation statements within a transaction are supported; * false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsDataDefinitionAndDataManipulationTransactions() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsDataDefinitionAndDataManipulationTransactions() { logMsg( "Calling DatabaseMetaData.supportsDataDefinitionAndDataManipulationTransactions"); bool retValue=dbmd->supportsDataDefinitionAndDataManipulationTransactions(); if (retValue) { logMsg( "supportsDataDefinitionAndDataManipulationTransactions is supported"); } else { logMsg( "supportsDataDefinitionAndDataManipulationTransactions is not supported"); } } /* * @testName: testSupportsDataManipulationTransactionsOnly * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsDataManipulationTransactionsOnly() method must return * a boolean value, true if the data manipulation statements within * a transaction is supported and false otherwise. A JDBC Compliant * driver should return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsDataManipulationTransactionsOnly() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsDataManipulationTransactionsOnly() { logMsg( "Calling DatabaseMetaData.supportsDataManipulationTransactionsOnly"); bool retValue=dbmd->supportsDataManipulationTransactionsOnly(); if (retValue) { logMsg("supportsDataManipulationTransactionsOnly is supported"); } else { logMsg( "supportsDataManipulationTransactionsOnly is not supported"); } } /* * @testName: testSupportsDifferentTableCorrelationNames * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsDifferentTableCorrelationNames() method must return * a boolean value; true if the database supports table * correlation names and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsDifferentTableCorrelationNames() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsDifferentTableCorrelationNames() { logMsg( "Calling supportsDifferentTableCorrelationNames on DatabaseMetaData"); bool retValue=dbmd->supportsDifferentTableCorrelationNames(); if (retValue) { logMsg( "supportsDifferentTableCorrelationNames method is supported"); } else { logMsg( "supportsDifferentTableCorrelationNames method is not supported"); } } /* * @testName: testSupportsExpressionsInOrderBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsExpressionsInOrderBy() method must return * a boolean value; true if the database supports expressions * in ORDER BY lists and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsExpressionsInOrderBy() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsExpressionsInOrderBy() { logMsg("Calling supportsExpressionsInOrderBy on DatabaseMetaData"); bool retValue=dbmd->supportsExpressionsInOrderBy(); if (retValue) { logMsg("supportsExpressionsInOrderBy method is supported"); } else { logMsg("supportsExpressionsInOrderBy method is not supported"); } } /* * @testName: testSupportsExtendedSQLGrammar * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsExtendedSQLGrammar() method must return a boolean * value; true if the database supports the ODBC Extended SQL * grammar and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsExtendedSQLGrammar() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsExtendedSQLGrammar() { logMsg("Calling supportsExtendedSQLGrammar on DatabaseMetaData"); bool retValue=dbmd->supportsExtendedSQLGrammar(); if (retValue) { logMsg("supportsExtendedSQLGrammar method is supported"); } else { logMsg("supportsExtendedSQLGrammar method is not supported"); } } /* * @testName: testSupportsFullOuterJoins * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsFullOuterJoins() method must return a * boolean value; true if the database supports full nested outer * joins and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsFullOuterJoins() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsFullOuterJoins() { logMsg("Calling supportsFullOuterJoins on DatabaseMetaData"); bool retValue=dbmd->supportsFullOuterJoins(); if (retValue) { logMsg("supportsFullOuterJoins method is supported"); if (!dbmd->supportsLimitedOuterJoins()) { FAIL("supportsLimitedOuterJoins() must " + "be true if supportsFullOuterJoins() " + "is true!"); } } else { logMsg("supportsFullOuterJoins method is not supported"); } } /* * @testName: testSupportsGroupBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsGroupBy() method must return a boolean value; * true if the database supports GROUP BY clause * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsGroupBy() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsGroupBy() { logMsg("Calling supportsGroupBy on DatabaseMetaData"); bool retValue=dbmd->supportsGroupBy(); if (retValue) { logMsg("supportsGroupBy method is supported"); } else { logMsg("supportsGroupBy method is not supported"); } } /* * @testName: testSupportsGroupByBeyondSelect * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsGroupByBeyondSelect() method must return a boolean * value; true if a GROUP BY clause can use columns that are not * in the SELECT clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsGroupByBeyondSelect() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsGroupByBeyondSelect() { logMsg("Calling supportsGroupByBeyondSelect on DatabaseMetaData"); bool retValue=dbmd->supportsGroupByBeyondSelect(); if (retValue) { logMsg("supportsGroupByBeyondSelect method is supported"); } else { logMsg("supportsGroupByBeyondSelect method is not supported"); } } /* * @testName: testSupportsGroupByUnrelated * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsGroupByUnrelated() method must return a boolean value; * true if a GROUP BY clause can use columns that are not in the * SELECT clause and false otherwise (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsGroupByUnrelated() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsGroupByUnrelated() { logMsg("Calling supportsGroupByUnrelated on DatabaseMetaData"); bool retValue=dbmd->supportsGroupByUnrelated(); if (retValue) { logMsg("supportsGroupByUnrelated method is supported"); } else { logMsg("supportsGroupByUnrelated method is not supported"); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testSupportsIntegrityEnhancementFacility * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsIntegrityEnhancementFacility() method must return a * boolean value; true if the database supports the SQL Integrity * Enhancement Facility and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsIntegrityEnhancementFacility() method onn that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsIntegrityEnhancementFacility() { logMsg( "Calling supportsIntegrityEnhancementFacility on DatabaseMetaData"); bool retValue=dbmd->supportsIntegrityEnhancementFacility(); if (retValue) { logMsg( "supportsIntegrityEnhancementFacility method is supported"); } else { logMsg( "supportsIntegrityEnhancementFacility method is not supported"); } } #endif /* * @testName: testSupportsLikeEscapeClause * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsLikeEscapeClause() method must return a boolean value * true if the database supports specifying a LIKE escape clause * and false otherwise. A JDBC compliant driver always return true. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsLikeEscapeClause() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsLikeEscapeClause() { logMsg("Calling supportsLikeEscapeClause on DatabaseMetaData"); bool retValue=dbmd->supportsLikeEscapeClause(); if (retValue) { logMsg("supportsLikeEscapeClause method is supported"); } else { logMsg("supportsLikeEscapeClause method is not supported"); } } /* * @testName: testSupportsLimitedOuterJoins * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsLimitedOuterJoins() method must return a * boolean value; true if the database supports limited outer joins * and false otherwise. Note if the method supportsFullOuterJoins * return true, this method will return true. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsLimitedOuterJoins() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsLimitedOuterJoins() { logMsg("Calling supportsLimitedOuterJoins on DatabaseMetaData"); bool retValue=dbmd->supportsLimitedOuterJoins(); if (retValue) { logMsg("supportsLimitedOuterJoins method is supported"); } else { logMsg("supportsLimitedOuterJoins method is not supported"); } } /* * @testName: testSupportsMinimumSQLGrammar * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMinimumSQLGrammar() method must return a boolean * value; true if the database supports the ODBC Minimum SQL * grammar and false otherwise. All JDBC Compliant drivers must * return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMinimumSQLGrammar() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsMinimumSQLGrammar() { logMsg("Calling supportsMinimumSQLGrammar on DatabaseMetaData"); bool retValue=dbmd->supportsMinimumSQLGrammar(); if (retValue) { logMsg("supportsMinimumSQLGrammar method is supported"); } else { logMsg("supportsMinimumSQLGrammar method is not supported"); } } /* * @testName: testSupportsMixedCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The supportsMixedCaseIdentifiers method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-sensitive and false otherwise. A JDBC * compliant driver will always return false. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMixedCaseIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsMixedCaseIdentifiers() { logMsg("Calling supportsMixedCaseIdentifiers on DatabaseMetaData"); bool retValue=dbmd->supportsMixedCaseIdentifiers(); if (retValue) { logMsg("supportsMixedCaseIdentifiers method is supported"); } else { logMsg("supportsMixedCaseIdentifiers method is not supported"); } } /* * @testName: testSupportsMixedCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMixedCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers in SQL * statements as case-insensitive and stores them as all mixed cases * in its metadata tables and false otherwise. A JDBC Compliant * driver will always return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMixedCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsMixedCaseQuotedIdentifiers() { logMsg( "Calling supportsMixedCaseQuotedIdentifiers on DatabaseMetaData"); bool retValue=dbmd->supportsMixedCaseQuotedIdentifiers(); if (retValue) { logMsg("supportsMixedCaseQuotedIdentifiers method is supported"); } else { logMsg( "supportsMixedCaseQuotedIdentifiers method is not supported"); } } /* * @testName: testSupportsMultipleResultSets * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMultipleResultSets() method must return a boolean value * true if the database supports multiple result sets from a single * execute statement and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMultipleResultSets() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsMultipleResultSets() { logMsg("Calling supportsMultipleResultSets on DatabaseMetaData"); bool retValue=dbmd->supportsMultipleResultSets(); if (retValue) { logMsg("supportsMultipleResultSets method is supported"); } else { logMsg("supportsMultipleResultSets method is not supported"); } } /* * @testName: testSupportsMultipleTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMultipleTransactions() method must return a boolean * value; true if multiple transactions can be open at once on * different connections and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMultipleTransactions() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsMultipleTransactions() { logMsg("Calling supportsMultipleTransactions on DatabaseMetaData"); bool retValue=dbmd->supportsMultipleTransactions(); if (retValue) { logMsg("supportsMultipleTransactions method is supported"); } else { logMsg("supportsMultipleTransactions method is not supported"); } } /* * @testName: testSupportsNonNullableColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsNonNullableColumns() method must return a boolean * value; true if the database supports defining columns as * non-nullable and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsNonNullableColumns() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsNonNullableColumns() { logMsg("Calling supportsNonNullableColumns on DatabaseMetaData"); bool retValue=dbmd->supportsNonNullableColumns(); if (retValue) { logMsg("supportsNonNullableColumns method is supported"); } else { logMsg("supportsNonNullableColumns method is not supported"); } } /* * @testName: testSupportsOpenCursorsAcrossCommit * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenCursorsAcrossCommit() method must return a boolean * value; true if cursors always remain open after commits; false * if cursors are closed on commit. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenCursorsAcrossCommit() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsOpenCursorsAcrossCommit() { logMsg("Calling DatabaseMetaData.supportsOpenCursorsAcrossCommit"); bool retValue=dbmd->supportsOpenCursorsAcrossCommit(); if (retValue) { logMsg("supportsOpenCursorsAcrossCommit is supported"); } else { logMsg("supportsOpenCursorsAcrossCommit is not supported"); } } /* * @testName: testSupportsOpenCursorsAcrossRollback * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenCursorsAcrossRollback() method must return a boolean * value; true if cursors always remain open after rollbacks; false * if cursors are closed on rollback. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenCursorsAcrossRollback() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsOpenCursorsAcrossRollback() { logMsg("Calling DatabaseMetaData.supportsOpenCursorsAcrossRollback"); bool retValue=dbmd->supportsOpenCursorsAcrossRollback(); if (retValue) { logMsg("supportsOpenCursorsAcrossRollback is supported"); } else { logMsg("supportsOpenCursorsAcrossRollback is not supported"); } } /* * @testName: testSupportsOpenStatementsAcrossCommit * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenStatementsAcrossCommit() method must return a * boolean value; true if statements always remain open after * commits; false if statements are closed on commit. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenStatementsAcrossCommit() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsOpenStatementsAcrossCommit() { logMsg( "Calling DatabaseMetaData.supportsOpenStatementsAcrossCommit"); bool retValue=dbmd->supportsOpenStatementsAcrossCommit(); if (retValue) { logMsg("supportsOpenStatementsAcrossCommit is supported"); } else { logMsg("supportsOpenStatementsAcrossCommit is not supported"); } } /* * @testName: testSupportsOpenStatementsAcrossRollback * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenStatementsAcrossRollback() method must return a * boolean value; true if statements always remain open after * rollbacks; false if statements are closed on rollback. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenStatementsAcrossRollback() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsOpenStatementsAcrossRollback() { logMsg( "Calling DatabaseMetaData.supportsOpenStatementsAcrossRollback"); bool retValue=dbmd->supportsOpenStatementsAcrossRollback(); if (retValue) { logMsg("supportsOpenStatementsAcrossRollback is supported"); } else { logMsg("supportsOpenStatementsAcrossRollback is not supported"); } } /* * @testName: testSupportsOrderByUnrelated * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOrderByUnrelated() method must return * a boolean value; true if the database supports ORDER BY * clause can use columns that are not in the SELECT clause * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsOrderByUnrelated() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsOrderByUnrelated() { logMsg("Calling supportsOrderByUnrelated on DatabaseMetaData"); bool retValue=dbmd->supportsOrderByUnrelated(); if (retValue) { logMsg("supportsOrderByUnrelated method is supported"); } else { logMsg("supportsOrderByUnrelated method is not supported"); } } /* * @testName: testSupportsOuterJoins * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOuterJoins() method must return a * boolean value; true if the database supports form of outer * joins and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsOuterJoins() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsOuterJoins() { logMsg("Calling supportsOuterJoins on DatabaseMetaData"); bool retValue=dbmd->supportsOuterJoins(); if (retValue) { logMsg("supportsOuterJoins method is supported"); } else { logMsg("supportsOuterJoins method is not supported"); } } /* * @testName: testSupportsPositionedDelete * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsPositionedDelete() method must return a * boolean value; true if the database supports positioned * DELETE statement and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsPositionedDelete() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsPositionedDelete() { logMsg("Calling DatabaseMetaData.supportsPositionedDelete"); bool retValue=dbmd->supportsPositionedDelete(); if (retValue) { logMsg("supportsPositionedDelete is supported"); } else { logMsg("supportsPositionedDelete is not supported"); } } /* * @testName: testSupportsPositionedUpdate * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsPositionedUpdate() method must return a * boolean value; true if the database supports positioned * UPDATE statement and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsPositionedUpdate() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsPositionedUpdate() { logMsg("Calling DatabaseMetaData.supportsPositionedUpdate"); bool retValue=dbmd->supportsPositionedUpdate(); if (retValue) { logMsg("supportsPositionedUpdate is supported"); } else { logMsg("supportsPositionedUpdate is not supported"); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testSupportsResultSetConcurrency1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_FORWARD_ONLY and CONCUR_READ_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetConcurrency1() { logMsg( "Calling DatabaseMetaData.supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_READ_ONLY)"); bool retValue=dbmd->supportsResultSetConcurrency(sql::ResultSet::TYPE_FORWARD_ONLY, sql::ResultSet::CONCUR_READ_ONLY); if (retValue) { logMsg( "supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_READ_ONLY) is supported"); } else { logMsg( "supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_READ_ONLY) is not supported"); } } /* * @testName: testSupportsResultSetConcurrency2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_FORWARD_ONLY and CONCUR_UPDATABLE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetConcurrency2() { logMsg( "Calling DatabaseMetaData.supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE)"); bool retValue=dbmd->supportsResultSetConcurrency(sql::ResultSet::TYPE_FORWARD_ONLY, sql::ResultSet::CONCUR_UPDATABLE); if (retValue) { logMsg( "supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE) is supported"); } else { logMsg( "supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE) is not supported"); } } /* * @testName: testSupportsResultSetConcurrency3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_INSENSITIVE and CONCUR_READ_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetConcurrency3() { logMsg( "Calling DatabaseMetaData.supportsResultSetConcurrency(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)"); bool retValue=dbmd->supportsResultSetConcurrency(sql::ResultSet::TYPE_SCROLL_INSENSITIVE, sql::ResultSet::CONCUR_READ_ONLY); if (retValue) { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY) is supported"); } else { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY) is not supported"); } } /* * @testName: testSupportsResultSetConcurrency4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_INSENSITIVE and CONCUR_UPDATABLE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetConcurrency4() { logMsg( "Calling DatabaseMetaData.supportsResultSetConcurrency(TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE)"); bool retValue=dbmd->supportsResultSetConcurrency(sql::ResultSet::TYPE_SCROLL_INSENSITIVE, sql::ResultSet::CONCUR_UPDATABLE); if (retValue) { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE) is supported"); } else { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE) is not supported"); } } /* * @testName: testSupportsResultSetConcurrency5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_SENSITIVE and CONCUR_READ_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetConcurrency5() { logMsg( "Calling DatabaseMetaData.supportsResultSetConcurrency(TYPE_SCROLL_SENSITIVE, CONCUR_READ_ONLY)"); bool retValue=dbmd->supportsResultSetConcurrency(sql::ResultSet::TYPE_SCROLL_SENSITIVE, sql::ResultSet::CONCUR_READ_ONLY); if (retValue) { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_SENSITIVE, CONCUR_READ_ONLY) is supported"); } else { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_SENSITIVE, CONCUR_READ_ONLY) is not supported"); } } /* * @testName: testSupportsResultSetConcurrency6 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_SENSITIVE and CONCUR_UPDATABLE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetConcurrency6() { logMsg( "Calling DatabaseMetaData.supportsResultSetConcurrency(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE)"); bool retValue=dbmd->supportsResultSetConcurrency(sql::ResultSet::TYPE_SCROLL_SENSITIVE, sql::ResultSet::CONCUR_UPDATABLE); if (retValue) { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE) is supported"); } else { logMsg( "supportsResultSetConcurrency(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE) is not supported"); } } #endif /* * @testName: testSupportsResultSetType1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetType(int resType) method must return a * boolean value where resType can be any one of the following * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE. * The value is true if the database supports the ResultSet type * resType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetType(int resType) method with Type TYPE_FORWARD_ONLY * on that object.It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetType1() { logMsg( "Calling DatabaseMetaData.supportsResultSetType(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->supportsResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg("TYPE_FORWARD_ONLY ResultSetType is supported"); } else { logMsg("TYPE_FORWARD_ONLY ResultSetType is not supported"); } } /* * @testName: testSupportsResultSetType2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetType(int resType) method must return a * boolean value where resType can be any one of the following * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE. * The value is true if the database supports the ResultSet type * resType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetType() method with Type TYPE_SCROLL_INSENSITIVE * on that object.It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetType2() { logMsg( "Calling DatabaseMetaData.supportsResultSetType(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->supportsResultSetType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg("TYPE_SCROLL_INSENSITIVE ResultSetType is supported"); } else { logMsg("TYPE_SCROLL_INSENSITIVE ResultSetType is not supported"); } } /* * @testName: testSupportsResultSetType3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetType(int resType) method must return a * boolean value where resType can be any one of the following * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE. * The value is true if the database supports the ResultSet type * resType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetType() method with Type TYPE_SCROLL_SENSITIVE * on that object.It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsResultSetType3() { logMsg( "Calling DatabaseMetaData.supportsResultSetType(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->supportsResultSetType(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg("TYPE_SCROLL_SENSITIVE ResultSetType is supported"); } else { logMsg("TYPE_SCROLL_SENSITIVE ResultSetType is not supported"); } } /* * @testName: testSupportsSchemasInDataManipulation * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInDataManipulation() method must return a * boolean value; true if the database supports using a schema name * in a data manipulation statement and false otherwise. * (See JDK 1.2.2 API documentation) * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.supportsSchemasInDataManipulation() on that object. * It should return a boolean value either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSchemasInDataManipulation() { logMsg("Calling DatabaseMetaData.supportsSchemasInDataManipulation"); bool retValue=dbmd->supportsSchemasInDataManipulation(); if (retValue) { logMsg("supportsSchemasInDataManipulation is supported"); } else { logMsg("supportsSchemasInDataManipulation is not supported"); } } /* * @testName: testSupportsSchemasInIndexDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInIndexDefinitions() method must return a * boolean value; true if the database supports using a schema name * in a index definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsSchemasInIndexDefinitions() on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSchemasInIndexDefinitions() { logMsg("Calling DatabaseMetaData.supportsSchemasInIndexDefinitions"); bool retValue=dbmd->supportsSchemasInIndexDefinitions(); if (retValue) { logMsg("supportsSchemasInIndexDefinitions is supported"); } else { logMsg("supportsSchemasInIndexDefinitions is not supported"); } } /* * @testName: testSupportsSchemasInPrivilegeDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInPrivilegeDefinitions() method must return a * boolean value; true if the database supports using a schema name * in a privilege definition statement and false otherwise. * (See JDK 1.2.2 API documentation). * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsSchemasInPrivilegeDefinitions() on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSchemasInPrivilegeDefinitions() { logMsg( "Calling DatabaseMetaData.supportsSchemasInPrivilegeDefinitions"); bool retValue=dbmd->supportsSchemasInPrivilegeDefinitions(); if (retValue) { logMsg("supportsSchemasInPrivilegeDefinitions is supported"); } else { logMsg("supportsSchemasInPrivilegeDefinitions is not supported"); } } /* * @testName: testSupportsSchemasInProcedureCalls * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInProcedureCalls() method must return a * boolean value; true if the database supports using a schema name * in a procedure call statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.supportsSchemasInProcedureCalls() on * that object. It should return a boolean value; either true or false * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSchemasInProcedureCalls() { logMsg("Calling DatabaseMetaData.supportsSchemasInProcedureCalls"); bool retValue=dbmd->supportsSchemasInProcedureCalls(); if (retValue) { logMsg("supportsSchemasInProcedureCalls is supported"); } else { logMsg("supportsSchemasInProcedureCalls is not supported"); } } /* * @testName: testSupportsSchemasInTableDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInTableDefinitions() method must return a * boolean value; true if the database supports using a schema name * in a table definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.supportsSchemasInTableDefinitions() * on that object.It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSchemasInTableDefinitions() { logMsg("Calling DatabaseMetaData.supportsSchemasInTableDefinitions"); bool retValue=dbmd->supportsSchemasInTableDefinitions(); if (retValue) { logMsg("supportsSchemasInTableDefinitions is supported"); } else { logMsg("supportsSchemasInTableDefinitions is not supported"); } } /* * @testName: testSupportsSelectForUpdate * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSelectForUpdate() method must return a * boolean value; true if the database supports positioned * UPDATE statement and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSelectForUpdate() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSelectForUpdate() { logMsg("Calling DatabaseMetaData.supportsSelectForUpdate"); bool retValue=dbmd->supportsSelectForUpdate(); if (retValue) { logMsg("supportsSelectForUpdate is supported"); } else { logMsg("supportsSelectForUpdate is not supported"); } } /* * @testName: testSupportsStoredProcedures * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave * as specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented.(See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The supportsStoredProcedures method must return a boolean value; * true if the database supports stored procedure calls and false if * the database does not support it. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsStoredprocedures() method * It should return true value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsStoredProcedures() { if (hasSps) { logMsg("Calling supportsStoredProcedures on DatabaseMetaData"); bool retValue=dbmd->supportsStoredProcedures(); if (retValue) { logMsg("SupportsStoredProcedures is supported"); } else { logErr("SupportsStoredProcedures is not supported"); FAIL("supportsStoredProcedures should always return true!"); } } } /* * @testName: testSupportsSubqueriesInComparisons * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInComparisons() method must return a * boolean value; true if the database supports subqueries in * comparison expressions and false otherwise. A JDBC compliant * driver always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInComparisons() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSubqueriesInComparisons() { logMsg("Calling DatabaseMetaData.supportsSubqueriesInComparisons"); bool retValue=dbmd->supportsSubqueriesInComparisons(); if (retValue) { logMsg("supportsSubqueriesInComparisons is supported"); } else { logMsg("supportsSubqueriesInComparisons is not supported"); } } /* * @testName: testSupportsSubqueriesInExists * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInExists() method must return a * boolean value; true if the database supports subqueries in * EXISTS expressions and false otherwise. A JDBC compliant driver * always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInExists() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSubqueriesInExists() { logMsg("Calling DatabaseMetaData.supportsSubqueriesInExists"); bool retValue=dbmd->supportsSubqueriesInExists(); if (retValue) { logMsg("supportsSubqueriesInExists is supported"); } else { logMsg("supportsSubqueriesInExists is not supported"); } } /* * @testName: testSupportsSubqueriesInIns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInIns() method must return a * boolean value; true if the database supports subqueries in * "IN" statements and false otherwise. A JDBC Compliant driver * always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInIns() method on that object. * It should return a boolean value either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSubqueriesInIns() { logMsg("Calling DatabaseMetaData.supportsSubqueriesInIns"); bool retValue=dbmd->supportsSubqueriesInIns(); if (retValue) { logMsg("supportsSubqueriesInIns is supported"); } else { logMsg("supportsSubqueriesInIns is not supported"); } } /* * @testName: testSupportsSubqueriesInQuantifieds * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInQuantifieds() method must return a * boolean value; true if the database supports subqueries in * quantified statement and false otherwise. A JDBC Compliant driver * always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInQuantifieds() method on that object. * It should return a boolean value either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsSubqueriesInQuantifieds() { logMsg("Calling DatabaseMetaData.supportsSubqueriesInQuantifieds"); bool retValue=dbmd->supportsSubqueriesInQuantifieds(); if (retValue) { logMsg("supportsSubqueriesInQuantifieds is supported"); } else { logMsg("supportsSubqueriesInQuantifieds is not supported"); } } /* * @testName: testSupportsTableCorrelationNames * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTableCorrelationNames() method must return * a boolean value; true if the database supports table * correlation names and false otherwise. A JDBC compliant * driver always return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsTableCorrelationNames() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTableCorrelationNames() { logMsg("Calling supportsTableCorrelationNames on DatabaseMetaData"); bool retValue=dbmd->supportsTableCorrelationNames(); if (retValue) { logMsg("supportsTableCorrelationNames method is supported"); } else { logMsg("supportsTableCorrelationNames method is not supported"); } } /* * @testName: testSupportsTransactionIsolationLevel1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with the isolation level TRANSACTION_NONE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTransactionIsolationLevel1() { logMsg( "Calling DatabaseMetaData.supportsTransactionIsolationLevel(sql::TRANSACTION_NONE)"); bool retValue=dbmd->supportsTransactionIsolationLevel(sql::TRANSACTION_NONE); if (retValue) { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_NONE) is supported"); } else { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_NONE) is not supported"); } } /* * @testName: testSupportsTransactionIsolationLevel2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with the isolation level TRANSACTION_READ_COMMITTED. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTransactionIsolationLevel2() { logMsg( "Calling DatabaseMetaData.supportsTransactionIsolationLevel(sql::TRANSACTION_READ_COMMITTED)"); bool retValue=dbmd->supportsTransactionIsolationLevel(sql::TRANSACTION_READ_COMMITTED); if (retValue) { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_READ_COMMITTED) is supported"); } else { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_READ_COMMITTED) is not supported"); } } /* * @testName: testSupportsTransactionIsolationLevel3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with the isolation level TRANSACTION_READ_UNCOMMITTED. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTransactionIsolationLevel3() { logMsg( "Calling DatabaseMetaData.supportsTransactionIsolationLevel(sql::TRANSACTION_READ_UNCOMMITTED)"); bool retValue=dbmd->supportsTransactionIsolationLevel(sql::TRANSACTION_READ_UNCOMMITTED); if (retValue) { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_READ_UNCOMMITTED) is supported"); } else { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_READ_UNCOMMITTED ) is not supported"); } } /* * @testName: testSupportsTransactionIsolationLevel4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with isolation level TRANSACTION_REPEATABLE_READ. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTransactionIsolationLevel4() { logMsg( "Calling DatabaseMetaData.supportsTransactionIsolationLevel(sql::TRANSACTION_REPEATABLE_READ)"); bool retValue=dbmd->supportsTransactionIsolationLevel(sql::TRANSACTION_REPEATABLE_READ); if (retValue) { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_REPEATABLE_READ) is supported"); } else { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_REPEATABLE_READ) is not supported"); } } /* * @testName: testSupportsTransactionIsolationLevel5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with isolation level TRANSACTION_SERIALIZABLE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTransactionIsolationLevel5() { logMsg( "Calling DatabaseMetaData.supportsTransactionIsolationLevel(sql::TRANSACTION_SERIALIZABLE)"); bool retValue=dbmd->supportsTransactionIsolationLevel(sql::TRANSACTION_SERIALIZABLE); if (retValue) { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_SERIALIZABLE) is supported"); } else { logMsg( "supportsTransactionIsolationLevel(sql::TRANSACTION_SERIALIZABLE) is not supported"); } } /* * @testName: testSupportsTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactions() method must return a boolean * value; true if transactions are supported and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactions() method. * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsTransactions() { logMsg("Calling DatabaseMetaData.supportsTransactions"); bool retValue=dbmd->supportsTransactions(); if (retValue) { logMsg("supportsTransactions is supported"); } else { logMsg("supportsTransactions is not supported"); } } /* * @testName: testSupportsUnion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsUnion() method must return a boolean value; * true if the database supports SQL Union and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsUnion() method on that object. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsUnion() { logMsg("Calling DatabaseMetaData.supportsUnion"); bool retValue=dbmd->supportsUnion(); if (retValue) { logMsg("supportsUnion is supported"); } else { logMsg("supportsUnion is not supported"); } } /* * @testName: testSupportsUnionAll * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsUnionAll() method must return a boolean value * true if the database supports SQL Union All and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsUnionAll() method on that object. * It should return a boolean value; eithet true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testSupportsUnionAll() { logMsg("Calling DatabaseMetaData.supportsUnionAll"); bool retValue=dbmd->supportsUnionAll(); if (retValue) { logMsg("supportsUnionAll is supported"); } else { logMsg("supportsUnionAll is not supported"); } } /* * @testName: testUpdatesAreDetected1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The updatesAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowUpdated returns * true when called on a ResultSet object with a given type that * contains visible row updates; false if the method * ResultSet.rowUpdated returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the updatesAreDetected() method on that object with the * ResultSet Type as sql::ResultSet::TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testUpdatesAreDetected1() { logMsg( "Calling DatabaseMetaData.updatesAreDetected(TYPE_FORWARD_ONLY)"); bool retValue=dbmd->updatesAreDetected(sql::ResultSet::TYPE_FORWARD_ONLY); if (retValue) { logMsg( "Visible row update can be detected for TYPE_FORWARD_ONLY"); } else { logMsg( "Visible row update cannot be detected for TYPE_FORWARD_ONLY"); } } /* * @testName: testUpdatesAreDetected2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The updatesAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowUpdated returns * true when called on a ResultSet object with a given type that * contains visible row updates; false if the method * ResultSet.rowUpdated returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the updatesAreDetected() method on that object with the * ResultSet Type as sql::ResultSet::TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testUpdatesAreDetected2() { logMsg( "Calling DatabaseMetaData.updatesAreDetected(TYPE_SCROLL_INSENSITIVE)"); bool retValue=dbmd->updatesAreDetected(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); if (retValue) { logMsg( "Visible row update can be detected for TYPE_SCROLL_INSENSITIVE"); } else { logMsg( "Visible row update cannot be detected for TYPE_SCROLL_INSENSITIVE"); } } /* * @testName: testUpdatesAreDetected3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The updatesAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowUpdated returns * true when called on a ResultSet object with a given type that * contains visible row updates; false if the method * ResultSet.rowUpdated returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the updatesAreDetected() method on that object with the * ResultSet Type as sql::ResultSet::TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws Exception */ void DatabaseMetaDataTest::testUpdatesAreDetected3() { logMsg( "Calling DatabaseMetaData.updatesAreDetected(TYPE_SCROLL_SENSITIVE)"); bool retValue=dbmd->updatesAreDetected(sql::ResultSet::TYPE_SCROLL_SENSITIVE); if (retValue) { logMsg( "Visible row update can be detected for TYPE_SCROLL_SENSITIVE"); } else { logMsg( "Visible row update cannot be detected for TYPE_SCROLL_SENSITIVE"); } } /* * @testName: testUsesLocalFilePerTable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The usesLocalFilePerTable method must return a boolean value; * true if the database uses a local file for each table. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the usesLocalFilePerTable() method * It should return a boolean value * */ /* throws Exception */ void DatabaseMetaDataTest::testUsesLocalFilePerTable() { logMsg("Calling usesLocalFilePerTable on DatabaseMetaData"); bool retValue=dbmd->usesLocalFilePerTable(); if (retValue) { logMsg( "usesLocalFilePerTable method returns database uses a local file"); } else { logMsg( "usesLocalFilePerTable method returns database not uses a local file"); } } /** * @see junit.framework.TestCase#setUp() */ /* throws Exception */ void DatabaseMetaDataTest::setUp() { super::setUp(); sPtable="CTSTABLE1"; Properties::const_iterator cit=sqlProps.find("ptable"); if (cit != sqlProps.end()) sPtable=cit->second; sFtable="CTSTABLE2"; cit=sqlProps.find("ftable"); if (cit != sqlProps.end()) sFtable=cit->second; if (sPtable.length() == 0) { FAIL("Invalid Primary table"); } if (sFtable.length() == 0) { FAIL("Invalid Foreign table"); } sSchemaName=""; dbmd= conn->getMetaData(); } /* A private method to compare the Column Names & No of Columns Specific to the test */ /* throws SQLException */ bool DatabaseMetaDataTest::columnCompare(List & sColumnNames, ResultSet & rset) { bool test_status= false; bool statusColumnCount= true; bool statusColumnMatch= true; int iColumnNamesLength= static_cast(sColumnNames.size()); ResultSetMetaData rsmd(rset->getMetaData()); int iCount=rsmd->getColumnCount(); TestsListener::messagesLog() << "Minimum Column Count is:" << iColumnNamesLength << std::endl; if (iColumnNamesLength <= iCount) { iCount=iColumnNamesLength; statusColumnCount=true; logMsg("Different numbers of columns"); } else { statusColumnCount=false; } logMsg("Comparing Column Names..."); while (iColumnNamesLength > 0) { if (ciString(sColumnNames[iColumnNamesLength - 1].c_str()) == rsmd->getColumnName(iCount).c_str()) { statusColumnMatch=true; } else { statusColumnMatch=false; logMsg("Wrong column value, dumping expected and returned data"); logMsg(sColumnNames[iColumnNamesLength - 1]); logMsg(rsmd->getColumnName(iCount)); break; } iCount--; iColumnNamesLength--; } if ((statusColumnCount == true) && (statusColumnMatch == true)) { test_status=true; } return test_status; } } // namespace compliance } // namespace testsuite mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/DatabaseMetaDataTest.h000644 015771 000012 00001267507 12645244437 030241 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" #include "cppconn/connection.h" #include "cppconn/metadata.h" #include "cppconn/resultset.h" #include "cppconn/resultset_metadata.h" #include "cppconn/exception.h" //#include javax.sql.DataSource /** * @author mmatthew * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ namespace testsuite { namespace compliance { class DatabaseMetaDataTest : public BaseTestFixture { private: typedef BaseTestFixture super; DatabaseMetaData dbmd; //DataSource ds1; String dbName; String dbUser; String drManager; String sCatalogName; String sFtable; String sPtable; String sSchemaName; /* A method to compare the Column Names & No of Columns Specific to the test */ /* throws sql::DbcException */ bool columnCompare(List & sColumnNames, ResultSet & rs); protected: /** * @see junit.framework.TestCase#setUp() */ /* throws std::exception * */ void setUp(); public: TEST_FIXTURE(DatabaseMetaDataTest) { TEST_CASE(testAllProceduresAreCallable); TEST_CASE(testAllTablesAreSelectable); TEST_CASE(testDataDefinitionCausesTransactionCommit); TEST_CASE(testDataDefinitionIgnoredInTransactions); TEST_CASE(testDeletesAreDetected1); TEST_CASE(testDeletesAreDetected2); TEST_CASE(testDeletesAreDetected3); TEST_CASE(testDoesMaxRowSizeIncludeBlobs); TEST_CASE(testGetBestRowIdentifier1); TEST_CASE(testGetBestRowIdentifier2); TEST_CASE(testGetBestRowIdentifier3); TEST_CASE(testGetBestRowIdentifier4); TEST_CASE(testGetBestRowIdentifier5); TEST_CASE(testGetBestRowIdentifier6); TEST_CASE(testGetBestRowIdentifier7); TEST_CASE(testGetCatalogSeparator); TEST_CASE(testGetCatalogTerm); TEST_CASE(testGetCatalogs); TEST_CASE(testGetColumnPrivileges); TEST_CASE(testGetColumns); TEST_CASE(testGetCrossReference); TEST_CASE(testGetDatabaseProductName); TEST_CASE(testGetDatabaseProductVersion); TEST_CASE(testGetDefaultTransactionIsolation); TEST_CASE(testGetDriverMajorVersion); TEST_CASE(testGetDriverMinorVersion); TEST_CASE(testGetDriverName); TEST_CASE(testGetDriverVersion); TEST_CASE(testGetExportedKeys); TEST_CASE(testGetExtraNameCharacters); TEST_CASE(testGetIdentifierQuoteString); TEST_CASE(testGetImportedKeys); TEST_CASE(testGetIndexInfo1); TEST_CASE(testGetIndexInfo2); TEST_CASE(testGetIndexInfo3); TEST_CASE(testGetIndexInfo4); TEST_CASE(testGetIndexInfo5); TEST_CASE(testGetMaxBinaryLiteralLength); TEST_CASE(testGetMaxCatalogNameLength); TEST_CASE(testGetMaxCharLiteralLength); TEST_CASE(testGetMaxColumnNameLength); TEST_CASE(testGetMaxColumnsInGroupBy); TEST_CASE(testGetMaxColumnsInIndex); TEST_CASE(testGetMaxColumnsInOrderBy); TEST_CASE(testGetMaxColumnsInSelect); TEST_CASE(testGetMaxColumnsInTable); TEST_CASE(testGetMaxConnections); TEST_CASE(testGetMaxCursorNameLength); TEST_CASE(testGetMaxIndexLength); TEST_CASE(testGetMaxProcedureNameLength); TEST_CASE(testGetMaxRowSize); TEST_CASE(testGetMaxSchemaNameLength); TEST_CASE(testGetMaxStatementLength); TEST_CASE(testGetMaxStatements); TEST_CASE(testGetMaxTableNameLength); TEST_CASE(testGetMaxTablesInSelect); TEST_CASE(testGetMaxUserNameLength); TEST_CASE(testGetNumericFunctions); TEST_CASE(testGetPrimaryKeys); TEST_CASE(testGetProcedureTerm); TEST_CASE(testGetProcedures); TEST_CASE(testGetSQLKeywords); TEST_CASE(testGetSchemaTerm); TEST_CASE(testGetSchemas); TEST_CASE(testGetSearchStringEscape); TEST_CASE(testGetStringFunctions); TEST_CASE(testGetSystemFunctions); TEST_CASE(testGetTablePrivileges); TEST_CASE(testGetTableTypes); TEST_CASE(testGetTables); TEST_CASE(testGetTimeDateFunctions); TEST_CASE(testGetTypeInfo); TEST_CASE(testGetUDTs); TEST_CASE(testGetUDTs01); TEST_CASE(testGetUserName); TEST_CASE(testGetVersionColumns); TEST_CASE(testInsertsAreDetected1); TEST_CASE(testInsertsAreDetected2); TEST_CASE(testInsertsAreDetected3); TEST_CASE(testIsCatalogAtStart); TEST_CASE(testIsReadOnly); TEST_CASE(testNullPlusNonNullIsNull); TEST_CASE(testNullsAreSortedAtEnd); TEST_CASE(testNullsAreSortedAtStart); TEST_CASE(testNullsAreSortedHigh); TEST_CASE(testNullsAreSortedLow); TEST_CASE(testOthersDeletesAreVisible1); TEST_CASE(testOthersDeletesAreVisible2); TEST_CASE(testOthersDeletesAreVisible3); TEST_CASE(testOthersInsertsAreVisible1); TEST_CASE(testOthersInsertsAreVisible2); TEST_CASE(testOthersInsertsAreVisible3); TEST_CASE(testOthersUpdatesAreVisible1); TEST_CASE(testOthersUpdatesAreVisible2); TEST_CASE(testOthersUpdatesAreVisible3); TEST_CASE(testOwnDeletesAreVisible1); TEST_CASE(testOwnDeletesAreVisible2); TEST_CASE(testOwnDeletesAreVisible3); TEST_CASE(testOwnInsertsAreVisible1); TEST_CASE(testOwnInsertsAreVisible2); TEST_CASE(testOwnInsertsAreVisible3); TEST_CASE(testOwnUpdatesAreVisible1); TEST_CASE(testOwnUpdatesAreVisible2); TEST_CASE(testOwnUpdatesAreVisible3); TEST_CASE(testStoresLowerCaseIdentifiers); TEST_CASE(testStoresLowerCaseQuotedIdentifiers); TEST_CASE(testStoresMixedCaseIdentifiers); TEST_CASE(testStoresMixedCaseQuotedIdentifiers); TEST_CASE(testStoresUpperCaseIdentifiers); TEST_CASE(testStoresUpperCaseQuotedIdentifiers); TEST_CASE(testSupportsANSI92EntryLevelSQL); TEST_CASE(testSupportsANSI92FullSQL); TEST_CASE(testSupportsANSI92IntermediateSQL); TEST_CASE(testSupportsAlterTableWithAddColumn); TEST_CASE(testSupportsAlterTableWithDropColumn); TEST_CASE(testSupportsBatchUpdates); TEST_CASE(testSupportsCatalogsInDataManipulation); TEST_CASE(testSupportsCatalogsInIndexDefinitions); TEST_CASE(testSupportsCatalogsInPrivilegeDefinitions); TEST_CASE(testSupportsCatalogsInProcedureCalls); TEST_CASE(testSupportsCatalogsInTableDefinitions); TEST_CASE(testSupportsColumnAliasing); TEST_CASE(testSupportsConvert); TEST_CASE(testSupportsConvert01); TEST_CASE(testSupportsConvert02); TEST_CASE(testSupportsConvert03); TEST_CASE(testSupportsConvert04); TEST_CASE(testSupportsConvert05); TEST_CASE(testSupportsConvert06); TEST_CASE(testSupportsConvert07); TEST_CASE(testSupportsConvert08); TEST_CASE(testSupportsConvert09); TEST_CASE(testSupportsConvert10); TEST_CASE(testSupportsConvert11); TEST_CASE(testSupportsConvert12); TEST_CASE(testSupportsConvert13); // TEST_CASE( testSupportsConvert14 ); TEST_CASE(testSupportsConvert15); TEST_CASE(testSupportsConvert16); TEST_CASE(testSupportsConvert17); TEST_CASE(testSupportsConvert18); TEST_CASE(testSupportsConvert19); TEST_CASE(testSupportsConvert20); TEST_CASE(testSupportsConvert21); TEST_CASE(testSupportsConvert22); TEST_CASE(testSupportsConvert23); TEST_CASE(testSupportsConvert24); TEST_CASE(testSupportsConvert25); TEST_CASE(testSupportsConvert26); TEST_CASE(testSupportsConvert27); TEST_CASE(testSupportsConvert28); TEST_CASE(testSupportsConvert29); TEST_CASE(testSupportsConvert30); TEST_CASE(testSupportsConvert31); TEST_CASE(testSupportsConvert32); TEST_CASE(testSupportsConvert33); TEST_CASE(testSupportsConvert34); TEST_CASE(testSupportsConvert35); TEST_CASE(testSupportsConvert36); TEST_CASE(testSupportsConvert37); TEST_CASE(testSupportsCoreSQLGrammar); TEST_CASE(testSupportsCorrelatedSubqueries); TEST_CASE(testSupportsDataDefinitionAndDataManipulationTransactions); TEST_CASE(testSupportsDataManipulationTransactionsOnly); TEST_CASE(testSupportsDifferentTableCorrelationNames); TEST_CASE(testSupportsExpressionsInOrderBy); TEST_CASE(testSupportsExtendedSQLGrammar); TEST_CASE(testSupportsFullOuterJoins); TEST_CASE(testSupportsGroupBy); TEST_CASE(testSupportsGroupByBeyondSelect); TEST_CASE(testSupportsGroupByUnrelated); TEST_CASE(testSupportsLikeEscapeClause); TEST_CASE(testSupportsLimitedOuterJoins); TEST_CASE(testSupportsMinimumSQLGrammar); TEST_CASE(testSupportsMixedCaseIdentifiers); TEST_CASE(testSupportsMixedCaseQuotedIdentifiers); TEST_CASE(testSupportsMultipleResultSets); TEST_CASE(testSupportsMultipleTransactions); TEST_CASE(testSupportsNonNullableColumns); TEST_CASE(testSupportsOpenCursorsAcrossCommit); TEST_CASE(testSupportsOpenCursorsAcrossRollback); TEST_CASE(testSupportsOpenStatementsAcrossCommit); TEST_CASE(testSupportsOpenStatementsAcrossRollback); TEST_CASE(testSupportsOrderByUnrelated); TEST_CASE(testSupportsOuterJoins); TEST_CASE(testSupportsPositionedDelete); TEST_CASE(testSupportsPositionedUpdate); TEST_CASE(testSupportsResultSetType1); TEST_CASE(testSupportsResultSetType2); TEST_CASE(testSupportsResultSetType3); TEST_CASE(testSupportsSchemasInDataManipulation); TEST_CASE(testSupportsSchemasInIndexDefinitions); TEST_CASE(testSupportsSchemasInPrivilegeDefinitions); TEST_CASE(testSupportsSchemasInProcedureCalls); TEST_CASE(testSupportsSchemasInTableDefinitions); TEST_CASE(testSupportsSelectForUpdate); TEST_CASE(testSupportsStoredProcedures); TEST_CASE(testSupportsSubqueriesInComparisons); TEST_CASE(testSupportsSubqueriesInExists); TEST_CASE(testSupportsSubqueriesInIns); TEST_CASE(testSupportsSubqueriesInQuantifieds); TEST_CASE(testSupportsTableCorrelationNames); TEST_CASE(testSupportsTransactionIsolationLevel1); TEST_CASE(testSupportsTransactionIsolationLevel2); TEST_CASE(testSupportsTransactionIsolationLevel3); TEST_CASE(testSupportsTransactionIsolationLevel4); TEST_CASE(testSupportsTransactionIsolationLevel5); TEST_CASE(testSupportsTransactions); TEST_CASE(testSupportsUnion); TEST_CASE(testSupportsUnionAll); TEST_CASE(testUpdatesAreDetected1); TEST_CASE(testUpdatesAreDetected2); TEST_CASE(testUpdatesAreDetected3); TEST_CASE(testUsesLocalFilePerTable); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS TEST_CASE(testGetProcedureColumns); TEST_CASE(testGetURL); TEST_CASE(testSupportsIntegrityEnhancementFacility); TEST_CASE(testSupportsResultSetConcurrency1); TEST_CASE(testSupportsResultSetConcurrency2); TEST_CASE(testSupportsResultSetConcurrency3); TEST_CASE(testSupportsResultSetConcurrency4); TEST_CASE(testSupportsResultSetConcurrency5); TEST_CASE(testSupportsResultSetConcurrency6); #endif dbmd= NULL; dbName=""; dbUser=""; drManager=""; sCatalogName=""; sFtable=""; sPtable=""; // ds1 (NULL), sSchemaName=""; } /* * @testName: testAllProceduresAreCallable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The allProceduresAreCallable method must return a boolean value; * true if the user has the security rights of calling all the * procedures returned by the method getProcedures and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the allProceduresAreCallable() method * It should return a boolean value * */ /* throws std::exception * */ void testAllProceduresAreCallable(); /* * @testName: testAllTablesAreSelectable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave * as specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The allTablesAreSelectable method must return a boolean value; * true if the user can use a SELECT statement with all the * tables returned by the method getTables and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the allTablesAreSelectable() method * It should return a boolean value * */ /* throws std::exception * */ void testAllTablesAreSelectable(); /* * @testName: testDataDefinitionCausesTransactionCommit * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The dataDefinitionCausesTransactionCommit() method must return * a boolean value; true if the data definition statement within a * transaction is forced the transaction to commit and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the dataDefinitionCausesTransactionCommit() method. * It should return a boolean value * */ /* throws std::exception * */ void testDataDefinitionCausesTransactionCommit(); /* * @testName: testDataDefinitionIgnoredInTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The dataDefinitionIgnoredInTransactions() method must return a * boolean value; true if a data definition statement within a * transaction is ignored and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the dataDefinitionIgnoredInTransactions() method. * It should return a boolean value * */ /* throws std::exception * */ void testDataDefinitionIgnoredInTransactions(); /* * @testName: testDeletesAreDetected1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The deletesAreDetected(int resType) method must return a * boolean value; true if changes are detected by the resultset type * and false otherwise. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the deletesAreDetected() method on that object with the * result set type as ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testDeletesAreDetected1(); /* * @testName: testDeletesAreDetected2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The deletesAreDetected(int resType) method must return a * boolean value; true if changes are detected by the resultset type * and false otherwise. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the deletesAreDetected() method on that object with the * result set type as ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testDeletesAreDetected2(); /* * @testName: testDeletesAreDetected3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The deletesAreDetected(int resType) method must return a * boolean value; true if changes are detected by the resultset type * and false otherwise. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the deletesAreDetected() method on that object with the * result set type as ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testDeletesAreDetected3(); /* * @testName: testDoesMaxRowSizeIncludeBlobs * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The doesMaxRowSizeIncludeBlobs() method must return a boolean * value; true if maximum row size includes LONGVARCHAR and * LONGVARBINARY blobs and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the doesMaxRowSizeIncludeBlobs() method. * It should return a boolean value * */ /* throws std::exception * */ void testDoesMaxRowSizeIncludeBlobs(); /* * @testName: testGetBestRowIdentifier1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetBestRowIdentifier1(); /* * @testName: testGetBestRowIdentifier2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetBestRowIdentifier2(); /* * @testName: testGetBestRowIdentifier3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetBestRowIdentifier3(); /* * @testName: testGetBestRowIdentifier4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetBestRowIdentifier4(); /* * @testName: testGetBestRowIdentifier5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetBestRowIdentifier5(); /* * @testName: testGetBestRowIdentifier6 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object * */ /* throws std::exception * */ void testGetBestRowIdentifier6(); /* * @testName: testGetBestRowIdentifier7 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getBestRowIdentifier(Str cat, Str sch, Str tab,int scope, boo nflg) * method must return a ResultSet object with each row is a * description of a column that belongs to a optimal set of columns * that uniquely identifies a row. The possible values for scope * are bestRowTemporary, bestRowTransaction or bestRowSession * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getBestRowIdentifier() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetBestRowIdentifier7(); /* * @testName: testGetCatalogSeparator * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCatalogSeparator() method must return a String value * representing the separator string. (See JDK 1.2.2 API * documentation) * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.getCatalogSeparator() on that object. * It should return a String and NULL if it is not supported. * */ /* throws std::exception * */ void testGetCatalogSeparator(); /* * @testName: testGetCatalogTerm * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCatalogTerm() method must return a String object containing * the vendor term for "catalog". (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getCatalogTerm() method on that object. * It should return a String and NULL if it cannot be returned. * */ /* throws std::exception * */ void testGetCatalogTerm(); /* * @testName: testGetCatalogs * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCatalogs() method must return a ResultSet object with each * row representing a catalog name available in the database. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getCatalogs() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetCatalogs(); /* * @testName: testGetColumnPrivileges * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * getColumnPrivileges(String ctlg,String sch,String tab,String colpat) * method must return a ResultSet object with each row is a * description of a column's privileges. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getColumnPrivileges() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetColumnPrivileges(); /* * @testName: testGetColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getColumns(String clg,String schp,String tnpat,String colNamepat) * method must return a ResultSet object with each row is a * description of a table column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getColumns() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetColumns(); /* * @testName: testGetCrossReference * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getCrossReference(Str prcalg,Str prsch,Str prtab,Str foclg,Str fosch,Str fotab) * method must return a ResultSet object with each row is a * description of a foreign key column in a foreign key table. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getCrossReference() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetCrossReference(); /* * @testName: testGetDatabaseProductName * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDatabaseProductName method must return a String object * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDatabaseProductName() method * It should return a String * */ /* throws std::exception * */ void testGetDatabaseProductName(); /* * @testName: testGetDatabaseProductVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDatabaseProductVersion method must return a String object * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDatabaseProductVersion() method * It should return a String * */ /* throws std::exception * */ void testGetDatabaseProductVersion(); /* * @testName: testGetDefaultTransactionIsolation * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getDefaultTransactionIsolation() method must return an integer * value; the value representing the default Transaction Isolation. * The value can be any one of the following TRANSACTION_NONE, * TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getDefaultTransactionIsolation() method. * It should return an integer value * */ /* throws std::exception * */ void testGetDefaultTransactionIsolation(); /* * @testName: testGetDriverMajorVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverMajorVersion method must return a integer value * representing the driver major version. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverMajorVersion() method * It should return a Integer value * */ /* throws std::exception * */ void testGetDriverMajorVersion(); /* * @testName: testGetDriverMinorVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverMinorVersion method must return a integer value * representing the driver major version. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverMinorVersion() method * It should return a Integer value * */ /* throws std::exception * */ void testGetDriverMinorVersion(); /* * @testName: testGetDriverName * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverName method must return a String object * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverName() method * It should return a String * */ /* throws std::exception * */ void testGetDriverName(); /* * @testName: testGetDriverVersion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getDriverVersion method must return a String object * representing the driver version including its major and minor * version numbers. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getDriverVersion() method * It should return a String * */ /* throws std::exception * */ void testGetDriverVersion(); /* * @testName: testGetExportedKeys * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getExportedKeys(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of a foreign key that reference a table's primary * key columns. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getExportedKeys() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetExportedKeys(); /* * @testName: testGetExtraNameCharacters * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getExtraNameCharacters() method must return a String object * containing the extra characters; (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getExtraNameCharacters() method * It should return a String * */ /* throws std::exception * */ void testGetExtraNameCharacters(); /* * @testName: testGetIdentifierQuoteString * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIdentifierQuoteString() method must return a String * object representing the quoting string or a space if the database * does not support quoting identifiers. A JDBC Compliant driver * always uses a double quote character ("). (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getIdentifierQuoteString() method * It should return a String * */ /* throws std::exception * */ void testGetIdentifierQuoteString(); /* * @testName: testGetImportedKeys * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getImportedKeys(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of a primary key columns that are referenced by a * table's foreign key columns. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getImportedKeys() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetImportedKeys(); /* * @testName: testGetIndexInfo1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetIndexInfo1(); /* * @testName: testGetIndexInfo2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetIndexInfo2(); /* * @testName: testGetIndexInfo3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetIndexInfo3(); /* * @testName: testGetIndexInfo4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * */ /* throws std::exception * */ void testGetIndexInfo4(); /* * @testName: testGetIndexInfo5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getIndexInfo(Str calg,Str sch,Str tab,boolean uni,boolean approx) * method must return a ResultSet object with each row is a * description of an index column. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getIndexInfo() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetIndexInfo5(); /* * @testName: testGetMaxBinaryLiteralLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxBinaryLiteralLength() method must return a integer * value; the value representing the maximum number of hex * characters; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxBinaryLiteralLength() method on that object. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxBinaryLiteralLength(); /* * @testName: testGetMaxCatalogNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxCatalogNameLength() method must return an integer * value; the value representing the maximum catalog name length * that is allowed; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxCatalogNameLength() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxCatalogNameLength(); /* * @testName: testGetMaxCharLiteralLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxCharLiteralLength() method must return a integer * value; the value representing the maximum number of * characters; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxCharLiteralLength() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxCharLiteralLength(); /* * @testName: testGetMaxColumnNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnNameLength() method must return a integer * value; the value representing the maximum number of * characters allowed as column name length; 0 if there is no limit * or the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnNameLength() method on that object. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxColumnNameLength(); /* * @testName: testGetMaxColumnsInGroupBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInGroupBy() method must return a integer * value; the value representing the maximum number of * columns in a GROUP BY clause; 0 if there is no limit or * the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInGroupBy() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxColumnsInGroupBy(); /* * @testName: testGetMaxColumnsInIndex * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInIndex() method must return a integer * value; the value representing the maximum number of * columns in Index; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInIndex() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxColumnsInIndex(); /* * @testName: testGetMaxColumnsInOrderBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInOrderBy() method must return a integer * value; the value representing the maximum number of columns * in a ORDER BY clause; 0 if there is no limit or the limit is * unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInOrderBy() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxColumnsInOrderBy(); /* * @testName: testGetMaxColumnsInSelect * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInSelect() method must return a integer * value; the value representing the maximum number of columns in * a SELECT list; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInSelect() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxColumnsInSelect(); /* * @testName: testGetMaxColumnsInTable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxColumnsInTable() method must return a integer * value; the value representing the maximum number of columns * in a Table; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxColumnsInTable() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxColumnsInTable(); /* * @testName: testGetMaxConnections * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxConnections() method must return a integer * value; the value representing the maximum number of active * connections at a time in a database; 0 if there is no limit or * the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxConnections() method on that object. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxConnections(); /* * @testName: testGetMaxCursorNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxCursorNameLength() method must return a integer * value; the value representing the maximum cursor name length * in bytes; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxCursorNameLength() method on that object. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxCursorNameLength(); /* * @testName: testGetMaxIndexLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxIndexLength() method must return a integer * value; the value representing the maximum index length in * bytes; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxIndexLength() method on that object. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxIndexLength(); /* * @testName: testGetMaxProcedureNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxProcedureNameLength() method must return a integer * value; the value representing the maximum procedure name length * that is allowed; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxProcedureNameLength() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxProcedureNameLength(); /* * @testName: testGetMaxRowSize * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxRowSize() method must return a integer * value; the value representing the maximum length of a single row * in bytes; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxRowSize() method on that object. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxRowSize(); /* * @testName: testGetMaxSchemaNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxSchemaNameLength() method must return a integer * value; the value representing the maximum schema name length that * is allowed; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxSchemaNameLength() method on that object. * It should return an integer value. * */ /* throws std::exception * */ void testGetMaxSchemaNameLength(); /* * @testName: testGetMaxStatementLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxStatementLength() method must return an integer * value; the value representing the maximum number of characters * allowed in SQL statement; 0 if there is no limit or the limit is * unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxStatementLength() method. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxStatementLength(); /* * @testName: testGetMaxStatements * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxStatements method must return an integer * value; the value representing the maximum number of statements * that can be open at one time to the database; 0 if there is no limit * or the limit is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxStatements() method. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxStatements(); /* * @testName: testGetMaxTableNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxTableNameLength() method must return an integer * value; the value representing the maximum number of characters * allowed in a table name; 0 if there is no limit or the limit * is unknown. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxTableNameLength() method. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxTableNameLength(); /* * @testName: testGetMaxTablesInSelect * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxTablesInSelect() method must return an integer * value; the value representing the maximum number of tables in * SELECT clause; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxTablesInSelect() method. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxTablesInSelect(); /* * @testName: testGetMaxUserNameLength * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getMaxUserNameLength() method must return an integer * value; the value representing the maximum of characters allowed * in a user name; 0 if there is no limit or the limit is unknown. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getMaxUserNameLength() method. * It should return an integer value * */ /* throws std::exception * */ void testGetMaxUserNameLength(); /* * @testName: testGetNumericFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getNumericFunctions() method must return a String object * that is a comma separated list of math functions; These are * the X/Open CLI math function names used in the JDBC function * escape clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getNumericFunctions() method * It should return a String * */ /* throws std::exception * */ void testGetNumericFunctions(); /* * @testName: testGetPrimaryKeys * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getPrimaryKeys(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of the given table's primary key column(s). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getPrimaryKeys() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetPrimaryKeys(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetProcedureColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getProcedureColumns(Str ctlg,Str schp,String prp,String colpa) * method must return a ResultSet object with each row describes * the information like parameter for the stored procedure, * return value of the stored procedure, etc., * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getProcedureColumns() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetProcedureColumns(); #endif /* * @testName: testGetProcedureTerm * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getProcedureTerm() method must return a String object * containing the vendor term for "procedure". (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getProcedureTerm() method on that object. * It should return a String and NULL if it cannot be generated.; * */ /* throws std::exception * */ void testGetProcedureTerm(); /* * @testName: testGetProcedures * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getProcedures(String catg, String schemapat, String procpat) * method must return a ResultSet object where catg is the catalog * name, schemapat is schema pattern and procpat is procedure name * pattern. Each row of the ResultSet is the description of the. * stored procedure. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getProcedures() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetProcedures(); /* * @testName: testGetSQLKeywords * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSQLKeywords() method must return a String object that is * comma separated list of keywords used by the database that are * not also SQL-92 keywords.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSQLKeywords() method * It should return a String * */ /* throws std::exception * */ void testGetSQLKeywords(); /* * @testName: testGetSchemaTerm * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSchemaTerm() method must return a String object representing * the vendor term for "schema". (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSchemaTerm() method on that object. * It should return a String and NULL if it cannot be generated. * */ /* throws std::exception * */ void testGetSchemaTerm(); /* * @testName: testGetSchemas * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSchemas() method must return a ResultSet object, with each row * representing a schema name available in the database * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getSchemas() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetSchemas(); /* * @testName: testGetSearchStringEscape * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSystemFunctions() method must return a String object * used to escape wildcard characters; (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSearchStringEscape() method * It should return a String * */ /* throws std::exception * */ void testGetSearchStringEscape(); /* * @testName: testGetStringFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getStringFunctions() method must return a String object * that is a comma separated list of string functions; These are * the X/Open CLI string function names used in the JDBC function * escape clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getStringFunctions() method * It should return a String * */ /* throws std::exception * */ void testGetStringFunctions(); /* * @testName: testGetSystemFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSystemFunctions() method must return a String object * that is a comma separated list of string functions; These are * the X/Open CLI system function names used in the JDBC function * escape clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getSystemFunctions() method * It should return a String * */ /* throws std::exception * */ void testGetSystemFunctions(); /* * @testName: testGetTablePrivileges * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * getTablePrivileges(String clg,String schpat,String tabnamepat) * method must return a ResultSet object with each row is a * description of the access rights for a table. (See JDK 1.2.2 * API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTablePrivileges() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetTablePrivileges(); /* * @testName: testGetTableTypes * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getTableTypes() method must return a ResultSet object with each * row representing a table type available in the DBMS. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTableTypes() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetTableTypes(); /* * @testName: testGetTables * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getTables() method must return a ResultSet object * with each row is a description of the table * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTables() method. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetTables(); /* * @testName: testGetTimeDateFunctions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getSystemFunctions method must return a String object * that is a comma separated list of time and date functions; * These are the X/Open CLI time and date function names used * in the JDBC function escape clause. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getTimeDateFunctions() method * It should return a String * */ /* throws std::exception * */ void testGetTimeDateFunctions(); /* * @testName: testGetTypeInfo * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getTypeInfo() method must return a ResultSet object with each * row is a description of a local DBMS type. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getTypeInfo() method on that object. * It should return a ResultSet object * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetTypeInfo(); /* * @testName: testGetUDTs * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getUDTs() method must return a ResultSet object with each * row is a description of a UDT (User Defined Type). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getUDTs() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetUDTs(); /* * @testName: testGetUDTs01 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getUDTs() method must return a ResultSet object with each * row is a description of a UDT (User Defined Type). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getUDTs() method on that object. * It should return a ResultSet object. * Validate the column names and column ordering. * */ /* throws std::exception * */ void testGetUDTs01(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetURL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave * as specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getURL method must return a String object representing the * URL for the database; null if it cannot be generated. * (See JDK 1.2.2 API documentation). * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getURL() method * It should return a String or null if it cannot be generated * */ /* throws std::exception * */ void testGetURL(); #endif /* * @testName: testGetUserName * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getUserName method must return a String object representing * the Username of the database. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the getUserName() method * It should return a String * */ /* throws std::exception * */ void testGetUserName(); /* * @testName: testGetVersionColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The getVersionColumns(String calg, String sch, String tab) * method must return a ResultSet object with each row is a * description of a table column that is automatically updated * whenever a value in a row is updated. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the getVersionColumns() method on that object. * It should return a ResultSet object.Compare the column names * Validate the column names and column ordering. */ /* throws std::exception * */ void testGetVersionColumns(); /* * @testName: testInsertsAreDetected1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The insertsAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowInserted returns * true when called on a ResultSet object with a given type that * contains visible row insertion; false if the method * ResultSet.rowInserted returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the insertsAreDetected() method on that object with the * result set type as ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either or false. * */ /* throws std::exception * */ void testInsertsAreDetected1(); /* * @testName: testInsertsAreDetected2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The insertsAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowInserted returns * true when called on a ResultSet object with a given type that * contains visible row insertion; false if the method * ResultSet.rowInserted returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the insertsAreDetected() method on that object with the * result set type as ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either or false. * */ /* throws std::exception * */ void testInsertsAreDetected2(); /* * @testName: testInsertsAreDetected3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The insertsAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowInserted returns * true when called on a ResultSet object with a given type that * contains visible row insertion; false if the method * ResultSet.rowInserted returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the insertsAreDetected() method on that object with the * result set type as ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either or false. * */ /* throws std::exception * */ void testInsertsAreDetected3(); /* * @testName: testIsCatalogAtStart * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The isCatalogAtStart() method must return a boolean value; * true if the catalog name appears at the start of a fully * qualified table name; false if it appears at the end. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the isCatalogAtStart() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testIsCatalogAtStart(); /* * @testName: testIsReadOnly * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isReadOnly method must return a boolean value; true if * the database is in read-only mode and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the isReadOnly() method * It should return a boolean value * */ /* throws std::exception * */ void testIsReadOnly(); /* * @testName: testNullPlusNonNullIsNull * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The nullPlusNonNullIsNull() method must return a boolean value; * true if the concatenation of a NULL value and a non-NULL value * results in a NULL value and false otherwise. A JDBC compliant * driver must always return true. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullPlusNonNullIsNull() method * It should return a boolean value * */ /* throws std::exception * */ void testNullPlusNonNullIsNull(); /* * @testName: testNullsAreSortedAtEnd * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedAtEnd method must return a boolean value; * true if NULL values are sorted at the end regardless of the * sort order and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedAtEnd() method * It should return a boolean value * */ /* throws std::exception * */ void testNullsAreSortedAtEnd(); /* * @testName: testNullsAreSortedAtStart * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedAtStart method must return a boolean value; * true if NULL values are sorted at the start regardless of the * sort order and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedAtStart() method * It should return a boolean value * */ /* throws std::exception * */ void testNullsAreSortedAtStart(); /* * @testName: testNullsAreSortedHigh * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedHigh method must return a boolean value; * true if NULL values are sorted high and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedHigh() method * It should return a boolean value * */ /* throws std::exception * */ void testNullsAreSortedHigh(); /* * @testName: testNullsAreSortedLow * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The nullsAreSortedLow method must return a boolean value; * true if NULL values are sorted low and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the nullsAreSortedLow() method * It should return a boolean value * */ /* throws std::exception * */ void testNullsAreSortedLow(); /* * @testName: testOthersDeletesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersDeletesAreVisible(int resType) method must return a * boolean value; true if a rows deleted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherDeletesAreVisible(int resType) method on that * object with ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersDeletesAreVisible1(); /* * @testName: testOthersDeletesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersDeletesAreVisible(int resType) method must return a * boolean value; true if a rows deleted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherDeletesAreVisible(int resType) method on that * object with ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersDeletesAreVisible2(); /* * @testName: testOthersDeletesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersDeletesAreVisible(int resType) method must return a * boolean value; true if a rows deleted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherDeletesAreVisible(int resType) method on that * object with ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersDeletesAreVisible3(); /* * @testName: testOthersInsertsAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersInsertsAreVisible(int resType) method must return a * boolean value; true if a rows inserted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherInsertsAreVisible(int resType) method on that * object with ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersInsertsAreVisible1(); /* * @testName: testOthersInsertsAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersInsertsAreVisible(int resType) method must return a * boolean value; true if a rows inserted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherInsertsAreVisible(int resType) method on that * object with ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersInsertsAreVisible2(); /* * @testName: testOthersInsertsAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersInsertsAreVisible(int resType) method must return a * boolean value; true if a rows inserted by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherInsertsAreVisible(int resType) method on that * object with ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersInsertsAreVisible3(); /* * @testName: testOthersUpdatesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersUpdatesAreVisible(int resType) method must return a * boolean value; true if a rows updated by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherUpdatesAreVisible(int resType) method on that * object with ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersUpdatesAreVisible1(); /* * @testName: testOthersUpdatesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersUpdatesAreVisible(int resType) method must return a * boolean value; true if a rows updated by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherUpdatesAreVisible(int resType) method on that * object with ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersUpdatesAreVisible2(); /* * @testName: testOthersUpdatesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The othersUpdatesAreVisible(int resType) method must return a * boolean value; true if a rows updated by others are visible and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the otherUpdatesAreVisible(int resType) method on that * object with ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOthersUpdatesAreVisible3(); /* * @testName: testOwnDeletesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownDeletesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own deletions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownDeletesAreVisible(int resType) method on that object * with ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnDeletesAreVisible1(); /* * @testName: testOwnDeletesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownDeletesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own deletions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownDeletesAreVisible(int resType) method on that object * with ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnDeletesAreVisible2(); /* * @testName: testOwnDeletesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownDeletesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own deletions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownDeletesAreVisible(int resType) method on that object * with ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnDeletesAreVisible3(); /* * @testName: testOwnInsertsAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownInsertsAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own insertions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownInsertsAreVisible(int resType) method on that object * with ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnInsertsAreVisible1(); /* * @testName: testOwnInsertsAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownInsertsAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own insertions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownInsertsAreVisible(int resType) method on that object * with ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnInsertsAreVisible2(); /* * @testName: testOwnInsertsAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownInsertsAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own insertions are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownInsertsAreVisible(int resType) method on that object * with ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnInsertsAreVisible3(); /* * @testName: testOwnUpdatesAreVisible1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownUpdatesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own updates are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownUpdatesAreVisible(int resType) method on that object * with ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnUpdatesAreVisible1(); /* * @testName: testOwnUpdatesAreVisible2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownUpdatesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own updates are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownUpdatesAreVisible(int resType) method on that object * with ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnUpdatesAreVisible2(); /* * @testName: testOwnUpdatesAreVisible3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The ownUpdatesAreVisible(int resType) method must return a * boolean value; true if a ResultSet object's own updates are * visible without having to close and reopen the result set and * false otherwise. The possible values for resType are * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE and TYPE_SCROLL_SENSITIVE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the ownUpdatesAreVisible(int resType) method on that object * with ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testOwnUpdatesAreVisible3(); /* * @testName: testStoresLowerCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The storesLowerCaseIdentifiers method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-insensitive and stores them as all lowercases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesLowerCaseIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testStoresLowerCaseIdentifiers(); /* * @testName: testStoresLowerCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesLowerCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers * in SQLstatements as case-insensitive and stores them as all * lower cases in its metadata tables and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesLowerCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testStoresLowerCaseQuotedIdentifiers(); /* * @testName: testStoresMixedCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesMixedCaseIdentifiers() method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-insensitive and stores them as all mixed cases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesMixedCaseIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testStoresMixedCaseIdentifiers(); /* * @testName: testStoresMixedCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesMixedCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers in SQL * statements as case-insensitive and stores them as all mixed cases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesMixedCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testStoresMixedCaseQuotedIdentifiers(); /* * @testName: testStoresUpperCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The storesUpperCaseIdentifiers method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-insensitive and stores them as all uppercases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesUpperCaseIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testStoresUpperCaseIdentifiers(); /* * @testName: testStoresUpperCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The storesUpperCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers in SQL * statements as case-insensitive and stores them as all upper cases * in its metadata tables and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the storesUpperCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testStoresUpperCaseQuotedIdentifiers(); /* * @testName: testSupportsANSI92EntryLevelSQL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsANSI92EntryLevelSQL() method must return a boolean * value; true if the database supports ANSI92 entry level SQL * grammar and false otherwise. All JDBC Compliant drivers must * return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsANSI92EntryLevelSQL() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsANSI92EntryLevelSQL(); /* * @testName: testSupportsANSI92FullSQL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsANSI92FullSQL() method must return a boolean value * true if the database supports ANSI92 Full SQL grammar and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsANSI92FullSQL() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsANSI92FullSQL(); /* * @testName: testSupportsANSI92IntermediateSQL * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsANSI92IntermediateSQL() method must return a boolean * value; true if the database supports ANSI92 Intermediate SQL * grammar and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsANSI92IntermediateSQL() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsANSI92IntermediateSQL(); /* * @testName: testSupportsAlterTableWithAddColumn * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsAlterTableWithAddColumn() method must return a * boolean value; true if the database supports ALTER TABLE * with add Column and false otherwise (See JDK 1.2.2 API * documentation). * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsAlterTableWithAddColumn() method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsAlterTableWithAddColumn(); /* * @testName: testSupportsAlterTableWithDropColumn * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsAlterTableWithDropColumn() method must return a * boolean value; true if the database supports ALTER TABLE * with drop column and false otherwise (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsAlterTableWithDropColumn() method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsAlterTableWithDropColumn(); /* * @testName: testSupportsBatchUpdates * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsBatchUpdates() method must return a boolean * value; true if the driver supports batch updates and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsBatchUpdates() method. * It should return a boolean value * */ /* throws std::exception * */ void testSupportsBatchUpdates(); /* * @testName: testSupportsCatalogsInDataManipulation * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInDataManipulation() method must return a * boolean value; true if the database supports using a catalog name * in a data manipulation statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsCatalogsInDataManipulation()on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsCatalogsInDataManipulation(); /* * @testName: testSupportsCatalogsInIndexDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInIndexDefinitions() method must return a * boolean value; true if the database supports using a catalog name * in a index definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * Call the supportsCatalogsInIndexDefinitions() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsCatalogsInIndexDefinitions(); /* * @testName: testSupportsCatalogsInPrivilegeDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInPrivilegeDefinitions() method must return a * boolean value; true if the database supports using a catalog name * in a privilege definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsCatalogsInPrivilegeDefinitions() method on that * object. It should return a boolean value; either true or false * */ /* throws std::exception * */ void testSupportsCatalogsInPrivilegeDefinitions(); /* * @testName: testSupportsCatalogsInProcedureCalls * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInProcedureCalls() method must return a * boolean value; true if the database supports using a catalog name * in a procedure call statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsCatalogsInProcedureCalls() on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsCatalogsInProcedureCalls(); /* * @testName: testSupportsCatalogsInTableDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCatalogsInTableDefinitions() method must return a * boolean value; true if the database supports using a catalog name * in a table definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * Call the supportsCatalogsInTableDefinitions() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsCatalogsInTableDefinitions(); /* * @testName: testSupportsColumnAliasing * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsColumnAliasing() method must return a * boolean value; true if the database supports column aliasing * and false otherwise. A JDBC compliant driver must always return * true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsColumnAliasing() method * It should return a true value * */ /* throws std::exception * */ void testSupportsColumnAliasing(); /* * @testName: testSupportsConvert * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert() method must return a boolean value; * true if the database supports the scalar function CONVERT for * for the conversion of one JDBC type to another and false * otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert() method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsConvert(); /* * @testName: testSupportsConvert01 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(ARRAY, VARCHAR) method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsConvert01(); /* * @testName: testSupportsConvert02 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIGINT, VARCHAR) method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsConvert02(); /* * @testName: testSupportsConvert03 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BINARY, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert03(); /* * @testName: testSupportsConvert04 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation). * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert04(); /* * @testName: testSupportsConvert05 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BLOB, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert05(); /* * @testName: testSupportsConvert06 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(CHAR, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert06(); /* * @testName: testSupportsConvert07 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(CLOB, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert07(); /* * @testName: testSupportsConvert08 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DATE, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert08(); /* * @testName: testSupportsConvert09 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DECIMAL, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert09(); /* * @testName: testSupportsConvert10 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DISTINCT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert10(); /* * @testName: testSupportsConvert11 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DOUBLE, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert11(); /* * @testName: testSupportsConvert12 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(FLOAT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert12(); /* * @testName: testSupportsConvert13 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(INTEGER, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert13(); /* * @testName: testSupportsConvert15 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(LONGVARBINARY, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert15(); /* * @testName: testSupportsConvert16 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(LONGVARCHAR, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert16(); /* * @testName: testSupportsConvert17 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(NULL, VARCHAR) on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert17(); /* * @testName: testSupportsConvert18 * @assertion: The DatabaseMetaData provides information about the database * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(NUMERIC, VARCHAR) method on that object * It should return a boolean value; either true or false * */ /* throws std::exception * */ void testSupportsConvert18(); /* * @testName: testSupportsConvert19 * @assertion: The DatabaseMetaData provides information about the database * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(OTHER, VARCHAR) method on that object * It should return a boolean value; either true or false * */ /* throws std::exception * */ void testSupportsConvert19(); /* * @testName: testSupportsConvert20 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(REAL, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert20(); /* * @testName: testSupportsConvert21 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(REF, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert21(); /* * @testName: testSupportsConvert22 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(SMALLINT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert22(); /* * @testName: testSupportsConvert23 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(STRUCT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert23(); /* * @testName: testSupportsConvert24 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TIME, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert24(); /* * @testName: testSupportsConvert25 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TIMESTAMP, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert25(); /* * @testName: testSupportsConvert26 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TINYINT, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert26(); /* * @testName: testSupportsConvert27 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(VARBINARY, VARCHAR) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert27(); /* * @testName: testSupportsConvert28 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIGINT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert28(); /* * @testName: testSupportsConvert29 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(BIT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert29(); /* * @testName: testSupportsConvert30 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DATE, INTEGER) method onn that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert30(); /* * @testName: testSupportsConvert31 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DECIMAL, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert31(); /* * @testName: testSupportsConvert32 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(DOUBLE, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert32(); /* * @testName: testSupportsConvert33 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(FLOAT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert33(); /* * @testName: testSupportsConvert34 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(NUMERIC, INTEGER) method on that object. * It should return a boolean value; true or false. * */ /* throws std::exception * */ void testSupportsConvert34(); /* * @testName: testSupportsConvert35 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(REAL, INTEGER) method on that object. * It should return a boolean value; either true false. * */ /* throws std::exception * */ void testSupportsConvert35(); /* * @testName: testSupportsConvert36 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(SMALLINT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert36(); /* * @testName: testSupportsConvert37 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsConvert(int fromType, int toType) method must return * a boolean value; true if the database supports the scalar function * CONVERT for conversions between the JDBC types fromType and toType * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsConvert(TINYINT, INTEGER) method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsConvert37(); /* * @testName: testSupportsCoreSQLGrammar * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCoreSQLGrammar() method must return a boolean value * true if the database supports the ODBC core SQL grammar and * false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsCoreSQLGrammar() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsCoreSQLGrammar(); /* * @testName: testSupportsCorrelatedSubqueries * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsCorrelatedSubqueries() method must return a * boolean value; true if the database supports correlated subqueries * and false otherwise. A JDBC Compliant driver always returns true. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsCorrelatedSubqueries() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsCorrelatedSubqueries(); /* * @testName: testSupportsDataDefinitionAndDataManipulationTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsDataDefinitionAndDataManipulationTransactions method * must return a boolean value; true if both data definition and * data manipulation statements within a transaction are supported; * false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsDataDefinitionAndDataManipulationTransactions() method. * It should return a boolean value * */ /* throws std::exception * */ void testSupportsDataDefinitionAndDataManipulationTransactions(); /* * @testName: testSupportsDataManipulationTransactionsOnly * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsDataManipulationTransactionsOnly() method must return * a boolean value, true if the data manipulation statements within * a transaction is supported and false otherwise. A JDBC Compliant * driver should return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsDataManipulationTransactionsOnly() method. * It should return a boolean value * */ /* throws std::exception * */ void testSupportsDataManipulationTransactionsOnly(); /* * @testName: testSupportsDifferentTableCorrelationNames * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsDifferentTableCorrelationNames() method must return * a boolean value; true if the database supports table * correlation names and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsDifferentTableCorrelationNames() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsDifferentTableCorrelationNames(); /* * @testName: testSupportsExpressionsInOrderBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsExpressionsInOrderBy() method must return * a boolean value; true if the database supports expressions * in ORDER BY lists and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsExpressionsInOrderBy() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsExpressionsInOrderBy(); /* * @testName: testSupportsExtendedSQLGrammar * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsExtendedSQLGrammar() method must return a boolean * value; true if the database supports the ODBC Extended SQL * grammar and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsExtendedSQLGrammar() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsExtendedSQLGrammar(); /* * @testName: testSupportsFullOuterJoins * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsFullOuterJoins() method must return a * boolean value; true if the database supports full nested outer * joins and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsFullOuterJoins() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsFullOuterJoins(); /* * @testName: testSupportsGroupBy * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsGroupBy() method must return a boolean value; * true if the database supports GROUP BY clause * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsGroupBy() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsGroupBy(); /* * @testName: testSupportsGroupByBeyondSelect * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsGroupByBeyondSelect() method must return a boolean * value; true if a GROUP BY clause can use columns that are not * in the SELECT clause. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsGroupByBeyondSelect() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsGroupByBeyondSelect(); /* * @testName: testSupportsGroupByUnrelated * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsGroupByUnrelated() method must return a boolean value; * true if a GROUP BY clause can use columns that are not in the * SELECT clause and false otherwise (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsGroupByUnrelated() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsGroupByUnrelated(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testSupportsIntegrityEnhancementFacility * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsIntegrityEnhancementFacility() method must return a * boolean value; true if the database supports the SQL Integrity * Enhancement Facility and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsIntegrityEnhancementFacility() method onn that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsIntegrityEnhancementFacility(); #endif /* * @testName: testSupportsLikeEscapeClause * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsLikeEscapeClause() method must return a boolean value * true if the database supports specifying a LIKE escape clause * and false otherwise. A JDBC compliant driver always return true. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsLikeEscapeClause() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsLikeEscapeClause(); /* * @testName: testSupportsLimitedOuterJoins * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsLimitedOuterJoins() method must return a * boolean value; true if the database supports limited outer joins * and false otherwise. Note if the method supportsFullOuterJoins * return true, this method will return true. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsLimitedOuterJoins() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsLimitedOuterJoins(); /* * @testName: testSupportsMinimumSQLGrammar * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMinimumSQLGrammar() method must return a boolean * value; true if the database supports the ODBC Minimum SQL * grammar and false otherwise. All JDBC Compliant drivers must * return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMinimumSQLGrammar() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsMinimumSQLGrammar(); /* * @testName: testSupportsMixedCaseIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The supportsMixedCaseIdentifiers method must return a boolean * value; true if DBMS allows mixed case SQL Identifiers in SQL * statements as case-sensitive and false otherwise. A JDBC * compliant driver will always return false. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMixedCaseIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsMixedCaseIdentifiers(); /* * @testName: testSupportsMixedCaseQuotedIdentifiers * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMixedCaseQuotedIdentifiers() method must return a boolean * value; true if DBMS allows mixed case quoted SQL Identifiers in SQL * statements as case-insensitive and stores them as all mixed cases * in its metadata tables and false otherwise. A JDBC Compliant * driver will always return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMixedCaseQuotedIdentifiers() method * It should return a boolean value * */ /* throws std::exception * */ void testSupportsMixedCaseQuotedIdentifiers(); /* * @testName: testSupportsMultipleResultSets * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMultipleResultSets() method must return a boolean value * true if the database supports multiple result sets from a single * execute statement and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMultipleResultSets() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsMultipleResultSets(); /* * @testName: testSupportsMultipleTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsMultipleTransactions() method must return a boolean * value; true if multiple transactions can be open at once on * different connections and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsMultipleTransactions() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsMultipleTransactions(); /* * @testName: testSupportsNonNullableColumns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsNonNullableColumns() method must return a boolean * value; true if the database supports defining columns as * non-nullable and false otherwise. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsNonNullableColumns() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsNonNullableColumns(); /* * @testName: testSupportsOpenCursorsAcrossCommit * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenCursorsAcrossCommit() method must return a boolean * value; true if cursors always remain open after commits; false * if cursors are closed on commit. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenCursorsAcrossCommit() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsOpenCursorsAcrossCommit(); /* * @testName: testSupportsOpenCursorsAcrossRollback * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenCursorsAcrossRollback() method must return a boolean * value; true if cursors always remain open after rollbacks; false * if cursors are closed on rollback. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenCursorsAcrossRollback() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsOpenCursorsAcrossRollback(); /* * @testName: testSupportsOpenStatementsAcrossCommit * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenStatementsAcrossCommit() method must return a * boolean value; true if statements always remain open after * commits; false if statements are closed on commit. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenStatementsAcrossCommit() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsOpenStatementsAcrossCommit(); /* * @testName: testSupportsOpenStatementsAcrossRollback * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOpenStatementsAcrossRollback() method must return a * boolean value; true if statements always remain open after * rollbacks; false if statements are closed on rollback. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsOpenStatementsAcrossRollback() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsOpenStatementsAcrossRollback(); /* * @testName: testSupportsOrderByUnrelated * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOrderByUnrelated() method must return * a boolean value; true if the database supports ORDER BY * clause can use columns that are not in the SELECT clause * and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsOrderByUnrelated() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsOrderByUnrelated(); /* * @testName: testSupportsOuterJoins * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsOuterJoins() method must return a * boolean value; true if the database supports form of outer * joins and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsOuterJoins() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsOuterJoins(); /* * @testName: testSupportsPositionedDelete * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsPositionedDelete() method must return a * boolean value; true if the database supports positioned * DELETE statement and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsPositionedDelete() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsPositionedDelete(); /* * @testName: testSupportsPositionedUpdate * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsPositionedUpdate() method must return a * boolean value; true if the database supports positioned * UPDATE statement and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsPositionedUpdate() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsPositionedUpdate(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testSupportsResultSetConcurrency1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_FORWARD_ONLY and CONCUR_READ_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetConcurrency1(); /* * @testName: testSupportsResultSetConcurrency2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_FORWARD_ONLY and CONCUR_UPDATABLE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetConcurrency2(); /* * @testName: testSupportsResultSetConcurrency3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_INSENSITIVE and CONCUR_READ_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetConcurrency3(); /* * @testName: testSupportsResultSetConcurrency4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_INSENSITIVE and CONCUR_UPDATABLE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetConcurrency4(); /* * @testName: testSupportsResultSetConcurrency5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_SENSITIVE and CONCUR_READ_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetConcurrency5(); /* * @testName: testSupportsResultSetConcurrency6 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetConcurrency(int rsType, int rsConcur) * method must return a boolean value where possible values for rsType * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE * and values for rsConcur can be CONCUR_READ_ONLY and * CONCUR_UPDATABLE. The method returns true if the database * supports the concurrency level rsConcur with the combination * of rsType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetConcurrency(int resType, int rsConcur) * method on that object with TYPE_SCROLL_SENSITIVE and CONCUR_UPDATABLE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetConcurrency6(); #endif /* * @testName: testSupportsResultSetType1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetType(int resType) method must return a * boolean value where resType can be any one of the following * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE. * The value is true if the database supports the ResultSet type * resType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetType(int resType) method with Type TYPE_FORWARD_ONLY * on that object.It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetType1(); /* * @testName: testSupportsResultSetType2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetType(int resType) method must return a * boolean value where resType can be any one of the following * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE. * The value is true if the database supports the ResultSet type * resType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetType() method with Type TYPE_SCROLL_INSENSITIVE * on that object.It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetType2(); /* * @testName: testSupportsResultSetType3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsResultSetType(int resType) method must return a * boolean value where resType can be any one of the following * TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE & TYPE_SCROLL_SENSITIVE. * The value is true if the database supports the ResultSet type * resType and false otherwise. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsResultSetType() method with Type TYPE_SCROLL_SENSITIVE * on that object.It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsResultSetType3(); /* * @testName: testSupportsSchemasInDataManipulation * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInDataManipulation() method must return a * boolean value; true if the database supports using a schema name * in a data manipulation statement and false otherwise. * (See JDK 1.2.2 API documentation) * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.supportsSchemasInDataManipulation() on that object. * It should return a boolean value either true or false. * */ /* throws std::exception * */ void testSupportsSchemasInDataManipulation(); /* * @testName: testSupportsSchemasInIndexDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInIndexDefinitions() method must return a * boolean value; true if the database supports using a schema name * in a index definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsSchemasInIndexDefinitions() on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsSchemasInIndexDefinitions(); /* * @testName: testSupportsSchemasInPrivilegeDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInPrivilegeDefinitions() method must return a * boolean value; true if the database supports using a schema name * in a privilege definition statement and false otherwise. * (See JDK 1.2.2 API documentation). * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Call to supportsSchemasInPrivilegeDefinitions() on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsSchemasInPrivilegeDefinitions(); /* * @testName: testSupportsSchemasInProcedureCalls * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInProcedureCalls() method must return a * boolean value; true if the database supports using a schema name * in a procedure call statement and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.supportsSchemasInProcedureCalls() on * that object. It should return a boolean value; either true or false * */ /* throws std::exception * */ void testSupportsSchemasInProcedureCalls(); /* * @testName: testSupportsSchemasInTableDefinitions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSchemasInTableDefinitions() method must return a * boolean value; true if the database supports using a schema name * in a table definition statement and false otherwise. * (See JDK 1.2.2 API documentation) * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase. * Make a call to DatabaseMetadata.supportsSchemasInTableDefinitions() * on that object.It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsSchemasInTableDefinitions(); /* * @testName: testSupportsSelectForUpdate * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSelectForUpdate() method must return a * boolean value; true if the database supports positioned * UPDATE statement and false otherwise.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSelectForUpdate() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsSelectForUpdate(); /* * @testName: testSupportsStoredProcedures * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave * as specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented.(See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The supportsStoredProcedures method must return a boolean value; * true if the database supports stored procedure calls and false if * the database does not support it. (See JDK 1.2.2 API * documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsStoredprocedures() method * It should return true value * */ /* throws std::exception * */ void testSupportsStoredProcedures(); /* * @testName: testSupportsSubqueriesInComparisons * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInComparisons() method must return a * boolean value; true if the database supports subqueries in * comparison expressions and false otherwise. A JDBC compliant * driver always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInComparisons() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsSubqueriesInComparisons(); /* * @testName: testSupportsSubqueriesInExists * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInExists() method must return a * boolean value; true if the database supports subqueries in * EXISTS expressions and false otherwise. A JDBC compliant driver * always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInExists() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsSubqueriesInExists(); /* * @testName: testSupportsSubqueriesInIns * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInIns() method must return a * boolean value; true if the database supports subqueries in * "IN" statements and false otherwise. A JDBC Compliant driver * always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInIns() method on that object. * It should return a boolean value either true or false. * */ /* throws std::exception * */ void testSupportsSubqueriesInIns(); /* * @testName: testSupportsSubqueriesInQuantifieds * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsSubqueriesInQuantifieds() method must return a * boolean value; true if the database supports subqueries in * quantified statement and false otherwise. A JDBC Compliant driver * always returns true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsSubqueriesInQuantifieds() method on that object. * It should return a boolean value either true or false. * */ /* throws std::exception * */ void testSupportsSubqueriesInQuantifieds(); /* * @testName: testSupportsTableCorrelationNames * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTableCorrelationNames() method must return * a boolean value; true if the database supports table * correlation names and false otherwise. A JDBC compliant * driver always return true. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the supportsTableCorrelationNames() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsTableCorrelationNames(); /* * @testName: testSupportsTransactionIsolationLevel1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with the isolation level TRANSACTION_NONE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsTransactionIsolationLevel1(); /* * @testName: testSupportsTransactionIsolationLevel2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with the isolation level TRANSACTION_READ_COMMITTED. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsTransactionIsolationLevel2(); /* * @testName: testSupportsTransactionIsolationLevel3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with the isolation level TRANSACTION_READ_UNCOMMITTED. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsTransactionIsolationLevel3(); /* * @testName: testSupportsTransactionIsolationLevel4 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with isolation level TRANSACTION_REPEATABLE_READ. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsTransactionIsolationLevel4(); /* * @testName: testSupportsTransactionIsolationLevel5 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactionIsolationLevel(int isolevel) method must * return a boolean value; true if the database supports the given * Transaction Isolation Level isolevel and false otherwise. The * possible values for isolevel can be TRANSACTION_NONE, * TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, * TRANSACTION_REPEATABLE_READ and TRANSACTION_SERIALIZABLE. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactionIsolationLevel(int isolevel) method * on that object with isolation level TRANSACTION_SERIALIZABLE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsTransactionIsolationLevel5(); /* * @testName: testSupportsTransactions * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsTransactions() method must return a boolean * value; true if transactions are supported and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsTransactions() method. * It should return a boolean value * */ /* throws std::exception * */ void testSupportsTransactions(); /* * @testName: testSupportsUnion * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsUnion() method must return a boolean value; * true if the database supports SQL Union and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsUnion() method on that object. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testSupportsUnion(); /* * @testName: testSupportsUnionAll * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The supportsUnionAll() method must return a boolean value * true if the database supports SQL Union All and false otherwise. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the supportsUnionAll() method on that object. * It should return a boolean value; eithet true or false. * */ /* throws std::exception * */ void testSupportsUnionAll(); /* * @testName: testUpdatesAreDetected1 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The updatesAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowUpdated returns * true when called on a ResultSet object with a given type that * contains visible row updates; false if the method * ResultSet.rowUpdated returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the updatesAreDetected() method on that object with the * ResultSet Type as ResultSet.TYPE_FORWARD_ONLY. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testUpdatesAreDetected1(); /* * @testName: testUpdatesAreDetected2 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The updatesAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowUpdated returns * true when called on a ResultSet object with a given type that * contains visible row updates; false if the method * ResultSet.rowUpdated returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the updatesAreDetected() method on that object with the * ResultSet Type as ResultSet.TYPE_SCROLL_INSENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testUpdatesAreDetected2(); /* * @testName: testUpdatesAreDetected3 * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * The updatesAreDetected(int resType) method must return a * boolean value; true if the method ResultSet.rowUpdated returns * true when called on a ResultSet object with a given type that * contains visible row updates; false if the method * ResultSet.rowUpdated returns false. The possible values for * resType are TYPE_FORWARD_ONLY, TYPE_SCROLL_SENSITIVE and * TYPE_SCROLL_INSENSITIVE.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a DatabaseMetadata object from the connection to the database * and call the updatesAreDetected() method on that object with the * ResultSet Type as ResultSet.TYPE_SCROLL_SENSITIVE. * It should return a boolean value; either true or false. * */ /* throws std::exception * */ void testUpdatesAreDetected3(); /* * @testName: testUsesLocalFilePerTable * @assertion: The DatabaseMetaData provides information about the database. * (See section 15.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * DatabaseMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The usesLocalFilePerTable method must return a boolean value; * true if the database uses a local file for each table. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get the DataBaseMetaData object from the Connection to the DataBase * and call the usesLocalFilePerTable() method * It should return a boolean value * */ /* throws std::exception * */ void testUsesLocalFilePerTable(); }; REGISTER_FIXTURE(DatabaseMetaDataTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/PreparedStatementTest.cpp000644 015771 000012 00000415271 12645244437 031106 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../driver/nativeapi/mysql_private_iface.h" #include "PreparedStatementTest.h" namespace testsuite { namespace compliance { /* * @testName: testGetMetaData * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The getMetadata() method returns a valid ResultSetMetaData Object * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the getMetaData() method and get the number of columns using * getColumnCount() method of ResultSetMetaData.Execute a query using * executeQuery() method and get the number of columns. Both the values * should be equal or it should throw an SQL exception. * */ /* throws Exception */ void PreparedStatementTest::testGetMetaData() { ResultSet res; ResultSetMetaData rsmd; ResultSetMetaData rsmdPrep; String sPrepStmt=sqlProps[ "SelCoffeeAll" ]; createStandardTable(TABLE_CTSTABLE2); pstmt.reset(conn->prepareStatement(sPrepStmt)); try { logMsg("Getting MetaData from PreparedStatement"); /* prepared statement class currently doesn't contain (get) metadata so, probably test doesn't make sense. Changing to compare result sets metadata */ //rsmdPrep= pstmt->getMetaData(); res.reset(pstmt->executeQuery()); rsmdPrep=res->getMetaData(); logMsg(String("Executing Query : ") + sPrepStmt); rs.reset(stmt->executeQuery(sPrepStmt)); logMsg("Getting MetaData from ResultSet"); rsmd=rs->getMetaData(); if (rsmdPrep->getColumnCount() == rsmd->getColumnCount()) logMsg("Call to getMetaData Method is Passed"); else { logErr("getMetaData Method does not return a valid ResultSetMetaData"); FAIL("Call to getMetaData Method is Failed!"); } } catch (sql::SQLException & sqe) { logErr(String("SQL std::exception * ") + sqe.what()); } } /* * @testName: testClearParameters * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 * API Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The method clearParameters() clears the values set for the * PreparedStatement object's IN parameters and releases the * resources used by those values. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Call the clearParameters() method.Call the executeQuery() method * to check if the call to clearParameters() clears the IN parameter * set by the Prepared Statement object. */ /* throws Exception */ void PreparedStatementTest::testClearParameters() { ResultSet reSet; bool sqlexcflag=false; String sPrepStmt=sqlProps[ "CoffeeTab_Query" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 1); pstmt->clearParameters(); try { reSet.reset(pstmt->executeQuery()); } catch (sql::SQLException &) { sqlexcflag=true; } if (sqlexcflag) { logMsg("clearParameters Method clears the current Parameters "); } else { logErr("clearParameters Method does not clear the current Parameters"); FAIL("Call to clearParameters Method is Failed!"); } } /* * @testName: testExecute01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The execute()method executes the SQL statement contained in * the Prepared Statement object and indicates whether the first * result is a resultset,an update count,or there are no results. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement * object. Execute the precompiled SQL Statement of deleting a row. * It should return a boolean value and the value should be equal to * false. (See JDK 1.2.2 API documentation) * */ /* throws Exception */ void PreparedStatementTest::testExecute01() { bool retValue; String sPrepStmt=sqlProps[ "CoffeeTab_Delete" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 1); retValue=pstmt->execute(); if (!retValue) { logMsg("execute Method executes the SQL Statement "); } else { logErr("execute Method does not execute the SQL Statement"); FAIL("Call to execute Method is Failed!"); } } /* * @testName: testExecute02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 * API Reference & Tutorial,Second Edition) * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The execute()method executes the SQL statement contained in the * Prepared Statement object and indicates whether the first result * is a resultset,an update count,or there are no results. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Execute the precompiled SQL Statement by calling executeQuery() * method with a non-existent row.Call ResultSet.next() method. * It should return a boolean value and the value should be equal * to false. (See JDK 1.2.2 API documentation) * */ /* throws Exception */ void PreparedStatementTest::testExecute02() { bool retValue; String sPrepStmt=sqlProps[ "CoffeeTab_Delete" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 0); retValue=pstmt->execute(); if (!retValue) { logMsg("execute Method executes the SQL Statement "); } else { logErr("execute Method does not execute the SQL Statment"); FAIL("Call to execute Method is Failed!"); } } /* * @testName: testExecute03 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * edition(J2EE) specification v 1.2). * * The execute() method executes the SQL statement contained in * the Prepared Statement object and indicates whether the first * result is a resultset,an update count,or there are no results. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling execute() method * without setting the parameters.An SQL Exception must be thrown. * (See JDK 1.2.2 API documentation) * */ /* throws Exception */ void PreparedStatementTest::testExecute03() { bool sqlexcflag=false; String sPrepStmt=sqlProps[ "CoffeeTab_Delete" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); try { pstmt->execute(); } catch (sql::SQLException &) { sqlexcflag=true; } if (sqlexcflag) { logMsg("execute Method executes the SQL Statement "); } else { logErr("execute Method does not execute the SQL Statment"); FAIL("Call to execute Method is Failed!"); } } /* * @testName: testExecuteQuery01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 * API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeQuery() method executes SQL query in this * PreparedStatement object and returns the result set generated * by the query.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Execute the precompiled SQL Statement by calling executeQuery() * method. It should return a ResultSet object. * */ /* throws Exception */ void PreparedStatementTest::testExecuteQuery01() { ResultSet reSet; const String & sPrepStmt=sqlProps[ "CoffeeTab_Query" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 1); reSet.reset(pstmt->executeQuery()); if (reSet.get() != NULL) { logMsg("executeQuery Method executes the SQL Statement "); } else { logErr("executeQuery Method does not execute the SQL Statment"); FAIL("Call to executeQuery Method is Failed!"); } } /* * @testName: testExecuteQuery02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeQuery() method executes SQL query in this * PreparedStatement object and returns the result set generated * by the query. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Execute the precompiled SQL Statement by calling executeQuery() * method with a non existent row. A call to ResultSet.next() * should return a false value. */ /* throws Exception */ void PreparedStatementTest::testExecuteQuery02() { ResultSet reSet; String sPrepStmt=sqlProps[ "CoffeeTab_Query" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 0); reSet.reset(pstmt->executeQuery()); if (!reSet->next()) { logMsg("executeQuery Method executes the SQL Statement "); } else { logErr("executeQuery Method does not execute the SQL Statment"); FAIL("Call to executeQuery Method is Failed!"); } } /* * @testName: testExecuteQuery03 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters).(See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeQuery() method executes SQL query in this * PreparedStatement object and returns the result set generated * by the query. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the * database. Execute the precompiled SQL Statement by calling * executeQuery() method without setting the parameters. * It should throw a SQL Exception. */ /* throws Exception */ void PreparedStatementTest::testExecuteQuery03() { ResultSet reSet; bool sqlexcflag=false; String sPrepStmt=sqlProps[ "CoffeeTab_Query" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); try { reSet.reset(pstmt->executeQuery()); } catch (sql::SQLException &) { sqlexcflag=true; } if (sqlexcflag) { logMsg("executeQuery Method executes the SQL Statement "); } else { logErr("executeQuery Method does not execute the SQL Statment"); FAIL("Call to executeQuery Method is Failed!"); } } /* * @testName: testExecuteUpdate01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements. It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeUpdate(String sql) method executes an SQL Insert, * Update or Delete Statement and returns the number of rows that * were affected.It can also be used to execute SQL statements * that have no return value such as DDL statements that create * or drop tables. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the * database. Set the value for the IN parameter of the PreparedStatement * object. Execute the precompiled SQL Statement by calling * executeUpdate() method. It should return an integer * value indicating the number of rows that were affected. * (The value could be zero if zero rows are affected). */ /* throws Exception */ void PreparedStatementTest::testExecuteUpdate01() { int retValue; const String & sPrepStmt=sqlProps[ "CoffeeTab_Delete" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 1); retValue=pstmt->executeUpdate(); if (retValue >= 0) { logMsg("executeUpdate Method executes the SQL Statement "); } else { logErr("executeUpdate Method does not execute the SQL Statment"); FAIL("Call to executeUpdate Method is Failed!"); } } /* * @testName: testExecuteUpdate02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters) (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeUpdate() method executes an SQL Insert, * Update or Delete Statement and returns the number of rows that * were affected.It can also be used to execute SQL statements * that have no return value such as DDL statements that create * or drop tables.(The value could be zero if zero rows are affected). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement * object. Execute the precompiled SQL Statement by calling * executeUpdate() method with a non existent row. * It should return an int value. */ /* throws Exception */ void PreparedStatementTest::testExecuteUpdate02() { int retValue; String sPrepStmt=sqlProps[ "CoffeeTab_Delete" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, 0); retValue=pstmt->executeUpdate(); if (retValue >= 0) { logMsg("executeUpdate Method executes the SQL Statement "); } else { logErr("executeUpdate Method does not execute the SQL Statment"); FAIL("Call to executeUpdate Method is Failed!"); } } /* * @testName: testExecuteUpdate03 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeUpdate() method executes an SQL Insert,Update or * Delete Statement and returns the number of rows that were affected. * It can also be used to execute SQL statements that have no * return value such as DDL statements that create or drop tables. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement without setting the IN parameter. * It should throw an SQL exception. */ /* throws Exception */ void PreparedStatementTest::testExecuteUpdate03() { bool sqlexcflag=false; String sPrepStmt=sqlProps[ "CoffeeTab_Delete" ]; createStandardTable(TABLE_CTSTABLE2); logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); try { pstmt->executeUpdate(); } catch (sql::SQLException &) { sqlexcflag=true; } if (sqlexcflag) { logMsg("executeUpdate Method executes the SQL Statement "); } else { logErr("executeUpdate Method does not execute the SQL Statment"); FAIL("Call to executeUpdate Method is Failed!"); } } /* * @testName: testSetBigDecimal01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition). * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBigDecimal(int parameterIndex, BigDecimal x) method * sets the parameterIndex to x which is an instance of * java.math.BigDecimal class. The Driver converts this to a * JDBC Numeric Value when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference,2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled.SQL Statement by calling the * setBigDecimal(int parameterindex, BigDecimal x) method for updating * the value of column MIN_VAL in Numeric_Tab.Check first * the return value of executeUpdate() method used is equal to 1. * Call the ResultSet.getBigDecimal(int columnIndex)method. * Check if returns the BigDecimal Value that has been set. */ /* throws Exception */ /* setBigDecimal is not included into current interface */ #ifdef __SET_BIG_DECIMAL_ADDED_ void PreparedStatementTest::testSetBigDecimal01() { BigDecimal rBigDecimalVal; BigDecimal minBigDecimalVal; initTable("Numeric_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Numeric_Tab_Min_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String sminBigDecimalVal=extractVal("Numeric_Tab", 2, sqlProps, conn); minBigDecimalVal=new BigDecimal(sminBigDecimalVal); logMsg(String("BigDecimal Value :") + minBigDecimalVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBigDecimal(1, minBigDecimalVal); int retVal=pstmt->executeUpdate(); TestsListener::messagesLog() << "Return Value " << retVal << std::endl; if (retVal != 1) { logErr("Minimum Value not being updated in the Min_Val column"); FAIL("Call to setBigDecimal Method is Failed!"); } String Min_Val_Query=sqlProps[ "Numeric_Query_Min" ]; logMsg(Min_Val_Query); rs.reset(stmt->executeQuery(Min_Val_Query)); rs->next(); rBigDecimalVal=rs->getBigDecimal(1); logMsg(String("Returned BigDecimal Value after Updation:") + rBigDecimalVal); if (rBigDecimalVal.compareTo(minBigDecimalVal) == 0) { logMsg("setBigDecimal Method sets the designated parameter to a BigDecimal value "); } else { logErr("setBigDecimal Method does not set the designated parameter to a BigDecimal value "); FAIL("Call to setBigDecimal Method is Failed!"); } } /* * @testName: testSetBigDecimal02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters) (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBigDecimal(int parameterIndex, BigDecimal x) method * sets the parameterIndex to x which is an instance of * java.math.BigDecimal class.The Driver converts this to a JDBC * Numeric Value when it sends it to the database.(See section * 24.3.2 of JDBC 2.0 API Tutorial & Reference, Second Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setBigDecimal(int parameterindex, BigDecimal x) method for updating * the value of column NULL_VAL in Numeric_Tab. Call the * ResultSet.getBigDecimal(int columnIndex) method. Check if * returns the BigDecimal Value that has been set. */ /* throws Exception */ void PreparedStatementTest::testSetBigDecimal02() { BigDecimal maxBigDecimalVal / *=NULL* /; BigDecimal rBigDecimalVal / *=NULL* /; initTable("Numeric_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Numeric_Tab_Null_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String smaxBigDecimalVal=extractVal("Numeric_Tab", 1, sqlProps, conn); maxBigDecimalVal=new BigDecimal(smaxBigDecimalVal); logMsg(String("BigDecimal Value :") + maxBigDecimalVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBigDecimal(1, maxBigDecimalVal); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Numeric_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rBigDecimalVal=rs->getBigDecimal(1); logMsg(String("Returned BigDecimal Value after Updation:") + rBigDecimalVal); if (rBigDecimalVal.compareTo(maxBigDecimalVal) == 0) { logMsg("setBigDecimal Method sets the designated parameter to a BigDecimal value "); } else { logErr("setBigDecimal Method does not set the designated parameter to a BigDecimal value "); FAIL("Call to setBigDecimal Method is Failed!"); } } #endif /* * @testName: testSetBoolean01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition). * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBoolean(int parameterIndex, boolean x) method sets the * parameterIndex to x, a Java boolean value.The driver converts * this to JDBC BIT value when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference, 2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setBoolean(int parameterIndex, boolean x) to set MAX_VAL * column of Bit_tab to the boolean value x. * Call the ResultSet.getBoolean(int columnIndex) method to check * if it returns the boolean Value that has been set. * */ /* throws Exception */ void PreparedStatementTest::testSetBoolean01() { createStandardTable(TABLE_BITTAB); bool bMinBooleanVal; bool rBooleanVal; initTable("Bit_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Bit_Tab_Max_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String sminBooleanVal=extractVal("Bit_Tab", 2, sqlProps, conn); bMinBooleanVal=(sminBooleanVal == "true" ? true : false); TestsListener::messagesLog() << "Boolean Value :" << bMinBooleanVal << std::endl; ResultSet tmp_res(stmt->executeQuery("select * from Bit_Tab")); TestsListener::messagesLog() << "Row count = " << tmp_res->rowsCount() << std::endl; TestsListener::messagesLog() << sPrepStmt << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBoolean(1, bMinBooleanVal); pstmt->executeUpdate(); String Max_Val_Query=sqlProps[ "Bit_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rBooleanVal=rs->getBoolean(1); TestsListener::messagesLog() << "Returned Boolean Value after Updation:" << rBooleanVal << std::endl; if (rBooleanVal == bMinBooleanVal) { logMsg("setBoolean Method sets the designated parameter to a Boolean value "); } else { logErr("setBoolean Method does not set the designated parameter to a Boolean value "); FAIL("Call to setBoolean Method is Failed!"); } } /* * @testName: testSetBoolean02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBoolean(int parameterIndex, boolean x) method sets the * parameterIndex to x, a Java boolean value.The driver converts this * to JDBC BIT value when it sends it to the database. (See section * 24.3.2 of JDBC 2.0 API Tutorial & Reference, Second Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the method * setBoolean(int parameterIndex, boolean x) to set NULL_VAL * column of Bit_tab to the boolean value x. * Call the ResultSet.getBoolean(int columnIndex) method to * check if it returns the boolean Value that has been set. */ /* throws Exception */ void PreparedStatementTest::testSetBoolean02() { createStandardTable(TABLE_BITTAB); bool bMaxBooleanVal; bool rBooleanVal; initTable("Bit_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Bit_Tab_Null_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String smaxBooleanVal=extractVal("Bit_Tab", 1, sqlProps, conn); bMaxBooleanVal=StringUtils::toBoolean(smaxBooleanVal); TestsListener::messagesLog() << "Boolean Value :" << bMaxBooleanVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBoolean(1, bMaxBooleanVal); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Bit_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rBooleanVal=rs->getBoolean(1); TestsListener::messagesLog() << "Returned Boolean Value after Updation:" << rBooleanVal << std::endl; if (rBooleanVal == bMaxBooleanVal) { logMsg("setBoolean Method sets the designated parameter to a Boolean value "); } else { logErr("setBoolean Method does not set the designated parameter to a Boolean value "); FAIL("Call to setBoolean Method is Failed!"); } } /* * @testName: testSetByte01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setByte(int parameterIndex, byte x) method sets the parameter * number parameterIndex to x,a Java byte value.The Driver converts * this to a JDBC Tinyint value when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference, 2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setByte(int parameterindex, byte x) method for updating MAX_VAL * column of Tinyint_Tab. Call the ResultSet.getByte(int columnIndex) * method to check if it returns the byte Value that has been set. */ /* throws Exception */ /* setByte is not included into current interface */ #ifdef __SET_BYTE_ADDED_ void PreparedStatementTest::testSetByte01() { byte bminByteVal=0; byte rByteVal=0; try { initTable("Tinyint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Tinyint_Tab_Max_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String sminByteVal=extractVal("Tinyint_Tab", 2, sqlProps, conn); bminByteVal=Byte.parseByte(sminByteVal); logMsg(String("Byte Value :") + bminByteVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setByte(1, bminByteVal); pstmt->executeUpdate(); String Max_Val_Query=sqlProps[ "Tinyint_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rByteVal=rs->getByte(1); logMsg(String("Returned Byte Value after Updation:") + rByteVal); if (rByteVal == bminByteVal) { logMsg("setByte Method sets the designated parameter to a Byte value "); } else { logErr("setByte Method does not set the designated parameter to a Byte value "); FAIL("Call to setByte Method is Failed!"); } } catch (sql::SQLException & sqle) { logErr(String("SQL std::exception * ") + sqle->what()); FAIL("Call to setByte is Failed!"); } catch (std::exception * e) { logErr(String("Unexpected std::exception * ") + e->what()); FAIL("Call to setByte Failed!", e); } { try { clearTable("Tinyint_Tab", conn); } catch (std::exception * e) { } } } /* * @testName: testSetByte02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setByte(int parameterIndex, byte x) method sets the parameter * number parameterIndex to x,a Java byte value. The Driver converts * this to a JDBC Tinyint value when it sends it to the database. * (See section 24.3.2 of JDBC 2.0 API Tutorial & Reference,2nd Edition) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setByte(int parameterindex, byte x) method for updating NULL_VAL * column of Tinyint_Tab. Call the ResultSet.getByte(int columnIndex) * method,to check if it returns the byte Value that has been set. */ /* throws Exception */ /* setByte is not included into current interface */ void PreparedStatementTest::testSetByte02() { byte bmaxByteVal=0; byte rByteVal=0; try { initTable("Tinyint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Tinyint_Tab_Null_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String smaxByteVal=extractVal("Tinyint_Tab", 1, sqlProps, conn); bmaxByteVal=Byte.parseByte(smaxByteVal); logMsg(String("Byte Value :") + bmaxByteVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setByte(1, bmaxByteVal); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Tinyint_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rByteVal=rs->getByte(1); logMsg(String("Returned Byte Value after Updation:") + rByteVal); if (rByteVal == bmaxByteVal) { logMsg("setByte Method sets the designated parameter to a Byte value "); } else { logErr("setByte Method does not set the designated parameter to a Byte value "); FAIL("Call to setByte Method is Failed!"); } } catch (sql::SQLException & sqle) { logErr(String("SQL std::exception * ") + sqle->what()); FAIL("Call to setByte is Failed!"); } catch (std::exception * e) { logErr(String("Unexpected std::exception * ") + e->what()); FAIL("Call to setByte Failed!", e); } { try { clearTable("Tinyint_Tab", conn); } catch (std::exception * e) { } } } #endif /* * @testName: testSetFloat01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setFloat(int parameterIndex, float x) method sets the parameter * number parameterIndex to x ,a Java float value. The Driver converts * this to a JDBC REAL when it sends it to the database. (See section * 24.3.2 of JDBC 2.0 API Tutorial & Reference,2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling the * setFloat(int parameterindex, float x) method for updating * the MAX_VAL column of Float_Tab. Call the * ResultSet.getFloat(int columnIndex) * method to check if it returns the float Value that has been set. * */ /* throws Exception */ /* setFloat is not included into current interface */ #ifdef __SET_FLOAT_ADDED_ void PreparedStatementTest::testSetFloat010101() { float rFloatVal=0; float minFloatVal=0; initTable("Float_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Float_Tab_Max_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String sminFloatVal=extractVal("Float_Tab", 2, sqlProps, conn); minFloatVal=float.parseFloat(sminFloatVal); logMsg(String("float Value :") + minFloatVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setFloat(1, minFloatVal); pstmt->executeUpdate(); String Max_Val_Query=sqlProps[ "Float_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rFloatVal=rs->getFloat(1); logMsg(String("Returned float Value after Updation:") + rFloatVal); if (rFloatVal == minFloatVal) { logMsg("setFloat Method sets the designated parameter to a float value "); } else { logErr("setFloat Method does not set the designated parameter to a float value "); FAIL("Call to setFloat Method is Failed!"); } } /* * @testName: testSetFloat02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setFloat(int parameterIndex, float x) method sets the * parameter number parameterIndex to x ,a Java float value. * The Driver converts this to a JDBC REAL when it sends it to * the database. (See section 24.3.2 of JDBC 2.0 API Tutorial & * Reference, Second Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling the * setFloat(int parameterindex, float x) method for updating the * NULL_VAL column of Float_Tab. Call the * ResultSet.getFloat(int columnIndex) method to check if it returns * the float Value that has been set. * */ /* throws Exception */ /* setFloat is not included into current interface */ void PreparedStatementTest::testSetFloat020202() { float maxFloatVal=0; float rFloatVal=0; try { initTable("Float_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Float_Tab_Null_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String smaxFloatVal=extractVal("Float_Tab", 1, sqlProps, conn); maxFloatVal=float.parseFloat(smaxFloatVal); logMsg(String("float Value :") + maxFloatVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setFloat(1, maxFloatVal); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Float_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rFloatVal=rs->getFloat(1); logMsg(String("Returned float Value after Updation:") + rFloatVal); if (rFloatVal == maxFloatVal) { logMsg("setFloat Method sets the designated parameter to a float value "); } else { logErr("setFloat Method does not set the designated parameter to a float value "); FAIL("Call to setFloat Method is Failed!"); } } catch (sql::SQLException & sqle) { logErr(String("SQL std::exception * ") + sqle->what()); FAIL("Call to setFloat is Failed!"); } catch (std::exception * e) { logErr(String("Unexpected std::exception * ") + e->what()); FAIL("Call to setFloat Failed!", e); } { try { clearTable("Float_Tab", conn); } catch (std::exception * e) { } } } #endif /* * @testName: testSetInt01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements. It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setInt(int parameterIndex, int x) method sets the parameter * number parameterIndex to x ,a Java int value. The Driver converts * this to a JDBC INTEGER when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference, 2nd Edition) * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling the * setInt(int parameterindex, int x) method for updating the MAX_VAL * column of Integer_Tab. Call the ResultSet.getInt(int columnIndex) * method to check if it returns the integer Value that has been set. * */ /* throws Exception */ void PreparedStatementTest::testSetInt01() { createStandardTable(TABLE_INTEGERTAB); int rIntegerVal=0; int minIntegerVal=0; initTable("Integer_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Integer_Tab_Max_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); String sminIntegerVal=extractVal("Integer_Tab", 2, sqlProps, conn); minIntegerVal=StringUtils::toInt(sminIntegerVal); TestsListener::messagesLog() << "int Value :" << minIntegerVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, minIntegerVal); pstmt->executeUpdate(); String Max_Val_Query=sqlProps[ "Integer_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rIntegerVal=rs->getInt(1); TestsListener::messagesLog() << "Returned int Value after Updation:" << rIntegerVal << std::endl; if (rIntegerVal == minIntegerVal) { logMsg("setInt Method sets the designated parameter to a int value "); } else { logErr("setInteger Method does not set the designated parameter to a int value "); FAIL("Call to setInt Method is Failed!"); } } /* * @testName: testSetInt02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setInt(int parameterIndex,int x) method sets parameter number * parameterIndex to Java int value x. The driver converts this to an * SQL INTEGER value when it sends it to the Database * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database * Using setInt(int parameterIndex,int x),update the column with the maximum * value of Integer_Tab. Now execute a query to get the maximum value and * retrieve the result of the query using the getInt(int columnIndex) method * Compare the returned value, with the maximum value extracted from the * ctssql.stmt file. Both of them should be equal */ /* throws Exception */ void PreparedStatementTest::testSetInt02() { createStandardTable(TABLE_INTEGERTAB); int maxIntegerVal=0; int rIntegerVal=0; initTable("Integer_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Integer_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String smaxIntegerVal=extractVal("Integer_Tab", 1, sqlProps, conn); maxIntegerVal=StringUtils::toInt(smaxIntegerVal); TestsListener::messagesLog() << "int Value: " << maxIntegerVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt(1, maxIntegerVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Integer_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rIntegerVal=rs->getInt(1); TestsListener::messagesLog() << "Returned int Value after Updation: " << rIntegerVal << std::endl; TestsListener::messagesLog() << "Value returned from ctssql.stmt: " << maxIntegerVal << std::endl; if (rIntegerVal == maxIntegerVal) { logMsg("setInt Method sets the designated parameter to a int value "); } else { logErr("setInteger Method does not set the designated parameter to a int value "); FAIL("Call to setInt Method is Failed!"); } } /* * @testName: testSetDate01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDate(int parameterIndex,Date x) method sets parameter * number parameterIndex to sql.Date value x. The driver * converts this to an SQL DATE value when it sends it to the database * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling setDate(int parameterIndex,Date x) * method and call the ResultSet.getDate(int) method to check and * it should return a String Value that it is been set */ /* throws Exception */ /* setDate is not included into current interface. Need to look if I should to rework it * for setDateTime */ #ifdef __SET_DATE_ADDED_ void PreparedStatementTest::testSetDate01() { Date mfgDateVal /*= NULL*/; Date rDateVal /*= NULL*/; String smfgDateVal; initTable("Date_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Date_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); smfgDateVal=extractVal("Date_Tab", 1, sqlProps, conn); smfgDateVal=smfgDateVal.substr(smfgDateVal.indexOf('\'') + 1, smfgDateVal.lastIndexOf('\'')); mfgDateVal=sql.Date.valueOf(smfgDateVal); logMsg(String("Date Value: ") + mfgDateVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setDate(1, mfgDateVal); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Date_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rDateVal=rs->getDate(1); logMsg(String("Returned Date Value after Updation: ") + rDateVal); logMsg(String("Value returned from ctssql.stmt: ") + mfgDateVal); if (rDateVal == mfgDateVal) { logMsg("setDate Method sets the designated parameter to a Date value "); } else { logErr("setDate Method does not set the designated parameter to a Date value "); FAIL("Call to setDate Method is Failed!"); } } /* * @testName: testSetDate02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDate(int parameterIndex,Date x,Calendar cal) method * sets the designated parameter to the given sql.Date value, * using the given Calendar object. The driver uses the Calendar * object to construct an SQL DATE value, which the driver then sends * to the database. With a a Calendar object, the driver can calculate * the date taking into account a custom timezone. If no Calendar * object is specified, the driver uses the default timezone, which * is that of the virtual machine running the application. * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling * setDate(int parameterIndex,Date x,Calendar cal) method * and call the ResultSet.getDate(int) method to check and * it should return a String Value that it is been set */ /* throws Exception */ /* setDate is not included into current interface. Need to look if I should to rework it * for setDateTime */ void PreparedStatementTest::testSetDate02() { Date mfgDateVal /*= NULL*/; Date rDateVal /*= NULL*/; String smfgDateVal; Calendar cal /*= NULL*/; initTable("Date_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Date_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); smfgDateVal=extractVal("Date_Tab", 1, sqlProps, conn); smfgDateVal=smfgDateVal.substr(smfgDateVal.indexOf('\'') + 1, smfgDateVal.lastIndexOf('\'')); mfgDateVal=sql.Date.valueOf(smfgDateVal); logMsg(String("Date Value :") + mfgDateVal); cal=Calendar.getInstance(); pstmt=conn->prepareStatement(sPrepStmt); logMsg(String("** Setting mfgDateVal") + mfgDateVal); pstmt->setDate(1, mfgDateVal, cal); pstmt->executeUpdate(); logMsg("Update query succeeeds"); const String & Null_Val_Query=sqlProps[ "Date_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); logMsg("Select query succeeds"); rDateVal=rs->getDate(1, cal); logMsg("getDate() succeeds"); logMsg(String("Returned Date Value after Updation: ") + rDateVal); logMsg(String("Value returned from ctssql.stmt: ") + mfgDateVal); if (rDateVal == mfgDateVal) { logMsg("setDate Method sets the designated parameter to a Date value "); } else { logErr(String("setDate Method does not set the designated parameter to a Date value ") + rDateVal + "!=" + mfgDateVal); FAIL("Call to setDate Method is Failed!"); } } #endif /* * @testName: testSetDouble01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDouble(int parameterIndex, double x) method Sets the * designated parameter to a Java double value. The driver converts * this to an SQL DOUBLE value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database * Using setDouble(int parameterIndex,double x),update the column the * minimum value of Double_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getDouble(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetDouble01() { createStandardTable(TABLE_DOUBLETAB); double rDoubleVal=0; double minDoubleVal=0; initTable("Double_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Double_Tab_Max_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String sminDoubleVal=extractVal("Double_Tab", 2, sqlProps, conn); minDoubleVal=StringUtils::toDouble(sminDoubleVal); TestsListener::messagesLog() << "Double Value: " << minDoubleVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setDouble(1, minDoubleVal); pstmt->executeUpdate(); const String & Max_Val_Query=sqlProps[ "Double_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rDoubleVal=rs->getDouble(1); TestsListener::messagesLog() << "Returned Double Value after Updation:" << rDoubleVal << std::endl; TestsListener::messagesLog() << "Value returned from ctssql.stmt: " << minDoubleVal << std::endl; if (rDoubleVal == minDoubleVal) { logMsg("setDouble Method sets the designated parameter to a Double value "); } else { logErr("setDouble Method does not set the designated parameter to a Double value "); FAIL("Call to setDouble Method is Failed!"); } } /* * @testName: testSetDouble02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDouble(int parameterIndex, double x) method Sets the * designated parameter to a Java double value. The driver converts * this to an SQL DOUBLE value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setDouble(int parameterIndex,double x),update the column * the maximum value of Double_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getDouble(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetDouble02() { createStandardTable(TABLE_DOUBLETAB); double maxDoubleVal=0; double rDoubleVal=0; initTable("Double_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Double_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String smaxDoubleVal=extractVal("Double_Tab", 1, sqlProps, conn); maxDoubleVal=StringUtils::toDouble(smaxDoubleVal); TestsListener::messagesLog() << "Double Value: " << maxDoubleVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setDouble(1, maxDoubleVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Double_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rDoubleVal=rs->getDouble(1); TestsListener::messagesLog() << "Returned Double Value after Updation: " << rDoubleVal << std::endl; TestsListener::messagesLog() << "Value returned from ctssql.stmt: " << maxDoubleVal << std::endl; if (rDoubleVal == maxDoubleVal) { logMsg("setDouble Method sets the designated parameter to a Double value "); } else { logErr("setDouble Method does not set the designated parameter to a Double value "); FAIL("Call to setDouble Method is Failed!"); } } /* * @testName: testSetLong01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setInt64(int parameterIndex, long x) method Sets the * designated parameter to a Java long value. The driver converts * this to an SQL BIGINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setInt64(int parameterIndex,long x),update the column the * minimum value of Bigint_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getInt64(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetLong01() { createStandardTable(TABLE_BIGINTTAB); long long rLongVal=0; long long minLongVal=0; initTable("Bigint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Bigint_Tab_Max_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String sminLongVal=extractVal("Bigint_Tab", 2, sqlProps, conn); minLongVal=StringUtils::toLong(sminLongVal); TestsListener::messagesLog() << "Long Value: " << minLongVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt64(1, minLongVal); pstmt->executeUpdate(); const String & Max_Val_Query=sqlProps[ "Bigint_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rLongVal=rs->getInt64(1); TestsListener::messagesLog() << "Returned Long Value after Updation:" << rLongVal << std::endl; TestsListener::messagesLog() << "Value returned from ctssql.stmt: " << minLongVal << std::endl; if (rLongVal == minLongVal) { logMsg("setInt64 Method sets the designated parameter to a long value "); } else { logErr("setInt64 Method does not set the designated parameter to a long value "); FAIL("Call to setInt64 Method is Failed!"); } } /* * @testName: testSetLong02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setInt64(int parameterIndex, long x) method Sets the * designated parameter to a Java long value. The driver converts * this to an SQL BIGINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setInt64(int parameterIndex,long x),update the column the * maximum value of Bigint_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getInt64(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetLong02() { createStandardTable(TABLE_BIGINTTAB); long long maxLongVal=0; long long rLongVal=0; initTable("Bigint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Bigint_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String smaxLongVal=extractVal("Bigint_Tab", 1, sqlProps, conn); maxLongVal=StringUtils::toLong(smaxLongVal); TestsListener::messagesLog() << "Long Value: " << maxLongVal << std::endl; pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setInt64(1, maxLongVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Bigint_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rLongVal=rs->getInt64(1); TestsListener::messagesLog() << "Returned Long Value after Updation:" << rLongVal << std::endl; TestsListener::messagesLog() << "Value returned from ctssql.stmt: " << maxLongVal << std::endl; if (rLongVal == maxLongVal) { logMsg("setInt64 Method sets the designated parameter to a long value "); } else { logErr("setInt64 Method does not set the designated parameter to a long value "); FAIL("Call to setInt64 Method is Failed!"); } } /* * @testName: testSetShort01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setShort(int parameterIndex, short x) method Sets the * designated parameter to a Java short value. The driver converts * this to an SQL SMALLINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setShort(int parameterIndex,short x),update the column the * minimum value of Smallint_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getShort(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ #ifdef __SET_SHORT_ADDED_ void PreparedStatementTest::testSetShort01() { short rShortVal=0; short minShortVal=0; initTable("Smallint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Smallint_Tab_Max_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String sminShortVal=extractVal("Smallint_Tab", 2, sqlProps, conn); minShortVal=StringUtils::toShort(sminShortVal); logMsg(String("Short Value: ") + minShortVal); pstmt=conn->prepareStatement(sPrepStmt); pstmt->setShort(1, minShortVal); pstmt->executeUpdate(); const String & Max_Val_Query=sqlProps[ "Smallint_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rShortVal=rs->getShort(1); logMsg(String("Returned Short Value after Updation: ") + rShortVal); logMsg(String("Value returned from ctssql.stmt: ") + minShortVal); if (rShortVal == minShortVal) { logMsg("setShort Method sets the designated parameter to a Short value "); } else { logErr("setShort Method does not set the designated parameter to a Short value "); FAIL("Call to setShort Method is Failed!"); } } /* * @testName: testSetShort02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setShort(int parameterIndex, short x) method Sets the * designated parameter to a Java short value. The driver converts * this to an SQL SMALLINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setShort(int parameterIndex,short x),update the column the * maximum value of Smallint_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getShort(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetShort02() { short maxShortVal=0; short rShortVal=0; initTable("Smallint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Smallint_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String smaxShortVal=extractVal("Smallint_Tab", 1, sqlProps, conn); maxShortVal=StringUtils::toShort(smaxShortVal); logMsg(String("Short Value: ") + maxShortVal); pstmt=conn->prepareStatement(sPrepStmt); pstmt->setShort(1, maxShortVal); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Smallint_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rShortVal=rs->getShort(1); logMsg(String("Returned Short Value after Updation:") + rShortVal); logMsg(String("Value returned from ctssql.stmt: ") + maxShortVal); if (rShortVal == maxShortVal) { logMsg("setShort Method sets the designated parameter to a Short value "); } else { logErr("setShort Method does not set the designated parameter to a Short value "); FAIL("Call to setShort Method is Failed!"); } } #endif /* * @testName: testSetNull01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for INTEGER Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ /* setNull is not included into current interface */ #ifdef __SET_NULL_ADDED_ void PreparedStatementTest::testSetNull01() { createStandardTable(TABLE_INTEGERTAB); bool NULLFlag; initTable("Integer_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Integer_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); // Second parameter to setNull is ignored pstmt->setNull(1, MYSQL_TYPE_LONG); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Integer_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rs->getInt(1); NULLFlag=rs->wasNull(); TestsListener::messagesLog() << "Boolean Value After Updation: " << NULLFlag << std::endl; if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for FLOAT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull02() { createStandardTable(TABLE_FLOATTAB); bool NULLFlag; initTable("Float_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Float_Tab_Null_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_FLOAT); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Float_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); static_cast (rs->getDouble(1)); NULLFlag=rs->wasNull(); TestsListener::messagesLog() << "Boolean Value After Updation: " << NULLFlag << std::endl; clearTable("Float_Tab", conn); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull03 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for SMALLINT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull03() { createStandardTable(TABLE_SMALLINTTAB); bool NULLFlag; initTable("Smallint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Smallint_Tab_Null_Update" ]; logMsg(String("Prepared Statement String :") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_SHORT); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Smallint_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); // it's easier to hack the test, than comment it rs->getInt(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + (NULLFlag ? "true" : "false")); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull04 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for CHAR Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull04() { createStandardTable(TABLE_CHARTAB); bool NULLFlag; String rStringVal; initTable("Char_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Char_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_STRING); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Char_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rStringVal=rs->getString(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + (NULLFlag ? "true" : "false")); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull05 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for TIME Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ // Assuming that set/getTiem and Timestamp will be added along w/ setDate #ifdef __SET_DATE_ADDED_ void PreparedStatementTest::testSetNull05() { bool NULLFlag; Time rTimeVal /*= NULL*/; initTable("Time_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Time_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::TIME); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Time_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rTimeVal=rs->getTime(1); NULLFlag=rs->wasNull(); logMsg(String("Time Value After Updation: ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull06 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for TIMESTAMP Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull06() { bool NULLFlag; Timestamp rTimestampVal/*= NULL*/; initTable("Timestamp_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Timestamp_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::TIMESTAMP); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Timestamp_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rTimestampVal=rs->getTimestamp(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull07 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for DATE Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull07() { bool NULLFlag; Date rDateVal /*= NULL*/; initTable("Date_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Date_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::DATE); logMsg("Null set"); pstmt->executeUpdate(); logMsg("Updated"); String Null_Val_Query=sqlProps[ "Date_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rDateVal=rs->getDate(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } #endif #ifdef __SET_BIG_DECIMAL_ADDED_ /* * @testName: testSetNull08 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for NUMERIC Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull08() { bool NULLFlag; BigDecimal rBigDecimalVal /*= NULL*/; initTable("Numeric_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Numeric_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::NUMERIC); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Numeric_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rBigDecimalVal=rs->getBigDecimal(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } #endif #ifdef __SET_BYTE_ADDED_ /* * @testName: testSetNull09 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for TINYINT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull09() { bool NULLFlag; byte rByteVal=0; initTable("Tinyint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Tinyint_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::TINYINT); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Tinyint_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rByteVal=rs->getByte(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } #endif /* * @testName: testSetNull10 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for DOUBLE Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull10() { createStandardTable(TABLE_DOUBLETAB); bool NULLFlag; initTable("Double_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Double_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_DOUBLE); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Double_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rs->getDouble(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + (NULLFlag ? "true" : "false")); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull11 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for BIGINT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws Exception */ void PreparedStatementTest::testSetNull11() { createStandardTable(TABLE_BIGINTTAB); bool NULLFlag; initTable("Bigint_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Bigint_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_LONG); pstmt->executeUpdate(); String Null_Val_Query=sqlProps[ "Bigint_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rs->getInt64(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + (NULLFlag ? "true" : "false")); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } #endif /* * @testName: testSetString01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setString(int parameterIndex, String x) method sets the designated * parameter to a Java String value. The driver converts this to an * SQL VARCHAR or LONGVARCHAR value (depending on the argument's size * relative to the driver's limits on VARCHAR values) when it sends * it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setString(int parameterIndex, String x) method,update the * column value with the maximum value of Char_Tab. Call the * getString(String columnName) method to retrieve this value. Extract * the maximum value from the ctssql.stmt file. Compare this value * with the value returned by the getString(String columnName) method. * Both the values should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetString01() { createStandardTable(TABLE_CHARTAB); String maxStringVal; String rStringVal; initTable("Char_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Char_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); maxStringVal=extractVal("Char_Tab", 1, sqlProps, conn); maxStringVal=maxStringVal.substr(1, maxStringVal.length() - 1); logMsg(String("String Value: ") + maxStringVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setString(1, maxStringVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Char_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rStringVal=rs->getString(1); rStringVal=StringUtils::trim(rStringVal); maxStringVal=StringUtils::trim(maxStringVal); logMsg(String("Returned String Value after Updation: ") + rStringVal); logMsg(String("Value returned from ctssql.stmt: ") + maxStringVal); if (rStringVal == maxStringVal) { logMsg("setString Method sets the designated parameter to a String value "); } else { logErr("setString Method does not set the designated parameter to a String value "); FAIL("Call to setString Method is Failed!"); } } #ifdef __SET_TIME_ADDED_ /* * @testName: testSetTime01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTime(int parameterIndex, Time x) method sets the * designated parameter to a sql.Time value. The driver * converts this to an SQL TIME value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTime(int parameterIndex, Time x) method,update the * column value with the Non-Null Time value. Call the getTime(int columnno) * method to retrieve this value. Extract the Time value * from the ctssql.stmt file. Compare this value with the value returned * by the getTime(int columnno) method. Both the values should be equal */ /* throws Exception */ void PreparedStatementTest::testSetTime01() { Time brkTimeVal /*= NULL*/; Time rTimeVal /*= NULL*/; String sbrkTimeVal; initTable("Time_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Time_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); sbrkTimeVal=extractVal("Time_Tab", 1, sqlProps, conn); sbrkTimeVal=sbrkTimeVal.substr(sbrkTimeVal.indexOf('\'') + 1, sbrkTimeVal.lastIndexOf('\'')); sbrkTimeVal=StringUtils::trim(sbrkTimeVal); brkTimeVal=Time.valueOf(sbrkTimeVal); logMsg(String("Time Value: ") + brkTimeVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setTime(1, brkTimeVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Time_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rTimeVal=rs->getTime(1); logMsg(String("Returned Time Value after Updation: ") + rTimeVal); logMsg(String("Value returned from ctssql.stmt: ") + brkTimeVal); if (rTimeVal == brkTimeVal) { logMsg("setTime Method sets the designated parameter to a Time value "); } else { logErr("setTime Method does not set the designated parameter to a Time value "); FAIL(String("Call to setTime Method is Failed!, expected '") + brkTimeVal + "', value returned was '" + rTimeVal + "'"); } } /* * @testName: testSetTime02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTime(int parameterIndex, String x, Calendar cal) method sets the * designated parameter to the given sql.Time value, using the given * Calendar object. The driver uses the Calendar object to construct an * SQL TIME value, which the driver then sends to the database. With a Calendar * object, the driver can calculate the time taking into account a custom * timezone. If no Calendar object is specified, the driver uses the default * timezone, which is that of the virtual machine running the application. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTime(int parameterIndex, Time x, Calendar cal) method,update the * column value with the Non-Null Time value using the Calendar Object. Call the * getTime(int columnno) method to retrieve this value. Extract the Time value * from the ctssql.stmt file. Compare this value with the value returned * by the getTime(int columnno) method. Both the values should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetTime02() { Time brkTimeVal /*= NULL*/; Time rTimeVal /*= NULL*/; String sbrkTimeVal; Calendar cal /*= NULL*/; initTable("Time_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Time_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); sbrkTimeVal=extractVal("Time_Tab", 1, sqlProps, conn); sbrkTimeVal=sbrkTimeVal.substr(sbrkTimeVal.indexOf('\'') + 1, sbrkTimeVal.lastIndexOf('\'')); sbrkTimeVal=StringUtils::trim(sbrkTimeVal); brkTimeVal=Time.valueOf(sbrkTimeVal); logMsg(String("Time Value: ") + brkTimeVal); cal=Calendar.getInstance(); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setTime(1, brkTimeVal, cal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Time_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rTimeVal=rs->getTime(1, cal); logMsg(String("Returned Time Value after Updation: ") + rTimeVal); logMsg(String("Value returned from ctssql.stmt:") + brkTimeVal); if ((rTimeVal).trim().equals((brkTimeVal).trim())) { logMsg("setTime Method sets the designated parameter to a Time value "); } else { logErr("setTime Method does not set the designated parameter to a Time value "); FAIL(String("Call to setTime Method is Failed!, expected '") + brkTimeVal + "', value returned was '" + rTimeVal + "'"); } } #endif #ifdef __SET_TIMESTAMP_ADDED_ /* * @testName: testSetTimestamp01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTimestamp(int parameterIndex,Timestamp x) method sets * the designated parameter to a sql.Timestamp value. * The driver converts this to an SQL TIMESTAMP value when it * sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTimestamp(int parameterIndex, Timestamp x) method,update the * column value with the Non-Null Timestamp value. Call the getTimestamp(int columnno) * method to retrieve this value. Extract the Timestamp value * from the ctssql.stmt file. Compare this value with the value returned * by the getTimestamp(int columnno) method. Both the values should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetTimestamp01() { Timestamp inTimeVal /*= NULL*/; Timestamp rTimestampVal /*= NULL*/; String sinTimeVal; initTable("Timestamp_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Timestamp_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); sinTimeVal=extractVal("Timestamp_Tab", 1, sqlProps, conn); sinTimeVal=sinTimeVal.substr(sinTimeVal.indexOf('\'') + 1, sinTimeVal.lastIndexOf('\'')); inTimeVal=Timestamp.valueOf(sinTimeVal); logMsg(String("Timestamp Value: ") + inTimeVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setTimestamp(1, inTimeVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Timestamp_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rTimestampVal=rs->getTimestamp(1); logMsg(String("Returned Timestamp Value after Updation: ") + rTimestampVal); logMsg(String("Value returned from ctssql.stmt :") + inTimeVal); if (rTimestampVal == inTimeVal) { logMsg("setTimestamp Method sets the designated parameter to a Timestamp value "); } else { logErr("setTimestamp Method does not set the designated parameter to a Timestamp value "); FAIL("Call to setTimestamp Method is Failed!"); } } /* * @testName: testSetTimestamp02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTimestamp(int parameterIndex, String x, Calendar cal) method sets the * designated parameter to the given sql.Timestamp value, using the given * Calendar object. The driver uses the Calendar object to construct an * SQL TIMESTAMP value, which the driver then sends to the database. With a Calendar * object, the driver can calculate the time taking into account a custom * timezone. If no Calendar object is specified, the driver uses the default * timezone, which is that of the virtual machine running the application. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTimestamp(int parameterIndex, Time x, Calendar cal) method,update the * column value with the Non-Null Timestamp value using the Calendar Object. Call the * getTimestamp(int columnno) method to retrieve this value. Extract the Timestamp value * from the ctssql.stmt file. Compare this value with the value returned * by the getTimestamp(int columnno) method. Both the values should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetTimestamp02() { Timestamp inTimeVal /*= NULL*/; Timestamp rTimestampVal /*= NULL*/; String sinTimeVal; Calendar cal /*= NULL*/; initTable("Timestamp_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Timestamp_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); sinTimeVal=extractVal("Timestamp_Tab", 1, sqlProps, conn); sinTimeVal=sinTimeVal.substr(sinTimeVal.indexOf('\'') + 1, sinTimeVal.lastIndexOf('\'')); inTimeVal=Timestamp.valueOf(sinTimeVal); logMsg(String("Timestamp Value: ") + inTimeVal); cal=Calendar.getInstance(); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setTimestamp(1, inTimeVal, cal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Timestamp_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rTimestampVal=rs->getTimestamp(1, cal); logMsg(String("Returned Timestamp Value after Updation: ") + rTimestampVal); logMsg(String("Value returned from ctssql.stmt :") + inTimeVal); if (rTimestampVal == inTimeVal) { logMsg("setTimestamp Method sets the designated parameter to a Timestamp value "); } else { logErr("setTimestamp Method does not set the designated parameter to a Timestamp value "); FAIL("Call to setTimestamp Method is Failed!"); } } #endif /* * @testName: testSetString02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setString(int parameterIndex, String x) method sets the designated * parameter to a Java String value. The driver converts this to an * SQL VARCHAR or LONGVARCHAR value (depending on the argument's size * relative to the driver's limits on VARCHAR values) when it sends * it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setString(int parameterIndex, String x),update the column * with the maximum value which is a SQL VARCHAR. Call the * getString(int ColumnIndex) method to retrieve this value. Extract * the maximum value as a String from the ctssql.stmt file. * Compare this value with the value returned by the getString method. * Both the values should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetString02() { createStandardTable(TABLE_VARCHARTAB); String maxStringVal; String rStringVal; initTable("Varchar_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Varchar_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); maxStringVal=extractVal("Varchar_Tab", 1, sqlProps, conn); maxStringVal=maxStringVal.substr(1, maxStringVal.length() - 1); logMsg(String("String Value: ") + maxStringVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setString(1, maxStringVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Varchar_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rStringVal=rs->getString(1); rStringVal=StringUtils::trim(rStringVal); maxStringVal=StringUtils::trim(maxStringVal); logMsg(String("Returned String Value after Updation: ") + rStringVal); logMsg(String("Value returned from ctssql.stmt: ") + maxStringVal); if (rStringVal == maxStringVal) { logMsg("setString Method sets the designated parameter to a String value "); } else { logErr("setString Method does not set the designated parameter to a String value "); FAIL("Call to setString Method is Failed!"); } } /* * @testName: testSetFloat01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setFloat(int parameterIndex, float x) sets the designated parameter * to a Java float value. The driver converts this to an SQL FLOAT value * when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setFloat(int parameterIndex,float x),update the column with the * minimum value of Real_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getFloat(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ #ifdef __SET_FLOAT_ADDED_ void PreparedStatementTest::testSetFloat01() { float rFloatVal=0; float minFloatVal=0; initTable("Real_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Real_Tab_Max_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String sminFloatVal=extractVal("Real_Tab", 2, sqlProps, conn); minFloatVal=float.parseFloat(sminFloatVal); logMsg(String("float Value: ") + minFloatVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setFloat(1, minFloatVal); pstmt->executeUpdate(); const String & Max_Val_Query=sqlProps[ "Real_Query_Max" ]; logMsg(Max_Val_Query); rs.reset(stmt->executeQuery(Max_Val_Query)); rs->next(); rFloatVal=rs->getFloat(1); logMsg(String("Returned float Value after Updation: ") + rFloatVal); logMsg(String("Value returned from ctssql.stmt: ") + minFloatVal); if (rFloatVal == minFloatVal) { logMsg("setFloat Method sets the designated parameter to a float value "); } else { logErr("setFloat Method does not set the designated parameter to a float value "); FAIL("Call to setFloat Method is Failed!"); } } /* * @testName: testSetFloat02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setFloat(int parameterIndex, float x) sets the designated parameter * to a Java float value. The driver converts this to an SQL FLOAT value * when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setFloat(int parameterIndex,float x),update the column with the * maximum value of Real_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getFloat(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws Exception */ void PreparedStatementTest::testSetFloat02() { float maxFloatVal=0; float rFloatVal=0; initTable("Real_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Real_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); String smaxFloatVal=extractVal("Real_Tab", 1, sqlProps, conn); maxFloatVal=float.parseFloat(smaxFloatVal); logMsg(String("float Value: ") + maxFloatVal); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setFloat(1, maxFloatVal); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Real_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rFloatVal=rs->getFloat(1); logMsg(String("Returned float Value after Updation: ") + rFloatVal); logMsg(String("Value returned from ctssql.stmt: ") + maxFloatVal); if (rFloatVal == maxFloatVal) { logMsg("setFloat Method sets the designated parameter to a float value "); } else { logErr("setFloat Method does not set the designated parameter to a float value "); FAIL("Call to setFloat Method is Failed!"); } } #endif #ifdef __SET_NULL_ADDED_ /* * @testName: testSetNull12 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for Varchar Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull12() { createStandardTable(TABLE_VARCHARTAB); bool NULLFlag; String rStringVal; initTable("Varchar_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Varchar_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_VARCHAR); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Varchar_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rStringVal=rs->getString(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + (NULLFlag ? "true" : "false")); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull13 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for LONGVARCHAR Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull13() { createStandardTable(TABLE_LONGVARCHARNULLTAB); bool NULLFlag; String rStringVal; initTable("Longvarcharnull_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Longvarchar_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, MYSQL_TYPE_MEDIUM_BLOB); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Longvarchar_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rStringVal=rs->getString(1); NULLFlag=rs->wasNull(); // TODO: add toString(bool) in the StringUtils logMsg(String("Boolean Value After Updation: ") + (NULLFlag ? "true" : "false")); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } #ifdef _WE_HAVE_SOME_REAL_TYPE /* * @testName: testSetNull14 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for REAL Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull14() { bool NULLFlag; float rFloatVal=0; try { initTable("Real_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Real_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::REAL); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Real_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rFloatVal=rs->getFloat(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation: ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } catch (sql::SQLException & sqle) { logErr(String("SQL std::exception *: ") + sqle->what()); FAIL("Call to setNull is Failed!"); } catch (std::exception * e) { logErr(String("Unexpected std::exception *: ") + e->what()); FAIL("Call to setNull is Failed!", e); } } #endif //getBigDecimal will be probably added along w/ its "set" counterpart #ifdef __SET_BIG_DECIMAL_ADDED_ /* * @testName: testSetNull15 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for DECIMAL Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull15() { bool NULLFlag; BigDecimal rBigDecimalVal /*= NULL*/; try { initTable("Decimal_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Decimal_Tab_Null_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setNull(1, sql::Types::DECIMAL); pstmt->executeUpdate(); const String & Null_Val_Query=sqlProps[ "Decimal_Query_Null" ]; logMsg(Null_Val_Query); rs.reset(stmt->executeQuery(Null_Val_Query)); rs->next(); rBigDecimalVal=rs->getBigDecimal(1); NULLFlag=rs->wasNull(); logMsg(String("Boolean Value After Updation ") + NULLFlag); if (NULLFlag) { logMsg("setNull Method sets the designated parameter to a SQL Null"); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } catch (sql::SQLException & sqle) { logErr(String("SQL std::exception *: ") + sqle->what()); FAIL("Call to setNull is Failed!"); } catch (std::exception * e) { logErr(String("Unexpected std::exception *: ") + e->what()); FAIL("Call to setNull is Failed!", e); } } #endif #ifdef __SET_BYTE_ADDED_ /* * @testName: testSetNull16 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for BINARY Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull16() { byte retByteArr[] /*= NULL*/; String binarySize; initTable("Binary_Tab", sqlProps, conn); binarySize=sqlProps["binarySize"]; logMsg(String("Binary Table Size : ") + binarySize); const String & sPrepStmt=sqlProps[ "Binary_Tab_Val_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); int bytearrsize=StringUtils::toInt(binarySize); logMsg(String("Binary Size : ") + bytearrsize); byte[] bytearr=new byte[bytearrsize]; String sbyteval; for (int count=0; count < bytearrsize; count++) { sbyteval=int.toString(count % 255); bytearr[count]=Byte.parseByte(sbyteval); } pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBytes(1, bytearr); pstmt->executeUpdate(); pstmt->setNull(1, sql::Types::BINARY); pstmt->executeUpdate(); const String & Binary_Val_Query=sqlProps[ "Binary_Query_Val" ]; logMsg(Binary_Val_Query); rs.reset(stmt->executeQuery(Binary_Val_Query)); rs->next(); retByteArr=(byte[]) rs->getBytes(1); if (retByteArr == NULL) { logMsg("setNull Method sets the designated parameter to a SQL Null "); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull17 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for VARBINARY Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull17() { byte retByteArr[] /*= NULL*/; String varbinarySize; initTable("Varbinary_Tab", sqlProps, conn); varbinarySize=sqlProps["varbinarySize"]; logMsg(String("Varbinary Table Size : ") + varbinarySize); const String & sPrepStmt=sqlProps[ "Varbinary_Tab_Val_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); int bytearrsize=StringUtils::toInt(varbinarySize); logMsg(String("Varbinary Size : ") + bytearrsize); byte[] bytearr=new byte[bytearrsize]; String sbyteval; for (int count=0; count < bytearrsize; count++) { sbyteval=int.toString(count % 255); bytearr[count]=Byte.parseByte(sbyteval); } pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBytes(1, bytearr); pstmt->executeUpdate(); pstmt->setNull(1, sql::Types::VARBINARY); pstmt->executeUpdate(); const String & Varbinary_Val_Query=sqlProps[ "Varbinary_Query_Val" ]; logMsg(Varbinary_Val_Query); rs.reset(stmt->executeQuery(Varbinary_Val_Query)); rs->next(); retByteArr=(byte[]) rs->getBytes(1); if (retByteArr == NULL) { logMsg("setNull Method sets the designated parameter to a SQL Null "); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } /* * @testName: testSetNull18 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for LONGVARBINARY Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws Exception */ void PreparedStatementTest::testSetNull18() { byte retByteArr[] /*= NULL*/; bool byteArrFlag=false; initTable("Longvarbinary_Tab", sqlProps, conn); const String & sPrepStmt=sqlProps[ "Longvarbinary_Tab_Val_Update" ]; logMsg(String("Prepared Statement String: ") + sPrepStmt); const String & binsize=sqlProps["longvarbinarySize"]; int bytearrsize=StringUtils::toInt(binsize); logMsg(String("Longvarbinary Size : ") + bytearrsize); byte[] bytearr=new byte[bytearrsize]; String sbyteval; for (int count=0; count < bytearrsize; count++) { sbyteval=int.toString(count % 255); bytearr[count]=Byte.parseByte(sbyteval); } pstmt.reset(conn->prepareStatement(sPrepStmt)); pstmt->setBytes(1, bytearr); pstmt->executeUpdate(); pstmt->setNull(1, sql::Types::LONGVARBINARY); pstmt->executeUpdate(); const String & Longvarbinary_Val_Query=sqlProps[ "Longvarbinary_Query_Val" ]; logMsg(Longvarbinary_Val_Query); rs.reset(stmt->executeQuery(Longvarbinary_Val_Query)); rs->next(); retByteArr=rs->getBytes(1); if (retByteArr == NULL) { logMsg("setNull Method sets the designated parameter to a SQL Null "); } else { logErr("setNull Method does not set the designated parameter to a SQL Null "); FAIL("Call to setNull Method is Failed!"); } } #endif // __SET_BYTE_ADDED_ #endif // __SET_NULL_ADDED_ /** * @see junit.framework.TestCase#setUp() */ /* throws Exception */ void PreparedStatementTest::setUp() { super::setUp(); dbmd=conn->getMetaData(); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/PreparedStatementTest.h000644 015771 000012 00000245213 12645244437 030550 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" #define __SET_NULL_ADDED_ /** * @author mmatthew * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ namespace testsuite { namespace compliance { class PreparedStatementTest : public BaseTestFixture { private: typedef BaseTestFixture super; DatabaseMetaData dbmd; protected: /** * setUp() function for tests */ /* throws std::exception * */ void setUp(); public: TEST_FIXTURE(PreparedStatementTest) { TEST_CASE( testGetMetaData ); TEST_CASE( testClearParameters); TEST_CASE(testExecute01); TEST_CASE(testExecute02); TEST_CASE(testExecute03); TEST_CASE(testExecuteQuery01); TEST_CASE(testExecuteQuery02); TEST_CASE(testExecuteQuery03); TEST_CASE(testExecuteUpdate01); TEST_CASE(testExecuteUpdate02); TEST_CASE(testExecuteUpdate03); TEST_CASE(testSetBoolean01); TEST_CASE(testSetBoolean02); TEST_CASE(testSetInt01); TEST_CASE(testSetInt02); TEST_CASE(testSetDouble01); TEST_CASE(testSetDouble02); TEST_CASE(testSetLong01); TEST_CASE(testSetLong02); TEST_CASE(testSetString01); TEST_CASE(testSetString02); #ifdef __SET_TIME_ADDED_ TEST_CASE(testSetTime01); TEST_CASE(testSetTime02); #endif #ifdef __SET_TIMESTAMP_ADDED_ TEST_CASE(testSetTimestamp01); TEST_CASE(testSetTimestamp02); #endif #ifdef __SET_BIG_DECIMAL_ADDED_ TEST_CASE(testSetBigDecimal01); TEST_CASE(testSetBigDecimal02); #endif #ifdef __SET_FLOAT_ADDED_ TEST_CASE(testSetFloat01); TEST_CASE(testSetFloat02); #endif #ifdef __SET_BYTE_ADDED_ TEST_CASE(testSetByte01); TEST_CASE(testSetByte02); #endif #ifdef __SET_SHORT_ADDED_ TEST_CASE(testSetShort01); TEST_CASE(testSetShort02); #endif #ifdef __SET_FLOAT_ADDED_ TEST_CASE(testSetFloat010101); TEST_CASE(testSetFloat020202); #endif #ifdef __SET_DATE_ADDED_ TEST_CASE(testSetDate01); TEST_CASE(testSetDate02); #endif #ifdef __SET_NULL_ADDED_ TEST_CASE(testSetNull01); TEST_CASE(testSetNull02); TEST_CASE(testSetNull03); TEST_CASE(testSetNull04); // Assuming that set/getTiem and Timestamp will be added along w/ setDate #ifdef __SET_DATE_ADDED_ TEST_CASE(testSetNull05); TEST_CASE(testSetNull06); TEST_CASE(testSetNull07); #endif #ifdef __SET_BIG_DECIMAL_ADDED_ TEST_CASE(testSetNull08); #endif TEST_CASE(testSetNull10); TEST_CASE(testSetNull11); TEST_CASE(testSetNull12); TEST_CASE(testSetNull13); #ifdef _WE_HAVE_SOME_REAL_TYPE TEST_CASE(testSetNull14); #endif #ifdef __SET_BIG_DECIMAL_ADDED_ TEST_CASE(testSetNull15); #endif #ifdef __SET_BYTE_ADDED_ TEST_CASE(testSetNull09); TEST_CASE(testSetNull16); TEST_CASE(testSetNull17); TEST_CASE(testSetNull18); #endif #endif } /* * @testName: testGetMetaData * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The getMetadata() method returns a valid ResultSetMetaData Object * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the getMetaData() method and get the number of columns using * getColumnCount() method of ResultSetMetaData.Execute a query using * executeQuery() method and get the number of columns. Both the values * should be equal or it should throw an SQL exception. * */ /* throws std::exception * */ void testGetMetaData(); /* * @testName: testClearParameters * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 * API Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The method clearParameters() clears the values set for the * PreparedStatement object's IN parameters and releases the * resources used by those values. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Call the clearParameters() method.Call the executeQuery() method * to check if the call to clearParameters() clears the IN parameter * set by the Prepared Statement object. */ /* throws std::exception * */ void testClearParameters(); /* * @testName: testExecute01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The execute()method executes the SQL statement contained in * the Prepared Statement object and indicates whether the first * result is a resultset,an update count,or there are no results. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement * object. Execute the precompiled SQL Statement of deleting a row. * It should return a boolean value and the value should be equal to * false. (See JDK 1.2.2 API documentation) * */ /* throws std::exception * */ void testExecute01(); /* * @testName: testExecute02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 * API Reference & Tutorial,Second Edition) * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The execute()method executes the SQL statement contained in the * Prepared Statement object and indicates whether the first result * is a resultset,an update count,or there are no results. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Execute the precompiled SQL Statement by calling executeQuery() * method with a non-existent row.Call ResultSet.next() method. * It should return a boolean value and the value should be equal * to false. (See JDK 1.2.2 API documentation) * */ /* throws std::exception * */ void testExecute02(); /* * @testName: testExecute03 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * edition(J2EE) specification v 1.2). * * The execute() method executes the SQL statement contained in * the Prepared Statement object and indicates whether the first * result is a resultset,an update count,or there are no results. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling execute() method * without setting the parameters.An SQL std::exception * must be thrown. * (See JDK 1.2.2 API documentation) * */ /* throws std::exception * */ void testExecute03(); /* * @testName: testExecuteQuery01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 * API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeQuery() method executes SQL query in this * PreparedStatement object and returns the result set generated * by the query.(See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Execute the precompiled SQL Statement by calling executeQuery() * method. It should return a ResultSet object. * */ /* throws std::exception * */ void testExecuteQuery01(); /* * @testName: testExecuteQuery02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeQuery() method executes SQL query in this * PreparedStatement object and returns the result set generated * by the query. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement object. * Execute the precompiled SQL Statement by calling executeQuery() * method with a non existent row. A call to ResultSet.next() * should return a false value. */ /* throws std::exception * */ void testExecuteQuery02(); /* * @testName: testExecuteQuery03 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters).(See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeQuery() method executes SQL query in this * PreparedStatement object and returns the result set generated * by the query. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the * database. Execute the precompiled SQL Statement by calling * executeQuery() method without setting the parameters. * It should throw a SQL std::exception *. */ /* throws std::exception * */ void testExecuteQuery03(); /* * @testName: testExecuteUpdate01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements. It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeUpdate(String sql) method executes an SQL Insert, * Update or Delete Statement and returns the number of rows that * were affected.It can also be used to execute SQL statements * that have no return value such as DDL statements that create * or drop tables. (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the * database. Set the value for the IN parameter of the PreparedStatement * object. Execute the precompiled SQL Statement by calling * executeUpdate() method. It should return an integer * value indicating the number of rows that were affected. * (The value could be zero if zero rows are affected). */ /* throws std::exception * */ void testExecuteUpdate01(); /* * @testName: testExecuteUpdate02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters) (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeUpdate() method executes an SQL Insert, * Update or Delete Statement and returns the number of rows that * were affected.It can also be used to execute SQL statements * that have no return value such as DDL statements that create * or drop tables.(The value could be zero if zero rows are affected). * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Set the value for the IN parameter of the Prepared Statement * object. Execute the precompiled SQL Statement by calling * executeUpdate() method with a non existent row. * It should return an Integer value. */ /* throws std::exception * */ void testExecuteUpdate02(); /* * @testName: testExecuteUpdate03 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The executeUpdate() method executes an SQL Insert,Update or * Delete Statement and returns the number of rows that were affected. * It can also be used to execute SQL statements that have no * return value such as DDL statements that create or drop tables. * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement without setting the IN parameter. * It should throw an SQL exception. */ /* throws std::exception * */ void testExecuteUpdate03(); /* * @testName: testSetBigDecimal01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition). * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBigDecimal(int parameterIndex, BigDecimal x) method * sets the parameterIndex to x which is an instance of * java.math.BigDecimal class. The Driver converts this to a * JDBC Numeric Value when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference,2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled.SQL Statement by calling the * setBigDecimal(int parameterindex, BigDecimal x) method for updating * the value of column MIN_VAL in Numeric_Tab.Check first * the return value of executeUpdate() method used is equal to 1. * Call the ResultSet.getBigDecimal(int columnIndex)method. * Check if returns the BigDecimal Value that has been set. */ /* throws std::exception * */ // void testSetBigDecimal01(); /* * @testName: testSetBigDecimal02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters) (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBigDecimal(int parameterIndex, BigDecimal x) method * sets the parameterIndex to x which is an instance of * java.math.BigDecimal class.The Driver converts this to a JDBC * Numeric Value when it sends it to the database.(See section * 24.3.2 of JDBC 2.0 API Tutorial & Reference, Second Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setBigDecimal(int parameterindex, BigDecimal x) method for updating * the value of column NULL_VAL in Numeric_Tab. Call the * ResultSet.getBigDecimal(int columnIndex) method. Check if * returns the BigDecimal Value that has been set. */ /* throws std::exception * */ // void testSetBigDecimal02(); /* * @testName: testSetBoolean01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition). * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBoolean(int parameterIndex, boolean x) method sets the * parameterIndex to x, a Java boolean value.The driver converts * this to JDBC BIT value when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference, 2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setBoolean(int parameterIndex, boolean x) to set MAX_VAL * column of Bit_tab to the boolean value x. * Call the ResultSet.getBoolean(int columnIndex) method to check * if it returns the boolean Value that has been set. * */ /* throws std::exception * */ void testSetBoolean01(); /* * @testName: testSetBoolean02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setBoolean(int parameterIndex, boolean x) method sets the * parameterIndex to x, a Java boolean value.The driver converts this * to JDBC BIT value when it sends it to the database. (See section * 24.3.2 of JDBC 2.0 API Tutorial & Reference, Second Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the method * setBoolean(int parameterIndex, boolean x) to set NULL_VAL * column of Bit_tab to the boolean value x. * Call the ResultSet.getBoolean(int columnIndex) method to * check if it returns the boolean Value that has been set. */ /* throws std::exception * */ void testSetBoolean02(); /* * @testName: testSetByte01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setByte(int parameterIndex, byte x) method sets the parameter * number parameterIndex to x,a Java byte value.The Driver converts * this to a JDBC Tinyint value when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference, 2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setByte(int parameterindex, byte x) method for updating MAX_VAL * column of Tinyint_Tab. Call the ResultSet.getByte(int columnIndex) * method to check if it returns the byte Value that has been set. */ /* throws std::exception * */ void testSetByte01(); /* * @testName: testSetByte02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setByte(int parameterIndex, byte x) method sets the parameter * number parameterIndex to x,a Java byte value. The Driver converts * this to a JDBC Tinyint value when it sends it to the database. * (See section 24.3.2 of JDBC 2.0 API Tutorial & Reference,2nd Edition) * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Execute the precompiled SQL Statement by calling the * setByte(int parameterindex, byte x) method for updating NULL_VAL * column of Tinyint_Tab. Call the ResultSet.getByte(int columnIndex) * method,to check if it returns the byte Value that has been set. */ /* throws std::exception * */ void testSetByte02(); /* * @testName: testSetFloat01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setFloat(int parameterIndex, float x) method sets the parameter * number parameterIndex to x ,a Java float value. The Driver converts * this to a JDBC REAL when it sends it to the database. (See section * 24.3.2 of JDBC 2.0 API Tutorial & Reference,2nd Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling the * setFloat(int parameterindex, float x) method for updating * the MAX_VAL column of Float_Tab. Call the * ResultSet.getFloat(int columnIndex) * method to check if it returns the float Value that has been set. * */ /* throws std::exception * */ void testSetFloat010101(); /* * @testName: testSetFloat02 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements.It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setFloat(int parameterIndex, float x) method sets the * parameter number parameterIndex to x ,a Java float value. * The Driver converts this to a JDBC REAL when it sends it to * the database. (See section 24.3.2 of JDBC 2.0 API Tutorial & * Reference, Second Edition). * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling the * setFloat(int parameterindex, float x) method for updating the * NULL_VAL column of Float_Tab. Call the * ResultSet.getFloat(int columnIndex) method to check if it returns * the float Value that has been set. * */ /* throws std::exception * */ void testSetFloat020202(); /* * @testName: testSetInt01 * @assertion: A Prepared Statement object provides a way of calling precompiled * SQL statements. It can take one or more parameters as input * arguments(IN parameters). (See section 11.1.6 of JDBC 2.0 API * Reference & Tutorial,Second Edition) * * The JDBC drivers must provide full support for PreparedStatement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setInt(int parameterIndex, int x) method sets the parameter * number parameterIndex to x ,a Java int value. The Driver converts * this to a JDBC INTEGER when it sends it to the database. (See * section 24.3.2 of JDBC 2.0 API Tutorial & Reference, 2nd Edition) * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling the * setInt(int parameterindex, int x) method for updating the MAX_VAL * column of Integer_Tab. Call the ResultSet.getInt(int columnIndex) * method to check if it returns the integer Value that has been set. * */ /* throws std::exception * */ void testSetInt01(); /* * @testName: testSetInt02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setInt(int parameterIndex,int x) method sets parameter number * parameterIndex to Java int value x. The driver converts this to an * SQL INTEGER value when it sends it to the Database * (See JDK 1.2.2 API documentation) * * @test_Strategy: Get a PreparedStatement object from the connection to the database * Using setInt(int parameterIndex,int x),update the column with the maximum * value of Integer_Tab. Now execute a query to get the maximum value and * retrieve the result of the query using the getInt(int columnIndex) method * Compare the returned value, with the maximum value extracted from the * ctssql.stmt file. Both of them should be equal */ /* throws std::exception * */ void testSetInt02(); /* * @testName: testSetDate01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDate(int parameterIndex,Date x) method sets parameter * number parameterIndex to java.sql.Date value x. The driver * converts this to an SQL DATE value when it sends it to the database * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling setDate(int parameterIndex,Date x) * method and call the ResultSet.getDate(int) method to check and * it should return a String Value that it is been set */ /* throws std::exception * */ void testSetDate01(); /* * @testName: testSetDate02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDate(int parameterIndex,Date x,Calendar cal) method * sets the designated parameter to the given java.sql.Date value, * using the given Calendar object. The driver uses the Calendar * object to construct an SQL DATE value, which the driver then sends * to the database. With a a Calendar object, the driver can calculate * the date taking into account a custom timezone. If no Calendar * object is specified, the driver uses the default timezone, which * is that of the virtual machine running the application. * * @test_Strategy: Get a PreparedStatement object from the connection to the database * execute the precompiled SQL Statement by calling * setDate(int parameterIndex,Date x,Calendar cal) method * and call the ResultSet.getDate(int) method to check and * it should return a String Value that it is been set */ /* throws std::exception * */ void testSetDate02(); /* * @testName: testSetDouble01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDouble(int parameterIndex, double x) method Sets the * designated parameter to a Java double value. The driver converts * this to an SQL DOUBLE value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database * Using setDouble(int parameterIndex,double x),update the column the * minimum value of Double_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getDouble(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetDouble01(); /* * @testName: testSetDouble02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setDouble(int parameterIndex, double x) method Sets the * designated parameter to a Java double value. The driver converts * this to an SQL DOUBLE value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setDouble(int parameterIndex,double x),update the column * the maximum value of Double_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getDouble(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetDouble02(); /* * @testName: testSetLong01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setLong(int parameterIndex, long x) method Sets the * designated parameter to a Java long value. The driver converts * this to an SQL BIGINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setLong(int parameterIndex,long x),update the column the * minimum value of Bigint_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getLong(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetLong01(); /* * @testName: testSetLong02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setLong(int parameterIndex, long x) method Sets the * designated parameter to a Java long value. The driver converts * this to an SQL BIGINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setLong(int parameterIndex,long x),update the column the * maximum value of Bigint_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getLong(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetLong02(); /* * @testName: testSetShort01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setShort(int parameterIndex, short x) method Sets the * designated parameter to a Java short value. The driver converts * this to an SQL SMALLINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setShort(int parameterIndex,short x),update the column the * minimum value of Smallint_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getShort(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetShort01(); /* * @testName: testSetShort02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setShort(int parameterIndex, short x) method Sets the * designated parameter to a Java short value. The driver converts * this to an SQL SMALLINT value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setShort(int parameterIndex,short x),update the column the * maximum value of Smallint_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getShort(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetShort02(); /* * @testName: testSetString01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setString(int parameterIndex, String x) method sets the designated * parameter to a Java String value. The driver converts this to an * SQL VARCHAR or LONGVARCHAR value (depending on the argument's size * relative to the driver's limits on VARCHAR values) when it sends * it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setString(int parameterIndex, String x) method,update the * column value with the maximum value of Char_Tab. Call the * getString(String columnName) method to retrieve this value. Extract * the maximum value from the ctssql.stmt file. Compare this value * with the value returned by the getString(String columnName) method. * Both the values should be equal. */ /* throws std::exception * */ void testSetString01(); #ifdef __SET_TIME_ADDED_ /* * @testName: testSetTime01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTime(int parameterIndex, Time x) method sets the * designated parameter to a java.sql.Time value. The driver * converts this to an SQL TIME value when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTime(int parameterIndex, Time x) method,update the * column value with the Non-Null Time value. Call the getTime(int columnno) * method to retrieve this value. Extract the Time value * from the ctssql.stmt file. Compare this value with the value returned * by the getTime(int columnno) method. Both the values should be equal */ /* throws std::exception * */ void testSetTime01(); /* * @testName: testSetTime02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTime(int parameterIndex, String x, Calendar cal) method sets the * designated parameter to the given java.sql.Time value, using the given * Calendar object. The driver uses the Calendar object to construct an * SQL TIME value, which the driver then sends to the database. With a Calendar * object, the driver can calculate the time taking into account a custom * timezone. If no Calendar object is specified, the driver uses the default * timezone, which is that of the virtual machine running the application. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTime(int parameterIndex, Time x, Calendar cal) method,update the * column value with the Non-Null Time value using the Calendar Object. Call the * getTime(int columnno) method to retrieve this value. Extract the Time value * from the ctssql.stmt file. Compare this value with the value returned * by the getTime(int columnno) method. Both the values should be equal. */ /* throws std::exception * */ void testSetTime02(); #endif #ifdef __SET_TIMESTAMP_ADDED_ /* * @testName: testSetTimestamp01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTimestamp(int parameterIndex,Timestamp x) method sets * the designated parameter to a java.sql.Timestamp value. * The driver converts this to an SQL TIMESTAMP value when it * sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTimestamp(int parameterIndex, Timestamp x) method,update the * column value with the Non-Null Timestamp value. Call the getTimestamp(int columnno) * method to retrieve this value. Extract the Timestamp value * from the ctssql.stmt file. Compare this value with the value returned * by the getTimestamp(int columnno) method. Both the values should be equal. */ /* throws std::exception * */ void testSetTimestamp01(); /* * @testName: testSetTimestamp02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setTimestamp(int parameterIndex, String x, Calendar cal) method sets the * designated parameter to the given java.sql.Timestamp value, using the given * Calendar object. The driver uses the Calendar object to construct an * SQL TIMESTAMP value, which the driver then sends to the database. With a Calendar * object, the driver can calculate the time taking into account a custom * timezone. If no Calendar object is specified, the driver uses the default * timezone, which is that of the virtual machine running the application. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using the setTimestamp(int parameterIndex, Time x, Calendar cal) method,update the * column value with the Non-Null Timestamp value using the Calendar Object. Call the * getTimestamp(int columnno) method to retrieve this value. Extract the Timestamp value * from the ctssql.stmt file. Compare this value with the value returned * by the getTimestamp(int columnno) method. Both the values should be equal. */ /* throws std::exception * */ void testSetTimestamp02(); #endif /* * @testName: testSetString02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setString(int parameterIndex, String x) method sets the designated * parameter to a Java String value. The driver converts this to an * SQL VARCHAR or LONGVARCHAR value (depending on the argument's size * relative to the driver's limits on VARCHAR values) when it sends * it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setString(int parameterIndex, String x),update the column * with the maximum value which is a SQL VARCHAR. Call the * getString(int ColumnIndex) method to retrieve this value. Extract * the maximum value as a String from the ctssql.stmt file. * Compare this value with the value returned by the getString method. * Both the values should be equal. */ /* throws std::exception * */ void testSetString02(); #ifdef __SET_FLOAT_ADDED_ /* * @testName: testSetFloat01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setFloat(int parameterIndex, float x) sets the designated parameter * to a Java float value. The driver converts this to an SQL FLOAT value * when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setFloat(int parameterIndex,float x),update the column with the * minimum value of Real_Tab. * Now execute a query to get the minimum value and retrieve the result * of the query using the getFloat(int columnIndex) method.Compare the * returned value, with the minimum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetFloat01(); /* * @testName: testSetFloat02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setFloat(int parameterIndex, float x) sets the designated parameter * to a Java float value. The driver converts this to an SQL FLOAT value * when it sends it to the database. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * Using setFloat(int parameterIndex,float x),update the column with the * maximum value of Real_Tab. * Now execute a query to get the maximum value and retrieve the result * of the query using the getFloat(int columnIndex) method.Compare the * returned value, with the maximum value extracted from the ctssql.stmt file. * Both of them should be equal. */ /* throws std::exception * */ void testSetFloat02(); #endif #ifdef __SET_NULL_ADDED_ /* * @testName: testSetNull01 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for INTEGER Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull01(); /* * @testName: testSetNull02 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for FLOAT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull02(); /* * @testName: testSetNull03 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for SMALLINT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull03(); /* * @testName: testSetNull04 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for CHAR Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull04(); /* * @testName: testSetNull05 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2) * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for TIME Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull05(); /* * @testName: testSetNull06 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for TIMESTAMP Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull06(); /* * @testName: testSetNull07 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for DATE Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull07(); /* * @testName: testSetNull08 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for NUMERIC Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull08(); /* * @testName: testSetNull09 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for TINYINT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull09(); /* * @testName: testSetNull10 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for DOUBLE Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull10(); /* * @testName: testSetNull11 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for BIGINT Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. */ /* throws std::exception * */ void testSetNull11(); /* * @testName: testSetNull12 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for Varchar Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull12(); /* * @testName: testSetNull13 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for LONGVARCHAR Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull13(); /* * @testName: testSetNull14 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for REAL Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull14(); /* * @testName: testSetNull15 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for DECIMAL Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull15(); /* * @testName: testSetNull16 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for BINARY Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull16(); /* * @testName: testSetNull17 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for VARBINARY Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull17(); /* * @testName: testSetNull18 * @assertion: A Prepared Statement object provides a way of calling * precompiled SQL statements.It can take one or more parameters * as input arguments(IN parameters). (See section 11.1.6 of * JDBC 2.0 API Reference & Tutorial,Second Edition) * * The drivers must provide full support for Prepared Statement * methods. (See section 6.2.2.3 of Java2 Platform Enterprise * Edition(J2EE) specification v 1.2). * * The setNull(int parameterIndex, int sqlType) method sets the * designated parameter to SQL NULL(the generic SQL NULL defined in * java.sql.Types). Note that the JDBC type of the parameter to be * set to JDBC NULL must be specified. * * @test_Strategy: Get a PreparedStatement object from the connection to the database. * execute the precompiled SQL Statement to set the value as SQL Null * for LONGVARBINARY Type and retrieve the same value by executing a query. Call * the ResultSet.wasNull() method to check it. It should return a true value. * */ /* throws std::exception * */ void testSetNull18(); #endif }; REGISTER_FIXTURE(PreparedStatementTest); } //namespace compliance } //namespace testsuite mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/ResultSetMetadataTest.cpp000644 015771 000012 00000121712 12645244437 031044 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ResultSetMetadataTest.h" namespace testsuite { namespace compliance { /* * @testName: testGetCatalogName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getCatalogName(int colindex) method returns a String * object representing the catalog name or an empty string ("") * if not applicable. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getCatalogName(int colindex) method.It should return a String object. */ /* throws Exception */ void ResultSetMetadataTest::testGetCatalogName() { logMsg("Calling getCatalogName on ResultSetMetadata"); String sRetValue=rsmd->getCatalogName(1); if (sRetValue.empty()) { logMsg("getCatalogName method does not return the column's table's catalog name"); } else { logMsg(String("getCatalogName method returns: ") + sRetValue); } } /* * @testName: testGetColumnClassName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnClassName(int colindex) method returns a String * object representing the fully qualified name of the Java class * to which a value in the designated column will be mapped. * (See section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnClassName(int colindex) method.It should return a * String object. */ /* throws Exception */ /* Not Implemented in C/C++ (not even part of interface at the moment) */ void ResultSetMetadataTest::testGetColumnClassName() { #ifdef getColumnClassName_IMPLEMENTED logMsg("Calling getColumnClassName on ResultSetMetadata"); String sRetValue=rsmd->getColumnClassName(1); if (sRetValue == NULL) { logMsg( "getColumnClassName method does not returns the fully-qualified name of the class"); } else { logMsg(String("getColumnClassName method returns: ") + sRetValue); } #endif } /* * @testName: testGetColumnCount * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnCount method returns an integer value representing the * number of columns in the ResultSet object.for which this ResultSetMetaData * object stores information. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the getColumnCount() * method on the ResultSetMetaData object.It should return an integer * value greater than or equal to zero. */ /* throws Exception */ void ResultSetMetadataTest::testGetColumnCount() { logMsg("Calling getColumnCount on ResultSetMetaData"); int coloumnCount=rsmd->getColumnCount(); if (coloumnCount >= 0) { TestsListener::messagesLog() << "getColumnCount method returns: " << coloumnCount << std::endl; } else { logErr(" getColumnCount method returns a negative value"); } } /* * @testName: testGetColumnDisplaySize * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications.None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnDisplaySize(int colindex) method returns an int value * representing the maximum width in characters. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnDisplaySize(int colindex) method.It should return an integer * representing the normal maximum width in characters for column colindex. */ /* throws Exception */ void ResultSetMetadataTest::testGetColumnDisplaySize() { /*try {*/ logMsg("Calling getColumnDisplaySize on ResultSetMetaData"); int colDispSize=rsmd->getColumnDisplaySize(2); if (colDispSize >= 0) { TestsListener::messagesLog() << "getColumnDisplaySize method returns: " << colDispSize << std::endl; } else { logErr(" getColumnDisplaySize method returns a negative value"); } /*} catch (sql::DbcException & sqle) { FAIL("Call to getColumnDisplaySize is Failed!"); }*/ /*catch (std::exception & e) { logErr(String( "Unexpected exception " ) + e.what()); FAIL("Call to getColumnDisplaySize is Failed!"); }*/ } /* * @testName: testGetColumnLabel * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnLabel(int colindex) method returns a String * object representing the suggested title for use in printouts * and displays. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnLabel(int colindex) method.It should return a String object. */ /* throws Exception */ void ResultSetMetadataTest::testGetColumnLabel() { logMsg("Calling getColumnLabel on ResultSetMetadata"); String sRetValue=rsmd->getColumnLabel(2); //"getColumnLabel method does not returns the suggested column title"); logMsg(String("getColumnLabel method returned: ") + sRetValue); } /* * @testName: testGetColumnName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnName(int colindex) method returns a String * object representing the column name (See JDK 1.2.2 API * documentation) * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnName(int colindex) method.It should return a String object. */ /* throws Exception */ void ResultSetMetadataTest::testGetColumnName() { logMsg("Calling getColumnName on ResultSetMetadata"); String sRetValue=rsmd->getColumnName(2); logMsg(String("getColumnName method returns: ") + sRetValue); //catch (sql::DbcInvalidArgument * sqle) //{ // logMsg( String("Invalid argument exception caught") + sqle->what() ); } /* * @testName: testGetColumnType * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnType(int colindex) method returns the JDBC type from * the java.sql.Types class for the value in the designated column colindex. * (See section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnType(int colindex) method.Check if an integer value is returned. */ /* throws Exception */ void ResultSetMetadataTest::testGetColumnType() { logMsg("Calling getColumnType on ResultSetMetaData"); int colType=rsmd->getColumnType(1); switch (colType) { case sql::DataType::BIT : case sql::DataType::TINYINT : case sql::DataType::SMALLINT : case sql::DataType::INTEGER : case sql::DataType::BIGINT : // case sql::DataType::FLOAT : case sql::DataType::REAL : case sql::DataType::DOUBLE : case sql::DataType::NUMERIC : case sql::DataType::DECIMAL : case sql::DataType::CHAR : case sql::DataType::VARCHAR : case sql::DataType::LONGVARCHAR : case sql::DataType::DATE : case sql::DataType::TIME : case sql::DataType::TIMESTAMP : case sql::DataType::BINARY : case sql::DataType::VARBINARY : case sql::DataType::LONGVARBINARY : case sql::DataType::SQLNULL : // case sql::DataType::OTHER : // case sql::DataType::JAVA_OBJECT: // case sql::DataType::DISTINCT : // case sql::DataType::STRUCT : // case sql::DataType::ARRAY : // case sql::DataType::BLOB : // case sql::DataType::CLOB : // case sql::DataType::REF : TestsListener::messagesLog() << "getColumnType method returns: " << colType << std::endl; break; default: TestsListener::errorsLog() << "getColumnType method returns a illegal value " << colType << std::endl; FAIL("Call to getColumnTypeName failed !"); } } /* * @testName: testGetColumnTypeName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnTypeName(int colindex) method returns a String * object representing the type name used by the database. * (See section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnTypeName(int colindex) method.It should return a * String object. */ /* throws Exception */ void ResultSetMetadataTest::testGetColumnTypeName() { logMsg("Calling getColumnTypeName on ResultSetMetadata"); String sRetValue=rsmd->getColumnTypeName(1); logMsg(String("getColumnTypeName method returns: ") + sRetValue); } /* * @testName: testGetPrecision * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getPrecision(int colindex) method returns an integer value * representing the number of decimal digits for number types,maximum * length in characters for character types,maximum length in bytes * for JDBC binary datatypes. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getPrecision(int colindex) method.It should return an integer greater * than or equal to zero. */ /* throws Exception */ void ResultSetMetadataTest::testGetPrecision() { logMsg("Calling getPrecision on ResultSetMetaData"); int precisionSize=rsmd->getPrecision(1); if (precisionSize >= 0) { TestsListener::messagesLog() << "getPrecision method returns: " << precisionSize << std::endl; } else { logErr(" getPrecision method returns a negative value"); } } /* * @testName: testGetScale * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getScale(int colindex) method returns an integer value * representing the number of digits to right of the decimal point. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the getScale(int colindex) * method.It should return an integer greater than or equal to zero. */ /* throws Exception */ void ResultSetMetadataTest::testGetScale() { logMsg("Calling getScale on ResultSetMetaData"); int scaleSize=rsmd->getScale(2); if (scaleSize >= 0) { TestsListener::messagesLog() << "getScale method returns: " << scaleSize << std::endl; } else { logErr(" getScale method returns a negative value"); } } /* * @testName: testGetSchemaName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getSchemaName(int colindex) method returns a String * object representing the schema name or an empty string ("") * if the DBMS.does not support this feature. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getSchemaName(int colindex) method.It should return a String object. */ /* throws Exception */ void ResultSetMetadataTest::testGetSchemaName() { logMsg("Calling getSchemaName on ResultSetMetadata"); String sRetValue=rsmd->getSchemaName(2); logMsg(String("getSchemaName returns: ") + sRetValue); } /* * @testName: testGetTableName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getTableName(int colindex) method returns a String * object representing the table name or an empty string ("") * if the DBMS does not support this feature. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the getTableName(int colindex) * method.It should return a String object. */ /* throws Exception */ void ResultSetMetadataTest::testGetTableName() { logMsg("Calling getTableName on ResultSetMetadata"); String sRetValue=rsmd->getTableName(1); logMsg(String("getTableName method returns: ") + sRetValue); } /* * @testName: testIsAutoIncrement * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isAutoIncrement(int colindex) method returns a boolean value; * true if the column colindex is automatically numbered which makes * the column read-only and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isAutoIncrement(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsAutoIncrement() { logMsg("Calling isAutoIncrement on ResultSetMetaData"); bool retValue=rsmd->isAutoIncrement(1); if (retValue) { logMsg( "isAutoIncrement method returns column is automatically numbered"); } else { logMsg( "isAutoIncrement method returns column cannot be automatically numbered"); } } /* @testName: testIsCaseSensitive * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isCaseSensitive(int colindex) method returns a boolean value; * true if the column colindex is case sensitive and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isCaseSensitive(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsCaseSensitive() { logMsg("Calling isCaseSensitive on ResultSetMetaData"); bool retValue=rsmd->isCaseSensitive(1); if (retValue) { logMsg( "isCaseSensitive method returns column's are case sensitive"); } else { logMsg( "isCaseSensitive method returns column's are case insensitive"); } } /* @testName: testIsCurrency * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isCurrency(int colindex) method returns a boolean value; * true if the column colindex is a cash value and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isCurrency(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsCurrency() { logMsg("Calling IsCurrency on ResultSetMetaData"); bool retValue=rsmd->isCurrency(2); if (retValue) { logMsg("isCurrency method returns column is a cash value"); } else { logMsg( "isCurrency method returns column does not contains a cash value"); } } /* * @testName: testIsDefinitelyWritable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isDefinitelyWritable(int colindex) method returns a boolean value; * true if the write on column colindex will definitely succeed * and false otherwise. (See JDK 1.2.2 API documentation) * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * isDefinitelyWritable(int column) method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsDefinitelyWritable() { logMsg("Calling isDefinitelyWritable on ResultSetMetaData"); bool retValue=rsmd->isDefinitelyWritable(1); if (retValue) { logMsg( "isDefinitelyWritable method returns write on the column is definitely succeed"); } else { logMsg( "isDefinitelyWritable method returns write on the column is definitely failed"); } } /* * @testName: testIsNullable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isNullable(int colindex) method returns an integer value * the possible values are columnNoNulls, columnNullable and * columnNullableUnknown. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isNullable(int column) * method.It should return an integer value which is one of the constants * columnNoNulls(0),columnNullable(1) and columnNullableUnknown(2). */ /* throws Exception */ void ResultSetMetadataTest::testIsNullable() { logMsg("Calling isNullable on ResultSetMetaData"); int coloumnCount=rsmd->isNullable(2); if ((coloumnCount == sql::ResultSetMetaData::columnNoNulls) || (coloumnCount == sql::ResultSetMetaData::columnNullable) || (coloumnCount == sql::ResultSetMetaData::columnNullableUnknown)) { TestsListener::messagesLog() << "isNullable method returns: " << coloumnCount << std::endl; } else { logErr(" isNullable method returns a negative value"); } } /* * @testName: testIsReadOnly * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isReadOnly(int colindex) method returns a boolean value; * true if the column colindex is definitely not writable and false * otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isReadOnly(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsReadOnly() { logMsg("Calling isReadOnly on ResultSetMetaData"); bool retValue=rsmd->isReadOnly(1); if (retValue) { logMsg("isReadOnly method returns column cannot be writable"); } else { logMsg("isReadOnly method returns column can be writable"); } } /* * @testName: testIsSearchable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isSearchable(int colindex) method returns a boolean value; * true if the value stored in column colindex can be used in a * WHERE clause and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isSearchable(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsSearchable() { logMsg("Calling isSearchable on ResultSetMetaData"); bool retValue=rsmd->isSearchable(1); if (retValue) { logMsg( "isSearchable method returns column can be used in a where clause"); } else { logMsg( "isSearchable method returns column cannot be used in a where clause"); } } /* @testName: testIsSigned * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isSigned(int colindex) method returns a boolean value; * true if the value stored in column colindex is a signed number * and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isSigned(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsSigned() { logMsg("Calling isSigned on ResultSetMetaData"); bool retValue=rsmd->isSigned(2); if (retValue) { logMsg( "isSigned method returns values in the column are signed numbers"); } else { logMsg( "isSigned method returns values in the column are isUnsigned numbers"); } } /* * @testName: testIsWritable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isWritable(int colindex) method returns a boolean value; * true if the column colindex is possible for write and false * otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isWritable(int column) * method.It should return a boolean value. */ /* throws Exception */ void ResultSetMetadataTest::testIsWritable() { logMsg("Calling isWritable on ResultSetMetaData"); bool retValue=rsmd->isWritable(1); if (retValue) { logMsg("isWritable method returns column is writable"); } else { logMsg("isWritable method returns column cannot be writable"); } } /** * @see junit.framework.TestCase#setUp() */ /* throws Exception */ void ResultSetMetadataTest::setUp() { super::setUp(); createStandardTable(TABLE_CTSTABLE2); Properties::const_iterator cit=sqlProps.find("ftable"); String fTableName; if (cit != sqlProps.end()) { fTableName=cit->second; } query=String("SELECT COF_NAME, PRICE FROM ") + fTableName; stmt.reset(conn->createStatement(/*sql::ResultSet::TYPE_SCROLL_INSENSITIVE,sql::ResultSet::CONCUR_READ_ONLY*/ )); rs.reset(stmt->executeQuery(query)); rsmd = rs->getMetaData(); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/ResultSetMetadataTest.h000644 015771 000012 00000105600 12645244437 030507 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /** * @author mmatthew * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ namespace testsuite { namespace compliance { class ResultSetMetadataTest : public BaseTestFixture { private: typedef BaseTestFixture super; ResultSetMetaData rsmd; String query; protected: /** * @see junit.framework.TestCase#setUp() */ /* throws std::exception * */ void setUp(); public: TEST_FIXTURE(ResultSetMetadataTest) { TEST_CASE(testGetCatalogName); TEST_CASE(testGetColumnClassName); TEST_CASE(testGetColumnCount); TEST_CASE(testGetColumnDisplaySize); TEST_CASE(testGetColumnLabel); TEST_CASE(testGetColumnName); TEST_CASE(testGetColumnType); TEST_CASE(testGetColumnTypeName); TEST_CASE(testGetPrecision); TEST_CASE(testGetScale); TEST_CASE(testGetSchemaName); TEST_CASE(testGetTableName); TEST_CASE(testIsAutoIncrement); TEST_CASE(testIsCaseSensitive); TEST_CASE(testIsCurrency); TEST_CASE(testIsDefinitelyWritable); TEST_CASE(testIsNullable); TEST_CASE(testIsReadOnly); TEST_CASE(testIsSearchable); TEST_CASE(testIsSigned); TEST_CASE(testIsWritable); } /* * @testName: testGetCatalogName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getCatalogName(int colindex) method returns a String * object representing the catalog name or an empty string ("") * if not applicable. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getCatalogName(int colindex) method.It should return a String object. */ /* throws std::exception * */ void testGetCatalogName(); /* * @testName: testGetColumnClassName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnClassName(int colindex) method returns a String * object representing the fully qualified name of the Java class * to which a value in the designated column will be mapped. * (See section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnClassName(int colindex) method.It should return a * String object. */ /* throws std::exception * */ void testGetColumnClassName(); /* * @testName: testGetColumnCount * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnCount method returns an integer value representing the * number of columns in the ResultSet object.for which this ResultSetMetaData * object stores information. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the getColumnCount() * method on the ResultSetMetaData object.It should return an integer * value greater than or equal to zero. */ /* throws std::exception * */ void testGetColumnCount(); /* * @testName: testGetColumnDisplaySize * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications.None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnDisplaySize(int colindex) method returns an int value * representing the maximum width in characters. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnDisplaySize(int colindex) method.It should return an integer * representing the normal maximum width in characters for column colindex. */ /* throws std::exception * */ void testGetColumnDisplaySize(); /* * @testName: testGetColumnLabel * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnLabel(int colindex) method returns a String * object representing the suggested title for use in printouts * and displays. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnLabel(int colindex) method.It should return a String object. */ /* throws std::exception * */ void testGetColumnLabel(); /* * @testName: testGetColumnName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnName(int colindex) method returns a String * object representing the column name (See JDK 1.2.2 API * documentation) * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnName(int colindex) method.It should return a String object. */ /* throws std::exception * */ void testGetColumnName(); /* * @testName: testGetColumnType * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnType(int colindex) method returns the JDBC type from * the java.sql.Types class for the value in the designated column colindex. * (See section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnType(int colindex) method.Check if an integer value is returned. */ /* throws std::exception * */ void testGetColumnType(); /* * @testName: testGetColumnTypeName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getColumnTypeName(int colindex) method returns a String * object representing the type name used by the database. * (See section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getColumnTypeName(int colindex) method.It should return a * String object. */ /* throws std::exception * */ void testGetColumnTypeName(); /* * @testName: testGetPrecision * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getPrecision(int colindex) method returns an integer value * representing the number of decimal digits for number types,maximum * length in characters for character types,maximum length in bytes * for JDBC binary datatypes. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getPrecision(int colindex) method.It should return an integer greater * than or equal to zero. */ /* throws std::exception * */ void testGetPrecision(); /* * @testName: testGetScale * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getScale(int colindex) method returns an integer value * representing the number of digits to right of the decimal point. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the getScale(int colindex) * method.It should return an integer greater than or equal to zero. */ /* throws std::exception * */ void testGetScale(); /* * @testName: testGetSchemaName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getSchemaName(int colindex) method returns a String * object representing the schema name or an empty string ("") * if the DBMS.does not support this feature. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * getSchemaName(int colindex) method.It should return a String object. */ /* throws std::exception * */ void testGetSchemaName(); /* * @testName: testGetTableName * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The getTableName(int colindex) method returns a String * object representing the table name or an empty string ("") * if the DBMS does not support this feature. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the getTableName(int colindex) * method.It should return a String object. */ /* throws std::exception * */ void testGetTableName(); /* * @testName: testIsAutoIncrement * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isAutoIncrement(int colindex) method returns a boolean value; * true if the column colindex is automatically numbered which makes * the column read-only and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isAutoIncrement(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsAutoIncrement(); /* @testName: testIsCaseSensitive * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isCaseSensitive(int colindex) method returns a boolean value; * true if the column colindex is case sensitive and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isCaseSensitive(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsCaseSensitive(); /* @testName: testIsCurrency * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isCurrency(int colindex) method returns a boolean value; * true if the column colindex is a cash value and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isCurrency(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsCurrency(); /* * @testName: testIsDefinitelyWritable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isDefinitelyWritable(int colindex) method returns a boolean value; * true if the write on column colindex will definitely succeed * and false otherwise. (See JDK 1.2.2 API documentation) * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the * isDefinitelyWritable(int column) method.It should return a boolean value. */ /* throws std::exception * */ void testIsDefinitelyWritable(); /* * @testName: testIsNullable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isNullable(int colindex) method returns an integer value * the possible values are columnNoNulls, columnNullable and * columnNullableUnknown. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isNullable(int column) * method.It should return an integer value which is one of the constants * columnNoNulls(0),columnNullable(1) and columnNullableUnknown(2). */ /* throws std::exception * */ void testIsNullable(); /* * @testName: testIsReadOnly * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isReadOnly(int colindex) method returns a boolean value; * true if the column colindex is definitely not writable and false * otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isReadOnly(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsReadOnly(); /* * @testName: testIsSearchable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isSearchable(int colindex) method returns a boolean value; * true if the value stored in column colindex can be used in a * WHERE clause and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isSearchable(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsSearchable(); /* @testName: testIsSigned * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isSigned(int colindex) method returns a boolean value; * true if the value stored in column colindex is a signed number * and false otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isSigned(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsSigned(); /* * @testName: testIsWritable * @assertion: The ResultSetMetaData provides information about the types and * properties of the columns in a ResultSet object. * (See section 27.1 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * A driver must provide full support for DatabaseMetaData and * ResultSetMetaData. This implies that all of the methods in the * ResultSetMetaData interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. None of the * methods in DatabaseMetaData and ResultSetMetaData may throw an * exception because they are not implemented. (See section 6.2.2.3 * of Java2 Platform Enterprise Edition (J2EE) Specification v1.2) * * The isWritable(int colindex) method returns a boolean value; * true if the column colindex is possible for write and false * otherwise. * (See Section 27.3 of JDBC 2.0 API Reference & Tutorial 2nd edition) * * @test_Strategy: Get the ResultSetMetaData object from the corresponding ResultSet * by using the ResultSet's getMetaData method.Call the isWritable(int column) * method.It should return a boolean value. */ /* throws std::exception * */ void testIsWritable(); }; REGISTER_FIXTURE(ResultSetMetadataTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/StatementTest.cpp000644 015771 000012 00000173416 12645244437 027425 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "StatementTest.h" namespace testsuite { namespace compliance { /* * @testName: testClearWarnings * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The ClearWarnings clears the SQLWarnings associated with * the statement object. After a call to this method, a call * to getWarnings will return a null SQLWarning object. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call clearWarnings() method * on the statement object.Further calling the getWarnings() * method should return a null SQLWarning object * */ /* throws Exception */ void StatementTest::testClearWarnings() { const sql::SQLWarning * sWarning=stmt->getWarnings(); if (sWarning != NULL) { logMsg("Calling clearWarnings method "); stmt->clearWarnings(); sWarning=stmt->getWarnings(); if (sWarning == NULL) { logMsg("clearWarnings clears the SQLWarnings"); } else { logErr("clearWarnings does not clear the SQLWarning"); FAIL("Call to clearWarnings is Failed!"); } } else { logErr("getWarnings() returns a NULL SQLWarning object"); } } /* * @testName: testClose * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The close method closes the statement object.When a Statement * object is closed, its current ResultSet object, if one exists, * is also closed. (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call close() method and call * executeQuery() method to check and it should throw SQLException * */ /* throws Exception */ void StatementTest::testClose() { Statement statemt; bool sqlExceptFlag=false; statemt.reset(conn->createStatement()); logMsg("Calling close method"); statemt->close(); String sSelCoffee=sqlProps["SelCoffeeAll"]; logMsg(String("Query String : ") + sSelCoffee); try { rs.reset(statemt->executeQuery(sSelCoffee)); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg("close method closes the Statement object"); } else { logErr("close method does not close the Statement object"); FAIL("Call to close method is Failed!"); } } /* * @testName: testExecute01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The execute(String sql) method returns a boolean value; true * if the first result is ResultSet or false if it is an integer. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Call execute(String sql) of updating a row * It should return a boolean value and the value should be * equal to false * */ /* throws Exception */ void StatementTest::testExecute01() { createStandardTable(TABLE_CTSTABLE2); bool executeFlag=false; String sSqlStmt=sqlProps[ "Upd_Coffee_Tab" ]; logMsg(String("SQL Statement to be executed ") + sSqlStmt); logMsg("Calling execute method "); executeFlag=stmt->execute(sSqlStmt); if (!executeFlag) { logMsg("execute method executes the SQL Statement "); } else { logErr("execute method does not execute the SQL Statement"); FAIL("Call to execute is Failed!"); } } /* * @testName: testExecute02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The execute(String sql) method returns a boolean value; * true if the first result is ResultSet or false if it is * an integer. (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call execute(String sql) * of selecting rows from the database * It should return a boolean value and the value should be equal * to true * */ /* throws Exception */ void StatementTest::testExecute02() { createStandardTable(TABLE_CTSTABLE2); bool executeFlag=false; String sSqlStmt=sqlProps[ "Sel_Coffee_Tab" ]; logMsg(String("Sql Statement to be executed ") + sSqlStmt); logMsg("Calling execute method "); executeFlag=stmt->execute(sSqlStmt); if (executeFlag) { logMsg("execute method executes the SQL Statement "); } else { logErr("execute method does not execute the SQL Statement"); FAIL("Call to execute is Failed!"); } } /* * @testName: testExecuteQuery01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeQuery(String sql) method returns a ResultSet object; * It may return an empty ResultSet object but never returns null. * This method throws SQLException if an error occurs in processing * SQL statement or if the SQL statement generates a row count * instead of ResultSet. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeQuery(String sql) * to select a row from the database * It should return a ResultSet object * */ /* *throws Exception * Pretty much useless in C++ */ void StatementTest::testExecuteQuery01() { createStandardTable(TABLE_CTSTABLE2); ResultSet reSet; String sSqlStmt=sqlProps[ "SelCoffeeAll" ]; logMsg(String("SQL Statement to be executed : ") + sSqlStmt); logMsg("Calling executeQuery method "); reSet.reset(stmt->executeQuery(sSqlStmt)); if (reSet.get() != NULL) { logMsg("executeQuery method returns a ResultSet object"); } else { logErr("executeQuery method does not return a ResultSet object"); FAIL("Call to executeQuery is Failed!"); } } /* * @testName: testExecuteQuery02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeQuery(String sql) method returns a ResultSet object; * It may return an empty ResultSet object but never returns null. * This method throws SQLException if an error occurs in processing * SQL statement or if the SQL statement generates a row count * instead of ResultSet. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeQuery(String sql) * to select a non-existent row from the database * It should return a ResultSet object which is empty and call * ResultSet.next() method to check and it should return a false * */ /* throws Exception */ void StatementTest::testExecuteQuery02() { createStandardTable(TABLE_CTSTABLE2); ResultSet reSet; String sSqlStmt=sqlProps[ "SelCoffeeNull" ]; logMsg(String("SQL Statement to be executed : ") + sSqlStmt); logMsg("Calling executeQuery method "); reSet.reset(stmt->executeQuery(sSqlStmt)); if (!reSet->next()) { logMsg( "executeQuery method returns an Empty ResultSet for Non-Existent row"); } else { logErr( "executeQuery method does not return an Empty ResultSet for non-existent row"); FAIL("Call to executeQuery is Failed!"); } } /* * @testName: testExecuteQuery03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeQuery(String sql) method returns a ResultSet object; * It may return an empty ResultSet object but never returns null. * This method throws SQLException if an error occurs in processing * SQL statement or if the SQL statement generates a row count * instead of ResultSet. (See JDK1.2.2 API documentation) * * * @test_Strategy: Get a Statement object and call executeQuery(String sql) * to insert a row from the database * It should throw SQLException * */ /* throws Exception */ void StatementTest::testExecuteQuery03() { ResultSet reSet; bool sqlExceptFlag=false; String sSqlStmt=sqlProps[ "Ins_Coffee_Tab" ]; logMsg(String("SQL Statement to be executed : ") + sSqlStmt); try { logMsg("Calling executeQuery method "); reSet.reset(stmt->executeQuery(sSqlStmt)); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (!sqlExceptFlag) { logErr("executeQuery method executes an Insert Statement"); FAIL("Call to executeQuery is Failed!"); } else { logMsg( "executeQuery method does not execute an Insert Statement"); } } /* * @testName: testExecuteUpdate01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeUpdate(String sql) method returns a integer value; * The value indicates the number of rows affected by INSERT, DELETE * or UPDATE specified in the sql; 0 if no rows were affected or the * statement executed was a DDL statement. * This method throws SQLException if an error occurs in processing * SQL statement or if the SQL statement generates a ResultSet. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeUpdate(String sql) * It should return an int value which is equal to row count */ /* throws Exception */ void StatementTest::testExecuteUpdate01() { createStandardTable(TABLE_CTSTABLE2); int updCount=0; int retRowCount=0; String sSqlStmt=sqlProps[ "Upd_Coffee_Tab" ]; logMsg(String("Update String : ") + sSqlStmt); logMsg("Calling executeUpdate method "); updCount=stmt->executeUpdate(sSqlStmt); String countQuery=sqlProps[ "Coffee_Updcount_Query" ]; logMsg(String("Query String : ") + countQuery); rs.reset(stmt->executeQuery(countQuery)); rs->next(); retRowCount=rs->getInt(1); TestsListener::messagesLog() << "Number of rows in the table with the specified condition " << retRowCount << std::endl; if (updCount == retRowCount) { logMsg("executeUpdate executes the SQL Statement "); } else { logErr("executeUpdate does not execute the SQL Statement "); FAIL("Call to executeUpdate is Failed!"); } } /* * @testName: testExecuteUpdate03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeUpdate(String sql) method returns a integer value; * The value indicates the number of rows affected by INSERT, DELETE * or UPDATE specified in the sql; 0 if no rows were affected or the * statement executed was a DDL statement. * This method throws SQLException if an error occurs in processing * SQL statement or if the SQL statement generates a ResultSet. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeUpdate(String sql) * for selecting row from the table * It should throw a SQL Exception * */ /* throws Exception */ void StatementTest::testExecuteUpdate03() { bool sqlExceptFlag=false; String sSqlStmt=sqlProps[ "Sel_Coffee_Tab" ]; logMsg(String("SQL String of non - existent row : ") + sSqlStmt); try { logMsg("Calling executeUpdate method "); stmt->executeUpdate(sSqlStmt); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg( "executeUpdate does not execute the SQL statement on non-existent row"); } else { logErr( "executeUpdate executes the SQL statement on non-existent row"); FAIL("Call to executeUpdate is Failed!"); } } /* * @testName: testGetFetchDirection * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getFetchDirection() method returns a integer value; * The value that is been set by the setFetchDirection method. * If no fetch direction has been set, the return value is * implementation specific. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the getFetchDirection() method * It should return a int value and the value should be equal to * any of the values FETCH_FORWARD or FETCH_REVERSE or FETCH_UNKNOWN * */ /* throws Exception * * Not included into sql::statement (and thus into MySQL_Statement) * Disabled so far. */ #ifdef MISSING_METHODS_INCLUDED2STATEMENT void StatementTest::testGetFetchDirection() { int fetchDirVal=0; logMsg("Calling getFetchDirection method "); fetchDirVal=stmt->getFetchDirection(); if (fetchDirVal == ResultSet::FETCH_FORWARD) { logMsg( "getFetchDirection method returns ResultSet.FETCH_FORWARD "); } else if (fetchDirVal == ResultSet.FETCH_REVERSE) { logMsg( "getFetchDirection method returns ResultSet.FETCH_REVERSE"); } else if (fetchDirVal == ResultSet.FETCH_UNKNOWN) { logMsg( "getFetchDirection method returns ResultSet.FETCH_UNKNOWN"); } else { logErr(" getFetchDirection method returns a invalid value"); FAIL("Call to getFetchDirection is Failed"); } } #endif #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetFetchSize * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getFetchSize() method returns a integer value; * The value that is been set by the setFetchSize method. * If no fetch size has been set, the return value is * implementation specific. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a ResultSet object and call the getFetchSize() method * It should return a int value * */ /* throws Exception */ void StatementTest::testGetFetchSize() { logMsg("Calling getFetchSize on Statement"); int fetchSizeVal=stmt->getFetchSize(); if (fetchSizeVal >= 0) { TestsListener::messagesLog() << "getFetchSize method returns :" << fetchSizeVal << std::endl; } else { logErr(" getFetchSize method returns a invalid value"); FAIL("Call to getFetchSize is Failed!"); } } /* * @testName: testGetMaxFieldSize * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMaxFieldSize() method returns a integer value; * The value representing the current maximum number of bytes * that a ResultSet column may contain. Zero means that there * is no limit. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the getMaxFieldSize() method * It should return a int value * */ /* throws Exception */ void StatementTest::testGetMaxFieldSize() { logMsg("Calling getMaxFieldSize on Statement"); int maxFieldSizeVal=stmt->getMaxFieldSize(); if (maxFieldSizeVal >= 0) { TestsListener::messagesLog() << "getMaxFieldSize method returns :" << maxFieldSizeVal << std::endl; } else { logErr(" getMaxFieldSize method returns a invalid value"); FAIL("Call to getMaxFieldSize is Failed!"); } } /* * @testName: testGetMaxRows * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMaxRows() method returns a integer value; * The value representing the current maximum number of rows * that a ResultSet object can contain. Zero means that there * is no limit. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the getMaxRows() method * It should return a int value * */ /* throws Exception */ void StatementTest::testGetMaxRows() { logMsg("Calling getMaxRows on Statement"); int maxRowsVal=static_cast (stmt->getMaxRows()); if (maxRowsVal >= 0) { TestsListener::messagesLog() << "getMaxRows method returns :" << maxRowsVal << std::endl; } else { logErr(" getMaxRows method returns a invalid value"); FAIL("Call to getMaxRows is Failed!"); } } #endif /* * @testName: testGetMoreResults01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMoreResults() method returns a boolean value; * true if the next result is ResultSet object; false if it is * an integer indicating that it is an update count or there are * no more results. There are no more results when the following * condition is satisfied. * (getMoreResults==false && getUpdatecount==-1) * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * selecting a row and call getMoreResults() method * It should return a boolean value * */ /* throws Exception */ void StatementTest::testGetMoreResults01() { createStandardTable(TABLE_CTSTABLE2); String sSqlStmt=sqlProps[ "SelCoffeeAll" ]; logMsg(String("Query String : ") + sSqlStmt); stmt->execute(sSqlStmt); logMsg("Calling getMoreResults on Statement"); bool moreResVal=stmt->getMoreResults(); // Hmm... smth is wrong here. Bad test if ((moreResVal == true) || (moreResVal == false)) { TestsListener::messagesLog() << "getMoreResults method returns :" << moreResVal << std::endl; TestsListener::setTestExecutionComment("This test needs to be changed or removed. It's wrong"); } else { logErr(" getMoreResults method returns a invalid value"); FAIL("Call to getMoreResults is Failed!"); } } /* * @testName: testGetMoreResults02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMoreResults() method returns a boolean value; * true if the next result is ResultSet object; false if it is * an integer indicating that it is an update count or there are * no more results. There are no more results when the following * condition is satisfied. * (getMoreResults==false && getUpdatecount==-1) * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * selecting a non-existent row and call getMoreResults() method * It should return a boolean value and the value should be * equal to false * */ /* throws Exception */ void StatementTest::testGetMoreResults02() { createStandardTable(TABLE_CTSTABLE2); String sSqlStmt=sqlProps[ "SelCoffeeNull" ]; logMsg(String("Query String : ") + sSqlStmt); stmt->execute(sSqlStmt); logMsg("Calling getMoreResults on Statement"); bool moreResVal=stmt->getMoreResults(); if (!moreResVal) { TestsListener::messagesLog() << "getMoreResults method returns :" << moreResVal << std::endl; } else { logErr(" getMoreResults method returns a invalid value"); FAIL("Call to getMoreResults is Failed!"); } } /* * @testName: testGetMoreResults03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMoreResults() method returns a boolean value; * true if the next result is ResultSet object; false if it is * an integer indicating that it is an update count or there are * no more results. There are no more results when the following * condition is satisfied. * (getMoreResults==false && getUpdatecount==-1) * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * updating a row and call getMoreResults() method * It should return a boolean value and the value should be * equal to false * */ /* throws Exception */ void StatementTest::testGetMoreResults03() { createStandardTable(TABLE_CTSTABLE2); String sSqlStmt=sqlProps[ "Upd_Coffee_Tab" ]; logMsg(String("Query String : ") + sSqlStmt); stmt->execute(sSqlStmt); logMsg("Calling getMoreResults on Statement"); bool moreResVal=stmt->getMoreResults(); if (!moreResVal) { TestsListener::messagesLog() << "getMoreResults method returns :" << moreResVal << std::endl; } else { logErr(" getMoreResults method returns a invalid value"); FAIL("Call to getMoreResults is Failed!"); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetQueryTimeout * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getQueryTimeout() method returns a integer value; * The value indicates the current query timeout limit in * seconds. Zero means that there is no time limit. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call getMoreResults() method * It should return a int value * */ /* throws Exception */ void StatementTest::testGetQueryTimeout() { int queryTimeout=0; logMsg("Calling getQueryTimeout on Statement"); queryTimeout=stmt->getQueryTimeout(); if (queryTimeout >= 0) { TestsListener::messagesLog() << "getQueryTimeout method returns :" << queryTimeout << std::endl; } else { logErr(" getQueryTimeout method returns a invalid value"); FAIL("Call to getQueryTimeout is Failed!"); } } #endif /* * @testName: testGetResultSet01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSet() method returns a ResultSet object; * the current result set as a ResultSet object; null if the * result is an integer indicating that it is an update count * or there are no more results.(See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call execute() method for * selecting a row and call getResultSet() method * It should return a ResultSet object * */ /* throws Exception */ void StatementTest::testGetResultSet01() { createStandardTable(TABLE_CTSTABLE2); ResultSet retResSet /*= NULL*/; String sSqlStmt=sqlProps[ "SelCoffeeAll" ]; logMsg(String("Query String : ") + sSqlStmt); logMsg("Calling getResultSet on Statement"); stmt->execute(sSqlStmt); retResSet.reset(stmt->getResultSet()); if (retResSet.get() != NULL) { logMsg("getResultSet method returns a ResultSet object "); } else { logErr( " getResultSet method does not return a ResultSet object"); FAIL("Call to getResultSet is Failed!"); } } /* * @testName: testGetResultSet02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSet() method returns a ResultSet object; * the current result set as a ResultSet object; null if the * result is an integer indicating that it is an update count * or there are no more results.(See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call execute() method for * updating a row.Then call getResultSet() method * It should return a Null ResultSet object */ /* throws Exception */ void StatementTest::testGetResultSet02() { createStandardTable(TABLE_CTSTABLE2); ResultSet retResSet /*= NULL*/; String sSqlStmt=sqlProps[ "Upd_Coffee_Tab" ]; logMsg(String("Query String : ") + sSqlStmt); logMsg("Calling getResultSet on Statement"); stmt->execute(sSqlStmt); retResSet.reset(stmt->getResultSet()); if (retResSet.get() == NULL) { logMsg("getResultSet method returns a Null ResultSet object "); } else { logErr( " getResultSet method does (not) return a ResultSet object"); FAIL("Call to getResultSet is Failed!"); } } /* * @testName: testGetResultSetType01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetType() method returns an integer value; * the value representing the type of the ResultSet objects * and the value can be any one of the following * ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_SENSITIVE * and ResultSet.TYPE_SCROLL_INSENSITIVE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call getResultSetType() method * It should return an int value which should be either * TYPE_FORWARD_ONLY or TYPE_SCROLL_INSENSITIVE or TYPE_SCROLL_SENSITIVE */ void StatementTest::testGetResultSetType01() { int rsType=0; rsType=stmt->getResultSetType(); if (rsType == sql::ResultSet::TYPE_FORWARD_ONLY) { TestsListener::messagesLog() << "getResultSetType method returns TYPE_FORWARD_ONLY" << rsType << std::endl; } else if (rsType == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) { TestsListener::messagesLog() << "getResultSetType method returns TYPE_SCROLL_INSENSITIVE " << rsType << std::endl; } else if (rsType == sql::ResultSet::TYPE_SCROLL_SENSITIVE) { TestsListener::messagesLog() << "getResultSetType method returns TYPE_SCROLL_SENSITIVE " << rsType << std::endl; } else { logErr(" getResultSetType method does not return a valid value"); FAIL("Call to getResultSetType is Failed!"); } } /* * @testName: testGetResultSetType02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetType() method returns an integer value; * the value representing the type of the ResultSet objects * and the value can be any one of the following * ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_SENSITIVE * and ResultSet.TYPE_SCROLL_INSENSITIVE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Call Connection.createStatement with the Type mode as * TYPE_FORWARD_ONLY and call getResultSetType() method * It should return a int value and the value should be equal * to ResultSet.TYPE_FORWARD_ONLY */ void StatementTest::testGetResultSetType02() { int rsType=0; logMsg("Creating Statement object with the ResultSet Type"); Statement statemt( conn->createStatement() ); statemt->setResultSetType( sql::ResultSet::TYPE_FORWARD_ONLY ); // sql::ResultSet::CONCUR_READ_ONLY); rsType=statemt->getResultSetType(); if ( rsType == sql::ResultSet::TYPE_FORWARD_ONLY ) { TestsListener::messagesLog() << "getResultSetType method returns TYPE_FORWARD_ONLY " << rsType << std::endl; } else { logErr(" getResultSetType method does not return a valid value"); FAIL("Call to getResultSetType is Failed!"); } } /* * @testName: testGetResultSetConcurrency01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetConcurrency() method returns an integer value; * the value representing the concurrency mode for the ResultSet * objects and the value can be any one of the following * ResultSet.CONCUR_READ_ONLY and ResultSet.CONCUR_UPDATABLE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call getResultSetConcurrency() method * It should return an int value either CONCUR_READ_ONLY or * CONCUR_UPDATABLE. */ /* getResultSetConcurrency not included into statement interface * * * throws Exception */ #ifdef MISSING_METHODS_INCLUDED2STATEMENT void StatementTest::testGetResultSetConcurrency01() { int rsConcur=0; rsConcur=stmt->getResultSetConcurrency(); if ((rsConcur == sql::ResultSet::CONCUR_READ_ONLY) || (rsConcur == sql::ResultSet::CONCUR_UPDATABLE)) { logMsg( "getResultSetConcurrency method returns ResultSet Concurrency mode " + rsConcur); } else { logErr( " getResultSetConcurrency method does not return a valid value"); FAIL("Call to getResultSetConcurrency is Failed!"); } } /* * @testName: testGetResultSetType03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetType() method returns an integer value; * the value representing the type of the ResultSet objects * and the value can be any one of the following * ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_SENSITIVE * and ResultSet.TYPE_SCROLL_INSENSITIVE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Call Connection.createStatement with the Type mode as * TYPE_SCROLL_INSENSITIVE and call getResultSetType() method * It should return a int value and the value should be equal * to ResultSet.TYPE_SCROLL_INSENSITIVE */ /* throws Exception */ void StatementTest::testGetResultSetType03() { int rsType=0; Statement statemt /*= NULL*/; logMsg("Creating Statement object with the ResultSet Type and Type"); statemt=conn->createStatement(sql::ResultSet::TYPE_SCROLL_INSENSITIVE, sql::ResultSet::CONCUR_READ_ONLY); rsType=statemt->getResultSetType(); if (rsType == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) { logMsg( "getResultSetType method returns TYPE_SCROLL_INSENSITIVE " + rsType); } else { statemt->close(); logErr(" getResultSetType method does not return a valid value"); FAIL("Call to getResultSetType is Failed!"); } statemt->close(); } /* * @testName: testGetUpdateCount01 * * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getUpdateCount() method should return a integer value; * the value might be greater than 0 representing the rows affected; * 0 if no rows are affected or if DDL statement; -1 if the result * is a ResultSet object or there are no more results * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * updating a row and call getUpdateCount() method * It should return a int value and the value should be * equal to number of rows with the specified condition for update */ #endif /* throws Exception */ void StatementTest::testGetUpdateCount01() { createStandardTable(TABLE_CTSTABLE2); int updCountVal=0; int rowsAffectVal=0; String sSqlStmt=sqlProps[ "Upd_Coffee_Tab" ]; logMsg(String("Query String : ") + sSqlStmt); stmt->execute(sSqlStmt); logMsg("Calling getUpdateCount on Statement"); updCountVal=static_cast (stmt->getUpdateCount()); String sQuery=sqlProps[ "Coffee_Updcount_Query" ]; logMsg(String("Query String : ") + sQuery); ResultSet rs1(stmt->executeQuery(sQuery)); rs1->next(); rowsAffectVal=rs1->getInt(1); TestsListener::messagesLog() << "Number of Rows Affected by Update Statement " << rowsAffectVal << std::endl; if (updCountVal == rowsAffectVal) { TestsListener::messagesLog() << "getUpdateCount method returns :" << updCountVal << std::endl; } else { logErr(" getUpdateCount method returns a invalid value"); FAIL("Call to getUpdateCount is Failed!"); } } /* * @testName: testGetUpdateCount02 * * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getUpdateCount() method should return a integer value; * the value might be greater than 0 representing the rows affected; * 0 if no rows are affected or if DDL statement; -1 if the result * is a ResultSet object or there are no more results * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * selecting a non-existent row and call getUpdateCount() method * It should return a int value and the value should be * equal to -1 */ /* throws Exception */ void StatementTest::testGetUpdateCount02() { createStandardTable(TABLE_CTSTABLE2); int updCountVal=0; String sSqlStmt=sqlProps[ "SelCoffeeNull" ]; logMsg(String("Query String : ") + sSqlStmt); stmt->execute(sSqlStmt); logMsg("Calling getMoreResults on Statement"); updCountVal=static_cast (stmt->getUpdateCount()); if (updCountVal == -1) { logMsg("getUpdateCount method returns : -1"); } else { logErr(" getUpdateCount method returns a invalid value"); FAIL("Call to getUpdateCount is Failed!"); } } /* * @testName: testGetWarnings * * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getWarnings() method should return a SQLWarning object; * or null if there are no warnings (See JDK 1.2.2 API * Documentation) * * @test_Strategy: Get a Statement object and call getWarnings() method * should return an SQLWarning object */ /* throws Exception */ void StatementTest::testGetWarnings() { createStandardTable(TABLE_INTEGERTAB); if (hasSps) { initTable("Integer_Tab", sqlProps, conn); //TODO: Need to invent somth to generate warnings instead of this #ifdef WE_GOT_SMTH2DEAL_WITH_SP CallableStatement cstmt=conn->prepareCall( "{call Integer_Proc(?,?,?)}"); logMsg(String("The Callable Statement ") + cstmt); cstmt->registerOutParameter(1, "cppconn/datatype.h".INTEGER); cstmt->registerOutParameter(2, "cppconn/datatype.h".INTEGER); cstmt->registerOutParameter(3, "cppconn/datatype.h".INTEGER); cstmt->execute(); int nRetVal=cstmt->getInt(1); Statement state(cstmt); #else sql::Statement * state=stmt.get(); #endif logMsg("Calling getWarnings method"); const sql::SQLWarning * sWarning=state->getWarnings(); if (sWarning != NULL) { logMsg("getWarnings method returns a SQLWarning object"); } else if (sWarning == NULL) { logErr("getWarnings() method returns a NULL SQLWarning Object"); } clearTable("Integer_Tab", conn); } } #ifdef MISSING_METHODS_INCLUDED2STATEMENT /* * @testName: testSetFetchDirection04 * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setFetchDirection(int dir) method sets the statement * object's fetch direction. The setFetchDirection method does * not return any value. (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setFetchDirection(int direction) * method with an invalid value and it should throw an SQLException */ /* throws Exception */ void StatementTest::testSetFetchDirection04() { bool sqlExceptFlag=false; logMsg("Calling setFetchDirection method "); try { stmt->setFetchDirection(-1); } catch (sql::SQLException * sqe) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg( "setFetchDirection method does not sets the invalid direction for the ResultSet "); } else { logErr( "setFetchDirection method sets the invalid direction for ResultSet"); FAIL("Call to setFetchDirection is Failed"); } } #endif #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testSetFetchSize02 * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setFetchSize(int rowsize) method sets the number of rows * to fetch from the database specified by the value of rowsize. * The setFetchSize does not return any value. (See JDK 1.2.2 * API Documentation) * * @test_Strategy: Get a Statement object and call the setFetchSize(int rows) * method with the value of Statement.getMaxRows and call * getFetchSize() method and it should return a int value * that is been set */ /* throws Exception */ void StatementTest::testSetFetchSize02() { int maxFetchSizeVal=50; int maxRowsVal=0; int retVal=0; stmt->setMaxRows(maxFetchSizeVal); maxRowsVal=static_cast (stmt->getMaxRows()); TestsListener::messagesLog() << "Maximum Rows that Statement can contain " << maxRowsVal << std::endl; logMsg("Calling the setFetchSize method"); stmt->setFetchSize(maxRowsVal); retVal=stmt->getFetchSize(); if (maxFetchSizeVal == retVal) { logMsg( "setFetchSize method sets the value as FetchSize for ResultSet"); } else { logErr( "setFetchSize method does not set the value as Fetch Size for ResultSet"); FAIL("Call to setFetchSize is Failed"); } } /* * @testName: testSetFetchSize05 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setFetchSize(int size) method sets the number of rows * to fetch from the database specified by the value size. * The method does not return any value and throws SQLException * if a database access error occurs or the condition * 0 <= size <= this.getMaxRows is not satisfied. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setFetchSize(int rows) * method with the negative value and it should throw * SQLException * */ /* throws Exception */ void StatementTest::testSetFetchSize05() { int maxFetchSizeVal=0; String sMaxFetchSizeVal; bool sqlExceptFlag=false; sMaxFetchSizeVal=sqlProps[ "Max_Set_Val" ]; maxFetchSizeVal=StringUtils::toInt(sMaxFetchSizeVal); maxFetchSizeVal=maxFetchSizeVal * (-1); TestsListener::messagesLog() << "Maximum Value to be set as Fetch Size " << maxFetchSizeVal << std::endl; logMsg("Calling setFetchSize method"); try { stmt->setFetchSize(maxFetchSizeVal); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg("setFetchSize method does not set the invalid value "); } else { logErr("setFetchSize method sets the Invalid value "); FAIL("Call to setFetchSize is Failed"); } } /* * @testName: testSetMaxFieldSize01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxFieldSize(int maxsize) method sets the maximum size * for a column in a result set specified by the value maxsize (in * bytes). For maximum portability, the maximum field size should * be set to a value greater than 256. If the value maxsize is 0 * then it means that there is no limit to the size of a column. * The setMaxFieldSize(int maxsize) does not return any value. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxFieldSize(int max) * method and call getMaxFieldSize() method and it should return * an integer value that is been set * */ /* throws Exception */ void StatementTest::testSetMaxFieldSize01() { int maxFieldSizeVal=0; String sMaxFieldSizeVal; int retVal=0; sMaxFieldSizeVal=sqlProps[ "Max_Set_Val" ]; maxFieldSizeVal=StringUtils::toInt(sMaxFieldSizeVal); maxFieldSizeVal=maxFieldSizeVal * 256; TestsListener::messagesLog() << "Maximum Field Size Value to be set " << maxFieldSizeVal << std::endl; logMsg("Calling maxFieldSize method "); stmt->setMaxFieldSize(maxFieldSizeVal); retVal=stmt->getMaxFieldSize(); if (maxFieldSizeVal == retVal) { logMsg( "setMaxFieldSize method sets the value for Maximum Field Size"); } else { logErr( "setMaxFieldSize method does not set the value for Maximum Field Size"); FAIL("Call to setMaxFieldSize is Failed"); } } /* * @testName: testSetMaxFieldSize02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxFieldSize(int maxsize) method sets the maximum size * for a column in a result set specified by the value maxsize (in * bytes). For maximum portability, the maximum field size should * be set to a value greater than 256. If the value maxsize is 0 * then it means that there is no limit to the size of a column. * The setMaxFieldSize(int maxsize) does not return any value. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxFieldSize(int max) * method with an invalid value (negative value) and It should * throw a SQLException * */ /* throws Exception */ void StatementTest::testSetMaxFieldSize02() { int maxFieldSizeVal=0; String sMaxFieldSizeVal; bool sqlExceptFlag=false; sMaxFieldSizeVal=sqlProps[ "Max_Set_Val" ]; maxFieldSizeVal=StringUtils::toInt(sMaxFieldSizeVal); maxFieldSizeVal=maxFieldSizeVal * (-1); TestsListener::messagesLog() << "Rows Value to be set " << maxFieldSizeVal << std::endl; logMsg("Calling the setMaxFieldSize method"); try { stmt->setMaxFieldSize(maxFieldSizeVal); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg("setMaxFieldSize method does not set the Invalid value "); } else { logErr("setMaxFieldSize method sets the Invalid value"); FAIL("Call to setMaxFieldSize is Failed"); } } /* * @testName: testSetMaxRows01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxRows(int maxsize) method sets the maximum number * of rows that any ResultSet object can contain is specified * by the value maxsize. If the value maxsize is 0 then it means * that there is no limit. The setMaxRows(int maxsize) does not * return any value.(See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxRows(int rows) * method and call getMaxRows() method and it should return a * integer value that is been set * */ /* throws Exception */ void StatementTest::testSetMaxRows01() { int maxRowsVal=0; String sMaxRowsVal; int retVal=0; sMaxRowsVal=sqlProps[ "Max_Set_Val" ]; maxRowsVal=StringUtils::toInt(sMaxRowsVal); TestsListener::messagesLog() << "Maximum Rows Value to be set " << maxRowsVal << std::endl; logMsg("Calling maxRowsVal method"); stmt->setMaxRows(maxRowsVal); retVal=static_cast (stmt->getMaxRows()); if (maxRowsVal == retVal) { logMsg("setMaxRows method sets the value for Maximum Rows"); } else { logErr( "setMaxRows method does not set the value for Maximum Rows"); FAIL("Call to setMaxRows is Failed"); } } /* * @testName: testSetMaxRows02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxRows(int maxsize) method sets the maximum number * of rows that any ResultSet object can contain is specified * by the value maxsize. If the value maxsize is 0 then it means * that there is no limit. The setMaxRows(int maxsize) does not * return any value.(See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxRows(int rows) * method with an invalid value (negative value) and It should * throw an SQLException * */ /* throws Exception */ void StatementTest::testSetMaxRows02() { int maxRowsVal=0; String sMaxRowsVal; bool sqlExceptFlag=false; sMaxRowsVal=sqlProps[ "Max_Set_Val" ]; maxRowsVal=StringUtils::toInt(sMaxRowsVal); maxRowsVal=maxRowsVal * (-1); TestsListener::messagesLog() << "Rows Value to be set " << maxRowsVal << std::endl; logMsg("Calling setMaxRows method"); try { stmt->setMaxRows(maxRowsVal); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg("setMaxRows method does not set the Invalid value "); } else { logErr("setMaxRows method sets the Invalid value"); FAIL("Call to setMaxRows is Failed"); } } /* * @testName: testSetQueryTimeout02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setQueryTimeout(int secval) method sets the time limit * for the number of secval seconds a driver will wait for a * statement object to be executed. If the value secval is 0 * then it means that there is no limit. The setQueryTimeout * method does not return any value. (See JDK 1.2.2 API * Documentation) * * @test_Strategy: Get a Statement object and call the setQueryTimeout(int secval) * method with an invalid value (negative value)and It should * throw an SQLException * */ /* throws Exception */ void StatementTest::testSetQueryTimeout02() { int maxQueryTimeVal=0; String sMaxQueryTimeVal; bool sqlExceptFlag=false; sMaxQueryTimeVal=sqlProps[ "Max_Set_Val" ]; maxQueryTimeVal=StringUtils::toInt(sMaxQueryTimeVal); maxQueryTimeVal=maxQueryTimeVal * (-1); TestsListener::messagesLog() << "Seconds Value to be set as QueryTimeout " << maxQueryTimeVal << std::endl; logMsg("Calling maxQueryTimeout method"); try { stmt->setQueryTimeout(maxQueryTimeVal); } catch (sql::SQLException &) { sqlExceptFlag=true; } if (sqlExceptFlag) { logMsg("setQueryTimeout method does not set the Invalid value "); } else { logErr("setQueryTimeout method sets the Invalid value"); FAIL("Call to setQueryTimeout is Failed"); } } #endif } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/StatementTest.h000644 015771 000012 00000141661 12645244437 027067 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /** * @author mmatthew * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ namespace testsuite { namespace compliance { class StatementTest : public BaseTestFixture { private: typedef BaseTestFixture super; protected: public: TEST_FIXTURE(StatementTest) { TEST_CASE(testClearWarnings); TEST_CASE(testClose); TEST_CASE(testExecute01); TEST_CASE(testExecute02); TEST_CASE(testExecuteQuery01); TEST_CASE(testExecuteQuery02); TEST_CASE(testExecuteQuery03); TEST_CASE(testExecuteUpdate01); TEST_CASE(testExecuteUpdate03); TEST_CASE(testGetMoreResults01); TEST_CASE(testGetMoreResults02); TEST_CASE(testGetMoreResults03); TEST_CASE(testGetResultSet01); TEST_CASE(testGetResultSet02); TEST_CASE(testGetUpdateCount01); TEST_CASE(testGetUpdateCount02); TEST_CASE(testGetWarnings); TEST_CASE(testGetResultSetType01); TEST_CASE(testGetResultSetType02); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS TEST_CASE(testGetFetchSize); TEST_CASE(testGetMaxFieldSize); TEST_CASE(testSetMaxFieldSize02); TEST_CASE(testGetMaxRows); TEST_CASE(testSetMaxRows02); TEST_CASE(testGetQueryTimeout); TEST_CASE(testSetQueryTimeout02); TEST_CASE(testSetFetchSize02); TEST_CASE(testSetFetchSize05); TEST_CASE(testSetMaxFieldSize01); TEST_CASE(testSetMaxRows01); #endif #ifdef MISSING_METHODS_INCLUDED2STATEMENT TEST_CASE(testSetFetchDirection04); TEST_CASE(testGetResultSetType03); TEST_CASE(testGetResultSetConcurrency01); TEST_CASE(testGetFetchDirection); #endif } /* * @testName: testClearWarnings * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The ClearWarnings clears the SQLWarnings associated with * the statement object. After a call to this method, a call * to getWarnings will return a null SQLWarning object. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call clearWarnings() method * on the statement object.Further calling the getWarnings() * method should return a null SQLWarning object * */ /* throws std::exception * */ void testClearWarnings(); /* * @testName: testClose * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The close method closes the statement object.When a Statement * object is closed, its current ResultSet object, if one exists, * is also closed. (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call close() method and call * executeQuery() method to check and it should throw sql::DbcException * */ /* throws std::exception * */ void testClose(); /* * @testName: testExecute01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The execute(String sql) method returns a boolean value; true * if the first result is ResultSet or false if it is an integer. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Call execute(String sql) of updating a row * It should return a boolean value and the value should be * equal to false * */ /* throws std::exception * */ void testExecute01(); /* * @testName: testExecute02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The execute(String sql) method returns a boolean value; * true if the first result is ResultSet or false if it is * an integer. (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call execute(String sql) * of selecting rows from the database * It should return a boolean value and the value should be equal * to true * */ /* throws std::exception * */ void testExecute02(); /* * @testName: testExecuteQuery01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeQuery(String sql) method returns a ResultSet object; * It may return an empty ResultSet object but never returns null. * This method throws sql::DbcException if an error occurs in processing * SQL statement or if the SQL statement generates a row count * instead of ResultSet. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeQuery(String sql) * to select a row from the database * It should return a ResultSet object * */ /* throws std::exception * */ void testExecuteQuery01(); /* * @testName: testExecuteQuery02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeQuery(String sql) method returns a ResultSet object; * It may return an empty ResultSet object but never returns null. * This method throws sql::DbcException if an error occurs in processing * SQL statement or if the SQL statement generates a row count * instead of ResultSet. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeQuery(String sql) * to select a non-existent row from the database * It should return a ResultSet object which is empty and call * ResultSet.next() method to check and it should return a false * */ /* throws std::exception * */ void testExecuteQuery02(); /* * @testName: testExecuteQuery03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeQuery(String sql) method returns a ResultSet object; * It may return an empty ResultSet object but never returns null. * This method throws sql::DbcException if an error occurs in processing * SQL statement or if the SQL statement generates a row count * instead of ResultSet. (See JDK1.2.2 API documentation) * * * @test_Strategy: Get a Statement object and call executeQuery(String sql) * to insert a row from the database * It should throw sql::DbcException * */ /* throws std::exception * */ void testExecuteQuery03(); /* * @testName: testExecuteUpdate01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeUpdate(String sql) method returns a integer value; * The value indicates the number of rows affected by INSERT, DELETE * or UPDATE specified in the sql; 0 if no rows were affected or the * statement executed was a DDL statement. * This method throws sql::DbcException if an error occurs in processing * SQL statement or if the SQL statement generates a ResultSet. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeUpdate(String sql) * It should return an int value which is equal to row count */ /* throws std::exception * */ void testExecuteUpdate01(); /* * @testName: testExecuteUpdate03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The executeUpdate(String sql) method returns a integer value; * The value indicates the number of rows affected by INSERT, DELETE * or UPDATE specified in the sql; 0 if no rows were affected or the * statement executed was a DDL statement. * This method throws sql::DbcException if an error occurs in processing * SQL statement or if the SQL statement generates a ResultSet. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call executeUpdate(String sql) * for selecting row from the table * It should throw a SQL std::exception * * */ /* throws std::exception * */ void testExecuteUpdate03(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetFetchSize * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getFetchSize() method returns a integer value; * The value that is been set by the setFetchSize method. * If no fetch size has been set, the return value is * implementation specific. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a ResultSet object and call the getFetchSize() method * It should return a int value * */ /* throws std::exception * */ void testGetFetchSize(); /* * @testName: testGetMaxFieldSize * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMaxFieldSize() method returns a integer value; * The value representing the current maximum number of bytes * that a ResultSet column may contain. Zero means that there * is no limit. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the getMaxFieldSize() method * It should return a int value * */ /* throws std::exception * */ void testGetMaxFieldSize(); /* * @testName: testGetMaxRows * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMaxRows() method returns a integer value; * The value representing the current maximum number of rows * that a ResultSet object can contain. Zero means that there * is no limit. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the getMaxRows() method * It should return a int value * */ /* throws std::exception * */ void testGetMaxRows(); #endif /* * @testName: testGetMoreResults01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMoreResults() method returns a boolean value; * true if the next result is ResultSet object; false if it is * an integer indicating that it is an update count or there are * no more results. There are no more results when the following * condition is satisfied. * (getMoreResults==false && getUpdatecount==-1) * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * selecting a row and call getMoreResults() method * It should return a boolean value * */ /* throws std::exception * */ void testGetMoreResults01(); /* * @testName: testGetMoreResults02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMoreResults() method returns a boolean value; * true if the next result is ResultSet object; false if it is * an integer indicating that it is an update count or there are * no more results. There are no more results when the following * condition is satisfied. * (getMoreResults==false && getUpdatecount==-1) * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * selecting a non-existent row and call getMoreResults() method * It should return a boolean value and the value should be * equal to false * */ /* throws std::exception * */ void testGetMoreResults02(); /* * @testName: testGetMoreResults03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getMoreResults() method returns a boolean value; * true if the next result is ResultSet object; false if it is * an integer indicating that it is an update count or there are * no more results. There are no more results when the following * condition is satisfied. * (getMoreResults==false && getUpdatecount==-1) * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * updating a row and call getMoreResults() method * It should return a boolean value and the value should be * equal to false * */ /* throws std::exception * */ void testGetMoreResults03(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testGetQueryTimeout * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getQueryTimeout() method returns a integer value; * The value indicates the current query timeout limit in * seconds. Zero means that there is no time limit. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call getMoreResults() method * It should return a int value * */ /* throws std::exception * */ void testGetQueryTimeout(); #endif /* * @testName: testGetResultSet01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSet() method returns a ResultSet object; * the current result set as a ResultSet object; null if the * result is an integer indicating that it is an update count * or there are no more results.(See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call execute() method for * selecting a row and call getResultSet() method * It should return a ResultSet object * */ /* throws std::exception * */ void testGetResultSet01(); /* * @testName: testGetResultSet02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSet() method returns a ResultSet object; * the current result set as a ResultSet object; null if the * result is an integer indicating that it is an update count * or there are no more results.(See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call execute() method for * updating a row.Then call getResultSet() method * It should return a Null ResultSet object */ /* throws std::exception * */ void testGetResultSet02(); /* * @testName: testGetUpdateCount01 * * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getUpdateCount() method should return a integer value; * the value might be greater than 0 representing the rows affected; * 0 if no rows are affected or if DDL statement; -1 if the result * is a ResultSet object or there are no more results * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * updating a row and call getUpdateCount() method * It should return a int value and the value should be * equal to number of rows with the specified condition for update */ /* throws std::exception * */ void testGetUpdateCount01(); /* * @testName: testGetUpdateCount02 * * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getUpdateCount() method should return a integer value; * the value might be greater than 0 representing the rows affected; * 0 if no rows are affected or if DDL statement; -1 if the result * is a ResultSet object or there are no more results * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the execute() method for * selecting a non-existent row and call getUpdateCount() method * It should return a int value and the value should be * equal to -1 */ /* throws std::exception * */ void testGetUpdateCount02(); /* * @testName: testGetWarnings * * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getWarnings() method should return a SQLWarning object; * or null if there are no warnings (See JDK 1.2.2 API * Documentation) * * @test_Strategy: Get a Statement object and call getWarnings() method * should return an SQLWarning object */ /* throws std::exception * */ void testGetWarnings(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /* * @testName: testSetFetchSize02 * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setFetchSize(int rowsize) method sets the number of rows * to fetch from the database specified by the value of rowsize. * The setFetchSize does not return any value. (See JDK 1.2.2 * API Documentation) * * @test_Strategy: Get a Statement object and call the setFetchSize(int rows) * method with the value of Statement.getMaxRows and call * getFetchSize() method and it should return a int value * that is been set */ /* throws std::exception * */ void testSetFetchSize02(); /* * @testName: testSetFetchSize05 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setFetchSize(int size) method sets the number of rows * to fetch from the database specified by the value size. * The method does not return any value and throws sql::DbcException * if a database access error occurs or the condition * 0 <= size <= this.getMaxRows is not satisfied. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setFetchSize(int rows) * method with the negative value and it should throw * sql::DbcException * */ /* throws std::exception * */ void testSetFetchSize05(); /* * @testName: testSetMaxFieldSize01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxFieldSize(int maxsize) method sets the maximum size * for a column in a result set specified by the value maxsize (in * bytes). For maximum portability, the maximum field size should * be set to a value greater than 256. If the value maxsize is 0 * then it means that there is no limit to the size of a column. * The setMaxFieldSize(int maxsize) does not return any value. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxFieldSize(int max) * method and call getMaxFieldSize() method and it should return * an integer value that is been set * */ /* throws std::exception * */ void testSetMaxFieldSize01(); /* * @testName: testSetMaxFieldSize02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxFieldSize(int maxsize) method sets the maximum size * for a column in a result set specified by the value maxsize (in * bytes). For maximum portability, the maximum field size should * be set to a value greater than 256. If the value maxsize is 0 * then it means that there is no limit to the size of a column. * The setMaxFieldSize(int maxsize) does not return any value. * (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxFieldSize(int max) * method with an invalid value (negative value) and It should * throw a sql::DbcException * */ /* throws std::exception * */ void testSetMaxFieldSize02(); /* * @testName: testSetMaxRows01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxRows(int maxsize) method sets the maximum number * of rows that any ResultSet object can contain is specified * by the value maxsize. If the value maxsize is 0 then it means * that there is no limit. The setMaxRows(int maxsize) does not * return any value.(See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxRows(int rows) * method and call getMaxRows() method and it should return a * integer value that is been set * */ /* throws std::exception * */ void testSetMaxRows01(); /* * @testName: testSetMaxRows02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setMaxRows(int maxsize) method sets the maximum number * of rows that any ResultSet object can contain is specified * by the value maxsize. If the value maxsize is 0 then it means * that there is no limit. The setMaxRows(int maxsize) does not * return any value.(See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setMaxRows(int rows) * method with an invalid value (negative value) and It should * throw an sql::DbcException * */ /* throws std::exception * */ void testSetMaxRows02(); /* * @testName: testSetQueryTimeout02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setQueryTimeout(int secval) method sets the time limit * for the number of secval seconds a driver will wait for a * statement object to be executed. If the value secval is 0 * then it means that there is no limit. The setQueryTimeout * method does not return any value. (See JDK 1.2.2 API * Documentation) * * @test_Strategy: Get a Statement object and call the setQueryTimeout(int secval) * method with an invalid value (negative value)and It should * throw an sql::DbcException * */ /* throws std::exception * */ void testSetQueryTimeout02(); #endif /* * @testName: testGetResultSetType01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetType() method returns an integer value; * the value representing the type of the ResultSet objects * and the value can be any one of the following * ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_SENSITIVE * and ResultSet.TYPE_SCROLL_INSENSITIVE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call getResultSetType() method * It should return an int value which should be either * TYPE_FORWARD_ONLY or TYPE_SCROLL_INSENSITIVE or TYPE_SCROLL_SENSITIVE */ /* throws std::exception * */ void testGetResultSetType01(); /* * @testName: testGetResultSetType02 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetType() method returns an integer value; * the value representing the type of the ResultSet objects * and the value can be any one of the following * ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_SENSITIVE * and ResultSet.TYPE_SCROLL_INSENSITIVE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Call Connection.createStatement with the Type mode as * TYPE_FORWARD_ONLY and call getResultSetType() method * It should return a int value and the value should be equal * to ResultSet.TYPE_FORWARD_ONLY */ /* throws std::exception * */ void testGetResultSetType02(); #ifdef MISSING_METHODS_INCLUDED2STATEMENT /* * @testName: testSetFetchDirection04 * @assertion: A driver must provide support for Statement and * ResultSet. This implies that the methods in the * Statement interface must be implemented and must behave as * specified in the JDBC 1.0 and 2.0 specifications. (See * Section :40.3 Statement Methods JDBC 2.0 API Tutorial * & Reference). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The setFetchDirection(int dir) method sets the statement * object's fetch direction. The setFetchDirection method does * not return any value. (See JDK 1.2.2 API Documentation) * * @test_Strategy: Get a Statement object and call the setFetchDirection(int direction) * method with an invalid value and it should throw an sql::DbcException */ /* throws std::exception * */ void testSetFetchDirection04(); /* * @testName: testGetResultSetConcurrency01 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetConcurrency() method returns an integer value; * the value representing the concurrency mode for the ResultSet * objects and the value can be any one of the following * ResultSet.CONCUR_READ_ONLY and ResultSet.CONCUR_UPDATABLE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call getResultSetConcurrency() method * It should return an int value either CONCUR_READ_ONLY or * CONCUR_UPDATABLE. */ /* throws std::exception * */ void testGetResultSetConcurrency01(); /* * @testName: testGetResultSetType03 * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getResultSetType() method returns an integer value; * the value representing the type of the ResultSet objects * and the value can be any one of the following * ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_SENSITIVE * and ResultSet.TYPE_SCROLL_INSENSITIVE. * (See JDK1.2.2 API documentation) * * @test_Strategy: Call Connection.createStatement with the Type mode as * TYPE_SCROLL_INSENSITIVE and call getResultSetType() method * It should return a int value and the value should be equal * to ResultSet.TYPE_SCROLL_INSENSITIVE */ /* throws std::exception * */ void testGetResultSetType03(); /* * @testName: testGetFetchDirection * @assertion: The Statement object provides methods for executing SQL * statements and retrieving results.(See section 40.1 of * JDBC 2.0 API Reference & Tutorial second edition). * * The driver must provide full support for Statement methods. * The driver must also support all the methods for executing * SQL Statements in a single batch (Batch Updates). (See * section 6.2.2.3 of Java2 Platform Enterprise Edition(J2EE) * Specification v1.2) * * The getFetchDirection() method returns a integer value; * The value that is been set by the setFetchDirection method. * If no fetch direction has been set, the return value is * implementation specific. (See JDK1.2.2 API documentation) * * @test_Strategy: Get a Statement object and call the getFetchDirection() method * It should return a int value and the value should be equal to * any of the values FETCH_FORWARD or FETCH_REVERSE or FETCH_UNKNOWN * */ /* throws std::exception * */ void testGetFetchDirection(); #endif }; REGISTER_FIXTURE(StatementTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/UnbufferedRsStmtTest.cpp000644 015771 000012 00000003123 12645244437 030706 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "UnbufferedRsStmtTest.h" namespace testsuite { namespace compliance { UnbufferedRsStmtTest::UnbufferedRsStmtTest( const String & name ) : StatementTest( name ) { logMsg( "UnbufferedRsStmtTest ctor called" ); } void UnbufferedRsStmtTest::setUp() { logMsg( "UnbufferedRsStmtTest setUp called" ); super::setUp(); sql::ResultSet::enum_type unbuffered= sql::ResultSet::TYPE_FORWARD_ONLY; conn->setClientOption( "defaultStatementResultType", & unbuffered ); stmt->setResultSetType( unbuffered ); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/compliance/UnbufferedRsStmtTest.h000644 015771 000012 00000002673 12645244437 030364 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "StatementTest.h" namespace testsuite { namespace compliance { // Same testsuite, as Statement test class UnbufferedRsStmtTest : public StatementTest { private: typedef StatementTest super; protected: public: typedef UnbufferedRsStmtTest TestSuiteClass; UnbufferedRsStmtTest( const String & name ); virtual void setUp(); }; REGISTER_FIXTURE(UnbufferedRsStmtTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/cts.sql000644 015771 000012 00000030025 12645244437 023301 0ustar00pb2userwheel000000 000000 -- Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. -- -- The MySQL Connector/C++ is licensed under the terms of the GPLv2 -- , like most -- MySQL Connectors. There are special exceptions to the terms and -- conditions of the GPLv2 as it is applied to this software, see the -- FLOSS License Exception -- . -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published -- by the Free Software Foundation; version 2 of the License. -- -- This program is distributed in the hope that it will be useful, but -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. -- -- You should have received a copy of the GNU General Public License along -- with this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -- MySQL dump 9.07 -- -- Host: localhost Database: cts -- ------------------------------------------------------- -- Server version 4.0.8-gamma-max-nt-log -- -- Table structure for table 'bb_tab' -- DROP DATABASE IF EXISTS test; CREATE DATABASE test; USE test; CREATE TABLE BB_tab ( KEY_ID int(11) NOT NULL default '0', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'bb_tab' -- -- -- Table structure for table 'bigint_tab' -- CREATE TABLE Bigint_Tab ( MAX_VAL bigint(20) default NULL, MIN_VAL bigint(20) default NULL, NULL_VAL bigint(20) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'bigint_Tab' -- -- -- Table structure for table 'binary_Tab' -- CREATE TABLE Binary_Tab ( BINARY_VAL blob ) ENGINE=InnoDB; -- -- Dumping data for table 'binary_Tab' -- -- -- Table structure for table 'bit_Tab' -- CREATE TABLE Bit_Tab ( MAX_VAL tinyint(1) default NULL, MIN_VAL tinyint(1) default NULL, NULL_VAL tinyint(1) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'bit_Tab' -- -- -- Table structure for table 'char_Tab' -- CREATE TABLE Char_Tab ( COFFEE_NAME char(30) default NULL, NULL_VAL char(30) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'char_Tab' -- -- -- Table structure for table 'connector_Tab' -- CREATE TABLE Connector_Tab ( KEY_ID int(11) default NULL, PRODUCT_NAME varchar(32) default NULL, PRICE float default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'connector_Tab' -- -- -- Table structure for table 'ctstable1' -- CREATE TABLE ctstable1 ( TYPE_ID int(11) NOT NULL default '0', TYPE_DESC varchar(32) default NULL, PRIMARY KEY (TYPE_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'ctstable1' -- INSERT INTO ctstable1 VALUES (1,NULL); INSERT INTO ctstable1 VALUES (2,NULL); INSERT INTO ctstable1 VALUES (3,NULL); INSERT INTO ctstable1 VALUES (4,NULL); INSERT INTO ctstable1 VALUES (5,NULL); INSERT INTO ctstable1 VALUES (6,NULL); INSERT INTO ctstable1 VALUES (7,NULL); INSERT INTO ctstable1 VALUES (8,NULL); INSERT INTO ctstable1 VALUES (9,NULL); INSERT INTO ctstable1 VALUES (10,NULL); -- -- Table structure for table 'ctstable2' -- CREATE TABLE ctstable2 ( KEY_ID int(11) NOT NULL default '0', COF_NAME varchar(32) default NULL, PRICE float default NULL, TYPE_ID int(11) default NULL, PRIMARY KEY (KEY_ID), KEY TYPE_ID (TYPE_ID), FOREIGN KEY (`TYPE_ID`) REFERENCES `ctstable1` (`TYPE_ID`) ) ENGINE=InnoDB; -- -- Dumping data for table 'ctstable2' -- INSERT INTO ctstable2 VALUES (2,'Continue-2',2,2); INSERT INTO ctstable2 VALUES (3,'COFFEE-3',3,2); INSERT INTO ctstable2 VALUES (4,'COFFEE-4',4,3); INSERT INTO ctstable2 VALUES (5,'COFFEE-5',5,3); INSERT INTO ctstable2 VALUES (6,'COFFEE-6',6,3); INSERT INTO ctstable2 VALUES (7,'COFFEE-7',7,4); INSERT INTO ctstable2 VALUES (8,'COFFEE-8',8,4); INSERT INTO ctstable2 VALUES (9,'COFFEE-9',9,4); -- -- Table structure for table 'ctstable3' -- CREATE TABLE ctstable3 ( STRING1 varchar(20) default NULL, STRING2 varchar(20) default NULL, STRING3 varchar(20) default NULL, NUMCOL decimal(10,0) default NULL, FLOATCOL float default NULL, DATECOL date default NULL, TIMECOL time default NULL, TSCOL1 datetime default NULL, TSCOL2 datetime default NULL ) ENGINE=MyISAM; -- -- Dumping data for table 'ctstable3' -- -- -- Table structure for table 'ctstable4' -- CREATE TABLE ctstable4 ( STRING4 varchar(20) default NULL, NUMCOL decimal(10,0) default NULL ) ENGINE=MyISAM; -- -- Dumping data for table 'ctstable4' -- -- -- Table structure for table 'date_Tab' -- CREATE TABLE Date_Tab ( MFG_DATE date default NULL, NULL_VAL date default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'date_Tab' -- -- -- Table structure for table 'decimal_Tab' -- CREATE TABLE Decimal_Tab ( MAX_VAL decimal(30,15) default NULL, MIN_VAL decimal(30,15) default NULL, NULL_VAL decimal(30,15) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'decimal_Tab' -- -- -- Table structure for table 'deploy_Tab1' -- CREATE TABLE Deploy_Tab1 ( KEY_ID int(11) NOT NULL default '0', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'deploy_Tab1' -- -- -- Table structure for table 'deploy_Tab2' -- CREATE TABLE Deploy_Tab2 ( KEY_ID varchar(100) NOT NULL default '', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'deploy_Tab2' -- -- -- Table structure for table 'deploy_Tab3' -- CREATE TABLE Deploy_Tab3 ( KEY_ID bigint(20) NOT NULL default '0', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'deploy_Tab3' -- -- -- Table structure for table 'deploy_Tab4' -- CREATE TABLE Deploy_Tab4 ( KEY_ID float NOT NULL default '0', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'deploy_Tab4' -- -- -- Table structure for table 'deploy_Tab5' -- CREATE TABLE Deploy_Tab5 ( KEY_ID1 int(11) NOT NULL default '0', KEY_ID2 varchar(100) NOT NULL default '', KEY_ID3 float NOT NULL default '0', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID1,KEY_ID2,KEY_ID3) ) ENGINE=InnoDB; -- -- Dumping data for table 'deploy_Tab5' -- -- -- Table structure for table 'double_Tab' -- CREATE TABLE Double_Tab ( MAX_VAL double default NULL, MIN_VAL double default NULL, NULL_VAL double default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'double_Tab' -- -- -- Table structure for table 'float_Tab' -- CREATE TABLE Float_Tab ( MAX_VAL float default NULL, MIN_VAL float default NULL, NULL_VAL float default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'float_Tab' -- -- -- Table structure for table 'integer_Tab' -- CREATE TABLE Integer_Tab ( MAX_VAL int(11) default NULL, MIN_VAL int(11) default NULL, NULL_VAL int(11) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'integer_Tab' -- -- -- Table structure for table 'integration_sec_Tab' -- CREATE TABLE Integration_sec_Tab ( LOG_NO int(11) default NULL, LINE_NO int(11) default NULL, MESSAGE varchar(255) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'integration_sec_Tab' -- -- -- Table structure for table 'integration_Tab' -- CREATE TABLE Integration_Tab ( ACCOUNT int(11) NOT NULL default '0', BALANCE float default NULL, PRIMARY KEY (ACCOUNT) ) ENGINE=InnoDB; -- -- Dumping data for table 'integration_Tab' -- -- -- Table structure for table 'jta_Tab1' -- CREATE TABLE Jta_Tab1 ( KEY_ID int(11) default NULL, COF_NAME varchar(32) default NULL, PRICE float default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'jta_Tab1' -- -- -- Table structure for table 'jta_Tab2' -- CREATE TABLE Jta_Tab2 ( KEY_ID int(11) default NULL, CHOC_NAME varchar(32) default NULL, PRICE float default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'jta_Tab2' -- -- -- Table structure for table 'longvarbinary_Tab' -- CREATE TABLE Longvarbinary_Tab ( LONGVARBINARY_VAL longblob ) ENGINE=InnoDB; -- -- Dumping data for table 'longvarbinary_Tab' -- -- -- Table structure for table 'longvarchar_Tab' -- CREATE TABLE Longvarchar_Tab ( COFFEE_NAME mediumtext ) ENGINE=InnoDB; -- -- Dumping data for table 'longvarchar_Tab' -- INSERT INTO Longvarchar_Tab VALUES ('1999-12-31 12:59:59'); -- -- Table structure for table 'longvarcharnull_Tab' -- CREATE TABLE Longvarcharnull_Tab ( NULL_VAL mediumtext ) ENGINE=InnoDB; -- -- Dumping data for table 'longvarcharnull_Tab' -- -- -- Table structure for table 'numeric_Tab' -- CREATE TABLE Numeric_Tab ( MAX_VAL decimal(30,15) default NULL, MIN_VAL decimal(30,15) default NULL, NULL_VAL decimal(30,15) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'numeric_Tab' -- -- -- Table structure for table 'real_Tab' -- CREATE TABLE Real_Tab ( MAX_VAL double default NULL, MIN_VAL double default NULL, NULL_VAL double default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'real_Tab' -- -- -- Table structure for table 'sec_Tab1' -- CREATE TABLE Sec_Tab1 ( KEY_ID int(11) NOT NULL default '0', PRICE float default NULL, BRAND varchar(32) default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'sec_Tab1' -- -- -- Table structure for table 'smallint_Tab' -- CREATE TABLE Smallint_Tab ( MAX_VAL smallint(6) default NULL, MIN_VAL smallint(6) default NULL, NULL_VAL smallint(6) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'smallint_Tab' -- -- -- Table structure for table 'time_Tab' -- CREATE TABLE Time_Tab ( BRK_TIME time default NULL, NULL_VAL time default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'time_Tab' -- -- -- Table structure for table 'timestamp_Tab' -- CREATE TABLE Timestamp_Tab ( IN_TIME datetime default NULL, NULL_VAL datetime default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'timestamp_Tab' -- -- -- Table structure for table 'tinyint_Tab' -- CREATE TABLE Tinyint_Tab ( MAX_VAL tinyint(4) default NULL, MIN_VAL tinyint(4) default NULL, NULL_VAL tinyint(4) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'tinyint_Tab' -- -- -- Table structure for table 'txbean_Tab1' -- CREATE TABLE TXBean_Tab1 ( KEY_ID int(11) default NULL, TABONE_NAME varchar(32) default NULL, PRICE float default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'txbean_Tab1' -- -- -- Table structure for table 'txbean_Tab2' -- CREATE TABLE TXBean_Tab2 ( KEY_ID int(11) default NULL, TABTWO_NAME varchar(32) default NULL, PRICE float default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'txbean_Tab2' -- -- -- Table structure for table 'txebean_Tab' -- CREATE TABLE TXEBean_Tab ( KEY_ID int(11) NOT NULL default '0', BRAND_NAME varchar(32) default NULL, PRICE float default NULL, PRIMARY KEY (KEY_ID) ) ENGINE=InnoDB; -- -- Dumping data for table 'txebean_Tab' -- -- -- Table structure for table 'varbinary_Tab' -- CREATE TABLE Varbinary_Tab ( VARBINARY_VAL blob ) ENGINE=InnoDB; -- -- Dumping data for table 'varbinary_Tab' -- -- -- Table structure for table 'varchar_Tab' -- CREATE TABLE Varchar_Tab ( COFFEE_NAME varchar(30) default NULL, NULL_VAL varchar(30) default NULL ) ENGINE=InnoDB; -- -- Dumping data for table 'varchar_Tab' -- -- -- Table structure for table 'xa_Tab1' -- CREATE TABLE XA_Tab1 ( col1 int(11) NOT NULL default '0', col2 varchar(32) default NULL, col3 varchar(32) default NULL, PRIMARY KEY (col1) ) ENGINE=InnoDB; -- -- Dumping data for table 'xa_Tab1' -- -- -- Table structure for table 'xa_Tab2' -- CREATE TABLE XA_Tab2 ( col1 int(11) NOT NULL default '0', col2 varchar(32) default NULL, col3 varchar(32) default NULL, PRIMARY KEY (col1) ) ENGINE=InnoDB; -- -- Dumping data for table 'xa_Tab2' -- mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/BlobRegressionTest.cpp000644 015771 000012 00000026322 12645244437 030437 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "BlobRegressionTest.h" #include "../../common/file.h" #include namespace testsuite { namespace regression { /** * Dunno how this test should look like in C++ * * @throws Exception * ... */ /* void BlobRegressionTest::testBug2670() { if (!isRunningOnJdk131()) { try { char blobData[32]; for (int i = 0; i < blobData.length; i++) { blobData[i] = 1; } stmt->executeUpdate("DROP TABLE IF EXISTS testBug2670"); stmt->executeUpdate("CREATE TABLE testBug2670(blobField LONGBLOB)"); PreparedStatement pstmt-> conn->prepareStatement("INSERT INTO testBug2670 (blobField) VALUES (?)"); pstmt->setBytes(1, blobData); pstmt->executeUpdate(); rs = stmt->executeQuery("SELECT blobField FROM testBug2670"); rs->next(); Blob blob = rs->getBlob(1); blob.setBytes(4, new char { 2, 2, 2, 2 }); char newBlobData = blob.getBytes(1L, (int) blob.length()); assertTrue("Blob changed length", blob.length() == blobData.length); assertTrue( "New data inserted wrongly", ((newBlobData[3] == 2) && (newBlobData[4] == 2) && (newBlobData[5] == 2) && (newBlobData[6] == 2))); blob.setBytes(32, new char { 2, 2, 2, 2 }); assertTrue("Blob length should be 3 larger", blob.length() == (blobData.length + 3)); } { stmt->executeUpdate("DROP TABLE IF EXISTS testUpdateLongBlob"); } } }*/ /** * @throws Exception * ... */ void BlobRegressionTest::testUpdateLongBlobGT16M() { if ( this->versionMeetsMinimum(4, 0) ) { int size18M= 18 * 1024 * 1024; String blobData; // 18M blob blobData.append( size18M, 'a' ); stmt->executeUpdate("DROP TABLE IF EXISTS testUpdateLongBlob"); stmt->executeUpdate("CREATE TABLE testUpdateLongBlob(blobField LONGBLOB)"); stmt->executeUpdate("INSERT INTO testUpdateLongBlob (blobField) VALUES (NULL)"); pstmt.reset( conn->prepareStatement("UPDATE testUpdateLongBlob SET blobField=?") ); pstmt->setString(1, blobData ); pstmt->execute(); stmt->executeUpdate("DROP TABLE IF EXISTS testUpdateLongBlob"); } } /** * * @throws Exception */ /* throws Exception */ /* void BlobRegressionTest::testUpdatableBlobsWithCharsets() { char smallBlob[32]; for (char i = 0; i < sizeof(smallBlob); ++i) { smallBlob[i] = i; } stmt->executeUpdate("DROP TABLE IF EXISTS testUpdatableBlobsWithCharsets"); stmt->executeUpdate("CREATE TABLE testUpdatableBlobsWithCharsets(pk INT NOT NULL PRIMARY KEY, field1 BLOB)"); std::istringstream str( smallBlob ); PreparedStatement pstmt( conn->prepareStatement("INSERT INTO testUpdatableBlobsWithCharsets (pk, field1) VALUES (1, ?)") ); pstmt->setBlob( 1, & str ); pstmt->executeUpdate(); Statement updstmt( conn->createStatement() ); rs.reset( updstmt->executeQuery("SELECT pk, field1 FROM testUpdatableBlobsWithCharsets") ); rs->next(); MESSAGE( rs->getString(1) + "->" + rs->getString(2) ); for (char i = 0; i < sizeof( smallBlob ); ++i) { smallBlob[i] = i + 32; } //we don't support that yet. so the whole test doesn't make sense either / * rs->setBlob(2, std::istringstream(smallBlob), sizeof(smallBlob) ); rs->updateRow();* / ResultSet newRs( stmt->executeQuery("SELECT field1 FROM testUpdatableBlobsWithCharsets") ); newRs->next(); String updatedBlob( newRs->getString(1) ); for (byte i = 0; i < sizeof(smallBlob); i++) { char origValue = smallBlob[i]; char newValue = updatedBlob[i]; assertTrue(String( "Original byte at position " ) + i + ", " + origValue + " != new value, " + newValue, origValue == newValue); } stmt->executeUpdate("DROP TABLE IF EXISTS testUpdatableBlobsWithCharsets"); }*/ /* throws Exception */ void BlobRegressionTest::testBug5490() { stmt->executeUpdate("DROP TABLE IF EXISTS testBug5490"); stmt->executeUpdate("CREATE TABLE testBug5490"\ "(pk INT NOT NULL PRIMARY KEY, blobField BLOB)"); String sql = "insert into testBug5490 values(?,?)"; int blobFileSize = 871; FileUtils::ccppFile blobFile("Bug5490"); if( ! blobFile.exists() || blobFile.getSize() != blobFileSize ) { blobFile.deleteFile(); std::fstream & fos= blobFile.getStream(); fos.seekp( blobFileSize - 1, std::ios_base::beg ); fos << 'a'; fos.flush(); blobFile.close(); } pstmt.reset( conn->prepareStatement(sql) ); pstmt->setInt(1, 2); pstmt->setBlob(2, & blobFile.getStream() ); pstmt->execute(); blobFile.close(); rs.reset( stmt->executeQuery("SELECT blobField FROM testBug5490") ); rs->next(); String returned = rs->getString( 1 ); ASSERT_EQUALS( blobFileSize, static_cast(returned.length()) ); stmt->executeUpdate("DROP TABLE IF EXISTS testBug5490"); if ( blobFile.exists() ) blobFile.deleteFile(); } /** * Tests BUG#8096 where emulated locators corrupt binary data when using * server-side prepared statements. * * @throws Exception * if the test fails. */ /* looks like doesn't make much sense here either */ void BlobRegressionTest::testBug8096() { const int dataSize = 256; Properties props ; props["emulateLocators"]= "true"; Connection locatorConn( getConnectionWithProps(props) ); stmt.reset( locatorConn->createStatement() ); selectDb( stmt ); String createTable( "CREATE TABLE testBug8096 (ID VARCHAR(10) "\ "PRIMARY KEY, DATA LONGBLOB)" ); String select( "SELECT ID, 'DATA' AS BLOB_DATA FROM testBug8096 "\ "WHERE ID = ?" ); String insert( "INSERT INTO testBug8096 (ID, DATA) VALUES (?, '')" ); String id( "1" ); char testData[dataSize]; for ( unsigned int i= 0; i < sizeof( testData ); ++i) { testData[i]= static_cast( i & 0xff ); } stmt->executeUpdate("DROP TABLE IF EXISTS testBug8096"); stmt->executeUpdate(createTable); pstmt.reset( locatorConn->prepareStatement( insert ) ); pstmt->setString(1, id); pstmt->execute(); pstmt.reset( locatorConn->prepareStatement(select) ); pstmt->setString(1, id); rs.reset( pstmt->executeQuery() ); if ( rs->next() ) { std::istream * b = rs->getBlob("BLOB_DATA"); (void) b; // void is to trick the compiler into generating no warnings //b.setBytes(1, testData); } pstmt.reset( locatorConn->prepareStatement(select) ); pstmt->setString(1, id); rs.reset(pstmt->executeQuery()); String result; if ( rs->next() ) { result = rs->getString(1); } ASSERT( result.length() > 0 ); for (unsigned i = 0; i < result.length() && i < sizeof(testData); ++i) { if (result[i] != testData[i]) { std::ostringstream s; s << "At position "<< i << " test data: " << static_cast(testData[i]) << " result " << static_cast(result[i]); ASSERT_MESSAGE( testData[i] == result[i], s.str().c_str() ); } } stmt->executeUpdate("DROP TABLE IF EXISTS testBug8096"); } /** * Tests fix for BUG#9040 - PreparedStatement.addBatch() doesn't work with * server-side prepared statements and streaming BINARY data. * * @throws Exception * if the test fails. */ /* not relevant at the moment - no batches */ /* void BlobRegressionTest::testBug9040() { stmt->executeUpdate("DROP TABLE IF EXISTS testBug9040"); stmt->executeUpdate("create table if not exists testBug9040 " + "(primary_key int not NULL primary key, " + "data mediumblob)"); pstmt-> conn->prepareStatement("replace into testBug9040 (primary_key, data) values(?,?)"); int primaryKey = 1; char data[] = "First Row"; pstmt->setInt(1, primaryKey); pstmt->setBinaryStream(2, new ByteArrayInputStream(data), data.length); pstmt->addBatch(); primaryKey = 2; data = "Second Row".getBytes(); pstmt->setInt(1, primaryKey); pstmt->setBinaryStream(2, new ByteArrayInputStream(data), data.length); pstmt->addBatch(); pstmt->executeBatch(); stmt->executeUpdate("DROP TABLE IF EXISTS testBug9040"); } }*/ /* throws Exception */ void BlobRegressionTest::testBug10850() { String tableName = "testBug10850"; createTable(tableName, "(field1 TEXT)"); pstmt.reset( conn->prepareStatement(String( "INSERT INTO " ) + tableName + " VALUES (?)") ); std::istringstream str(""); pstmt->setBlob(1, & str); pstmt->executeUpdate(); ASSERT( getSingleIndexedValueWithQuery(1, String( "SELECT LENGTH(field1) FROM " ) + tableName).toString() == "0"); stmt->executeUpdate(String( "TRUNCATE TABLE " ) + tableName); pstmt->clearParameters(); std::istringstream str2; pstmt->setBlob( 1, &str ); pstmt->executeUpdate(); ASSERT( getSingleIndexedValueWithQuery(1, String( "SELECT LENGTH(field1) FROM " ) + tableName).toString() == "0" ); stmt->executeUpdate(String( "TRUNCATE TABLE " ) + tableName); } /* throws Exception */ /** Doesn't make much sense. As well as i'm not sure it's equivalenly translated*/ void BlobRegressionTest::testBug34677() { SKIP( "The test is wrong" ); createTable("testBug34677", "(field1 BLOB)"); stmt->executeUpdate("INSERT INTO testBug34677 VALUES ('abc')"); rs.reset( stmt->executeQuery("SELECT field1 FROM testBug34677") ); rs->next(); MESSAGE( rs->getString( 1 ) + "<- field1 in testBug34677" ); std::istream * blob = rs->getBlob(1); blob->width(0L); ASSERT_EQUALS(0, (int)blob->width()); char tmp; if ( ! blob->read(&tmp,1).fail() ) { TestsListener::errorsLog() << "read: " << tmp << static_cast(tmp) << std::endl; FAIL( "But probably that's ok - bad test likely" ); } } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/BlobRegressionTest.h000644 015771 000012 00000005620 12645244437 030102 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /** * Tests fixes for BLOB handling. * * @author Mark Matthews * @version $Id: BlobRegressionTest.java,v 1.1.2.19 2005/03/09 18:16:16 * mmatthews Exp $ */ namespace testsuite { namespace regression { class BlobRegressionTest : public BaseTestFixture { private: typedef BaseTestFixture super; public: TEST_FIXTURE( BlobRegressionTest ) { //TEST_CASE( testBug2670 ); //TEST_CASE( testUpdatableBlobsWithCharsets ); TEST_CASE( testBug5490 ); // not relevant to c/c++ (at least) at the moment //TEST_CASE( testBug8096 ); //TEST_CASE( testBug9040 ); TEST_CASE( testBug10850 ); TEST_CASE( testBug34677 ); // TEST_CASE( testUpdateLongBlobGT16M ); } /** * Looks irrelevant at least at the moment. * @throws std::exception * */ //void testBug2670() ; /** * @throws std::exception * * ... */ void testUpdateLongBlobGT16M(); /** * @throws std::exception * */ //void testUpdatableBlobsWithCharsets(); /* throws std::exception * */ void testBug5490(); /** * Tests BUG#8096 where emulated locators corrupt binary data when using * server-side prepared statements. * * @throws std::exception * * if the test fails. */ void testBug8096(); /** * Tests fix for BUG#9040 - PreparedStatement.addBatch() doesn't work with * server-side prepared statements and streaming BINARY data. * * @throws std::exception * * if the test fails. Irrelevant - May become useful later */ //void testBug9040(); /* throws std::exception * */ void testBug10850(); /* throws std::exception * */ void testBug34677(); }; REGISTER_FIXTURE(BlobRegressionTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/EscapeProcessorRegressionTest.cpp000644 015771 000012 00000005366 12645244437 032666 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "EscapeProcessorRegressionTest.h" namespace testsuite { namespace regression { /** * Tests fix for BUG#11797 - Escape tokenizer doesn't respect stacked single * quotes for escapes. * * @throws Exception * if the test fails. */ /* throws Exception */ void EscapeProcessorRegressionTest::testBug11797() { ASSERT_EQUALS("select 'ESCAPED BY ''\\'' ON {tbl_name | * | *.* | db_name.*}'", this->conn->nativeSQL("select 'ESCAPED BY ''\\'' ON {tbl_name | * | *.* | db_name.*}'")); } /** * Tests fix for BUG#11498 - Escape processor didn't honor strings * demarcated with double quotes. * * @throws Exception * if the test fails. */ /* throws Exception */ void EscapeProcessorRegressionTest::testBug11498() { ASSERT_EQUALS( "replace into t1 (id, f1, f4) VALUES(1,\"\",\"tko { zna gdje se sakrio\"),(2,\"a\",\"sedmi { kontinentio\"),(3,\"a\",\"a } cigov si ti?\")", this->conn->nativeSQL("replace into t1 (id, f1, f4) VALUES(1,\"\",\"tko { zna gdje se sakrio\"),(2,\"a\",\"sedmi { kontinentio\"),(3,\"a\",\"a } cigov si ti?\")")); } /** * Tests fix for BUG#14909 - escape processor replaces quote character in * quoted string with string delimiter. * * @throws Exception */ /* throws Exception */ void EscapeProcessorRegressionTest::testBug14909() { ASSERT_EQUALS("select '{\"','}'", this->conn->nativeSQL("select '{\"','}'")); } /** * Tests fix for BUG#25399 - EscapeProcessor gets confused by multiple backslashes * * @throws Exception if the test fails. */ /* throws Exception */ void EscapeProcessorRegressionTest::testBug25399() { /* ASSERT_EQUALS("\\' {d}", getSingleValueWithQuery("SELECT '\\\\\\' {d}'"));*/ } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/EscapeProcessorRegressionTest.h000644 015771 000012 00000004622 12645244437 032325 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /** * Tests regressions w/ the Escape Processor code. * * @version $Id:$ * */ namespace testsuite { namespace regression { class EscapeProcessorRegressionTest : public BaseTestFixture { private: typedef BaseTestFixture super; protected: public: TEST_FIXTURE(EscapeProcessorRegressionTest) { TEST_CASE(testBug11797); TEST_CASE(testBug11498); TEST_CASE(testBug14909); TEST_CASE(testBug25399); } /** * Tests fix for BUG#11797 - Escape tokenizer doesn't respect stacked single * quotes for escapes. * * @throws Exception * if the test fails. */ /* throws Exception */ void testBug11797(); /** * Tests fix for BUG#11498 - Escape processor didn't honor strings * demarcated with double quotes. * * @throws Exception * if the test fails. */ /* throws Exception */ void testBug11498(); /** * Tests fix for BUG#14909 - escape processor replaces quote character in * quoted string with string delimiter. * * @throws Exception */ /* throws Exception */ void testBug14909(); /** * Tests fix for BUG#25399 - EscapeProcessor gets confused by multiple backslashes * * @throws Exception if the test fails. */ /* throws Exception */ void testBug25399(); }; REGISTER_FIXTURE(EscapeProcessorRegressionTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/PreparedStatementRegressionTest.cpp000644 015771 000012 00000003157 12645244437 033211 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "PreparedStatementRegressionTest.h" namespace testsuite { namespace regression { void PreparedStatementRegressionTest::testStmtClose() { pstmt.reset( conn->prepareStatement( "select ?" ) ); pstmt->setString( 1, "dummy" ); ResultSet tmp(pstmt->executeQuery()); pstmt->close(); // Application crashed on the destructor if close was closed before. // prepared statement had to contain any parameter. pstmt.reset(); } void PreparedStatementRegressionTest::setUp() { super::setUp(); dbmd= conn->getMetaData(); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/PreparedStatementRegressionTest.h000644 015771 000012 00000003154 12645244437 032653 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /** * @author */ namespace testsuite { namespace regression { class PreparedStatementRegressionTest : public BaseTestFixture { private: typedef BaseTestFixture super; DatabaseMetaData dbmd; protected: /** * setUp() function for tests */ /* throws std::exception * */ void setUp(); public: TEST_FIXTURE(PreparedStatementRegressionTest) { TEST_CASE( testStmtClose ); } void testStmtClose(); }; REGISTER_FIXTURE(PreparedStatementRegressionTest); } //namespace regression } //namespace testsuite mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/SubqueriesRegressionTest.cpp000644 015771 000012 00000016500 12645244437 031705 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "SubqueriesRegressionTest.h" namespace testsuite { namespace regression { const int SubqueriesRegressionTest::REPETITIONS = 100; /* * (non-Javadoc) * * @see junit.framework.TestCase#setUp() */ /* throws Exception */ void SubqueriesRegressionTest::setUp() { super::setUp(); createTables(); } /* * (non-Javadoc) * * @see junit.framework.TestCase#tearDown() */ /* throws Exception */ void SubqueriesRegressionTest::tearDown() { dropTables(); super::tearDown(); } /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void SubqueriesRegressionTest::testSubQuery1() { if (versionMeetsMinimum(4, 1)) { for (int i = 0; i < REPETITIONS; i++) { rs.reset( stmt->executeQuery("select t3.colA from t3, t1 "\ "where t3.colA = 'bbbb' "\ "and t3.colB = t1.colA "\ "and exists (select 'X' "\ "from t2 "\ "where t2.colB = t1.colB)")); ASSERT(rs->next()); ASSERT_EQUALS( "bbbb", rs->getString(1) ); ASSERT(!rs->next()); } } } /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void SubqueriesRegressionTest::testSubQuery2() { if (versionMeetsMinimum(4, 1)) { for (int i = 0; i < REPETITIONS; i++) { rs.reset( stmt->executeQuery("select t3.colA from t3, t1"\ " where t3.colA = 'bbbb' "\ "and t3.colB = t1.colA "\ "and exists (select 'X' from t2 "\ "where t2.colB = 2)") ); ASSERT(rs->next()); ASSERT_EQUALS( "bbbb", rs->getString(1) ); ASSERT(!rs->next()); } } } /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void SubqueriesRegressionTest::testSubQuery3() { if (versionMeetsMinimum(4, 1)) { for (int i = 0; i < REPETITIONS; i++) { rs.reset( stmt->executeQuery("select * from t1 where t1.colA = 'efgh' "\ "and exists (select 'X' from t2 "\ "where t2.colB = t1.colB)") ); ASSERT(rs->next()); ASSERT_EQUALS( "efgh" , rs->getString(1) ); ASSERT_EQUALS( "2" , rs->getString(2) ); ASSERT(!rs->next()); } } } /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void SubqueriesRegressionTest::testSubQuery4() { if ( versionMeetsMinimum(4, 1) ) { for (int i = 0; i < REPETITIONS; i++) { rs.reset( stmt->executeQuery("select colA, '' from t2"\ " union select colA, colB from t3") ); ASSERT(rs->next()); ASSERT_EQUALS("type1", rs->getString(1) ); ASSERT_EQUALS("" , rs->getString(2) ); ASSERT(rs->next()); ASSERT_EQUALS("type2", rs->getString(1) ); ASSERT_EQUALS("" , rs->getString(2) ); ASSERT(rs->next()); ASSERT_EQUALS("type3", rs->getString(1) ); ASSERT_EQUALS("" , rs->getString(2) ); ASSERT(rs->next()); ASSERT_EQUALS("aaaa", rs->getString(1)); ASSERT_MESSAGE( rs->getString(2) == "abcd", String( "'" ) + rs->getString(2) + "' != expected of 'abcd'" ); ASSERT(rs->next()); ASSERT_EQUALS("bbbb", rs->getString(1) ); ASSERT_EQUALS("efgh", rs->getString(2) ); ASSERT(rs->next()); ASSERT_EQUALS("cccc", rs->getString(1) ); ASSERT_MESSAGE(rs->getString(2) == "ijkl", String( "'" ) + rs->getString(2) + "' != expected of 'ijkl'" ); ASSERT(!rs->next()); } } } /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void SubqueriesRegressionTest::testSubQuery5() { if ( versionMeetsMinimum(4, 1) ) { for (int i = 0; i < REPETITIONS; i++) { rs.reset( stmt->executeQuery("select t1.colA from t1, t4 where t4.colA = t1.colA "\ "and exists (select 'X' from t2 where t2.colA = t4.colB)") ); ASSERT(rs->next()); ASSERT_EQUALS( "abcd", rs->getString(1) ); ASSERT(rs->next()); ASSERT_EQUALS( "efgh", rs->getString(1) ); ASSERT(rs->next()); ASSERT_EQUALS( "ijkl", rs->getString(1) ); ASSERT(!rs->next()); } } } /* throws Exception */ void SubqueriesRegressionTest::createTables() { stmt->executeUpdate("drop table if exists t1"); stmt->executeUpdate("drop table if exists t2"); stmt->executeUpdate("drop table if exists t3"); stmt->executeUpdate("drop table if exists t4"); stmt->executeUpdate("create table t1(colA varchar(10), colB decimal(3,0))"); stmt->executeUpdate("create table t2(colA varchar(10), colB varchar(10))"); stmt->executeUpdate("create table t3(colA varchar(10), colB varchar(10))"); stmt->executeUpdate("create table t4(colA varchar(10), colB varchar(10))"); stmt->executeUpdate("insert into t1 values ('abcd', 1), ('efgh', 2)"\ ", ('ijkl', 3)" ); stmt->executeUpdate("insert into t2 values ('type1', '1'), ('type2', '2')"\ ", ('type3', '3')"); stmt->executeUpdate("insert into t3 values ('aaaa', 'abcd')"\ ", ('bbbb', 'efgh')"\ ", ('cccc', 'ijkl')"); stmt->executeUpdate("insert into t4 values ('abcd', 'type1')"\ ", ('efgh', 'type2')"\ ", ('ijkl', 'type3')"); } /* throws Exception */ void SubqueriesRegressionTest::dropTables() { stmt->executeUpdate("drop table if exists t1"); stmt->executeUpdate("drop table if exists t2"); stmt->executeUpdate("drop table if exists t3"); stmt->executeUpdate("drop table if exists t4"); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/regression/SubqueriesRegressionTest.h000644 015771 000012 00000005413 12645244437 031353 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../BaseTestFixture.h" /** * Tests SubQueries on MySQL > 4.1 * * @author Mark Matthews * @version $Id: SubqueriesRegressionTest.java,v 1.1.2.1 2005/05/13 18:58:38 * mmatthews Exp $ */ namespace testsuite { namespace regression { class SubqueriesRegressionTest : public BaseTestFixture { private: typedef BaseTestFixture super; static const int REPETITIONS; /* throws std::exception * */ void createTables() ; /* throws std::exception * */ void dropTables() ; protected: public: TEST_FIXTURE( SubqueriesRegressionTest ) { TEST_CASE( testSubQuery1 ); TEST_CASE( testSubQuery2 ); TEST_CASE( testSubQuery3 ); TEST_CASE( testSubQuery4 ); TEST_CASE( testSubQuery5 ); } /* throws std::exception * */ void setUp() ; /* throws std::exception * */ void tearDown() ; /** * DOCUMENT ME! * * @throws std::exception * * DOCUMENT ME! */ /* throws std::exception * */ void testSubQuery1() ; /** * DOCUMENT ME! * * @throws std::exception * * DOCUMENT ME! */ /* throws std::exception * */ void testSubQuery2() ; /** * DOCUMENT ME! * * @throws std::exception * * DOCUMENT ME! */ /* throws std::exception * */ void testSubQuery3() ; /** * DOCUMENT ME! * * @throws std::exception * * DOCUMENT ME! */ /* throws std::exception * */ void testSubQuery4() ; /** * DOCUMENT ME! * * @throws std::exception * * DOCUMENT ME! */ /* throws std::exception * */ void testSubQuery5() ; }; REGISTER_FIXTURE(SubqueriesRegressionTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/resources.cpp000644 015771 000012 00000017414 12645244437 024514 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "resources.h" #include "../common/stringutils.h" namespace testsuite { namespace resources { void CharsetMapping::Init() { STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("big5"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("dec8"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp850"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("hp8"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("koi8r"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("latin1"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("latin2"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("swe7"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("ascii"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("ujis"), 3U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("sjis"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("hebrew"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("tis620"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("euckr"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("koi8u"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("gb2312"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("greek"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp1250"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("gbk"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("latin5"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("armscii8"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("utf8"), 3U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("ucs2"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp866"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("keybcs2"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("macce"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("macroman"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp852"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("latin7"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp1251"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp1256"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp1257"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("binary"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("geostd8"), 1U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("cp932"), 2U)); STATIC_CHARSET_TO_NUM_BYTES_MAP.insert( std::map::value_type(_T("eucjpms"), 3U)); } const CharsetMapping & CharsetMapping::Instance() { static CharsetMapping instance; return instance; } bool OpenFile(std::ifstream & fileStream, const String & fileName , const char * _possibleLocations[]) { fileStream.open(fileName.c_str()); int i=0; while (!fileStream.is_open() && _possibleLocations != NULL && _possibleLocations[ i ] != NULL) { fileStream.clear(); fileStream.open((String(_possibleLocations[ i ]) + "/" + fileName).c_str()); ++i; } return fileStream.is_open(); } int LoadProperties(const String & fileName, Properties & props , const char * _possibleLocations[]) { int counter=0; std::ifstream propsFile; if (OpenFile(propsFile, fileName, _possibleLocations)) { String line; while (getline(propsFile, line)) { StringUtils::trim(line); // Not empty line or a comment if (!propsFile.eof() && line.size() > 0 && line.c_str()[0] != '#') { String::size_type pos=line.find_first_of("="); if (pos != String::npos && pos > 0) { String key=line.substr(0, pos); String val=line.substr(pos + 1); StringUtils::trim( key ); StringUtils::trim( val ); props.insert(Properties::value_type(key, val)); ++counter; } } } propsFile.close(); } else { std::cout << "Unable to open file" << std::endl; return -1; } return counter; } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/resources.h000644 015771 000012 00000003307 12645244437 024155 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _TESTSUITE_RESOURCES_H_ #define _TESTSUITE_RESOURCES_H_ #include "../common/ccppTypes.h" namespace testsuite { namespace resources { class CharsetMapping { public: typedef std::map Map; typedef Map::const_iterator cit; private: /* Hiding constructor */ CharsetMapping() { Init(); } Map STATIC_CHARSET_TO_NUM_BYTES_MAP; void Init(); public: static const CharsetMapping & Instance(); const Map & GetMap() const { return STATIC_CHARSET_TO_NUM_BYTES_MAP; } }; int LoadProperties(const String & fileName, Properties &props , const char * _possibleLocations[]=NULL); } } #endif mysql-connector-c++-1.1.7/test/CJUnitTestsPort/simple/BlobTest.cpp000644 015771 000012 00000020564 12645244437 025511 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "BlobTest.h" #define BYTE_MAX_VALUE 255 #define BYTE_MIN_VALUE 0 namespace testsuite { namespace simple { const String BlobTest::TEST_BLOB_FILE_PREFIX("cmj-testblob"); /** * Setup the test case * * @throws Exception * if an error occurs */ void BlobTest::setUp() { static int counter= 0; // Just to make 2nd run(setString) to use smaller file(and be faster) ++counter; super::setUp(); realFrameworkTiming=TestsListener::doTiming(); testBlobFile.reset(new FileUtils::ccppFile(TEST_BLOB_FILE_PREFIX + ".dat")); int requiredSize=16 * 1024 * 1024/counter - (counter - 1)*128; if (!versionMeetsMinimum(4, 0)) { requiredSize=8 * 1024 * 1024; } Timer::startTimer("BlobTest::testByteStreamInsert", "Blob File Creation", __FILE__, __LINE__); createBlobFile(requiredSize); TestsListener::messagesLog() << "Blob File Creation" << Timer::translate2seconds(Timer::stopTimer("BlobTest::testByteStreamInsert", "Blob File Creation")) << std::endl; createTestTable(); } /** * Destroy resources created by test case * * @throws Exception * if an error occurs */ /* throws Exception */ void BlobTest::tearDown() { stmt->executeUpdate("DROP TABLE IF EXISTS BLOBTEST"); testBlobFile.reset(); TestsListener::doTiming(realFrameworkTiming); super::tearDown(); } /* throws Exception */ void BlobTest::testBlobStreamInsert() { //SKIP("too slow"); testBlobInsert( conn ); } void BlobTest::testBlobStringInsert() { //SKIP("too slow"); testBlobInsert( conn, true ); } /** * Tests inserting blob data as a stream * * @throws Exception * if an error occurs */ void BlobTest::testBlobInsert( Connection & c, bool asString ) { TIMER_START( "Populating blob table" ); pstmt.reset( conn->prepareStatement("INSERT INTO BLOBTEST(blobdata) VALUES (?)") ); if ( asString ) { sql::SQLString str; testBlobFile->readFile( const_cast(str.asStdString()) ); pstmt->setString( 1, str ); pstmt->execute(); } else { std::fstream & bIn= testBlobFile->getStream(); ASSERT( ! bIn.fail() ); pstmt->setBlob( 1, & bIn ); pstmt->execute(); } TIMER_STOP("Populating blob table"); pstmt->clearParameters(); doRetrieval(); } /* throws Exception */ bool BlobTest::checkBlob(const String & retrBytes) { bool passed=true; std::fstream & bIn=testBlobFile->getStream(); bIn.seekg(0, std::ios_base::beg); ASSERT_MESSAGE(!bIn.fail(), "seekg 0 position from the beginning - failed"); ASSERT_MESSAGE(!bIn.eof(), "stream is at eof"); unsigned int fileLength=testBlobFile->getSize(); ASSERT_EQUALS((unsigned int) retrBytes.size(), fileLength); int substrIdx=0; while (!bIn.eof()) { char fromFile[8192]; bIn.read(fromFile, sizeof (fromFile)); ASSERT_MESSAGE(!bIn.fail() || bIn.eof(), "read from file failed"); if (bIn.gcount() == 0) { logMsg("We did not get any data from our input stream, we cannot do the compare input and output."); logMsg("Lets be gentle and consider the test as passed."); break; } if (retrBytes.compare(substrIdx, bIn.gcount(), fromFile, bIn.gcount()) != 0) { passed=false; int j=0; TestsListener::errorsLog() << "compare returned !=0 at " << substrIdx << ", read from file " << bIn.gcount() << std::endl; while (j < bIn.gcount() && fromFile[ j ] == retrBytes[substrIdx + j]) ++j; if (j < bIn.gcount()) { TestsListener::errorsLog() << "Byte pattern differed at position " << j << " , Retrieved: " << retrBytes[ substrIdx + j ] << "(" << StringUtils::toHexString(retrBytes[ substrIdx + j ]) << ") != From File:" << fromFile[ j ] << "(" << StringUtils::toHexString(fromFile[ j ]) << ")" << std::endl; if (j < bIn.gcount() - 1) { TestsListener::errorsLog() << "Following bytes (table:file):"; while (j < bIn.gcount()) { // current byte was already printed; ++j; TestsListener::errorsLog() << " (" << StringUtils::toHexString(retrBytes[ substrIdx + j ]) << ":" << StringUtils::toHexString(fromFile[ j ]) << ")"; } TestsListener::errorsLog() << std::endl; } } break; } substrIdx+=static_cast (bIn.gcount()); } return passed; } /* throws Exception */ void BlobTest::createTestTable() { try { stmt->executeUpdate("DROP TABLE BLOBTEST"); } catch (sql::SQLException &) { } stmt->executeUpdate("CREATE TABLE BLOBTEST (pos int PRIMARY KEY auto_increment, "\ "blobdata LONGBLOB)"); } /** * Mark this as deprecated to avoid warnings from compiler... * * @deprecated * * @throws Exception * if an error occurs retrieving the value */ /* throws Exception */ void BlobTest::doRetrieval() { bool passed=false; TIMER_START("Blob Retrieval"); rs.reset(stmt->executeQuery("SELECT blobdata from BLOBTEST LIMIT 1")); rs->next(); TIMER_STOP("Blob Retrieval"); TIMER_START("getString"); String s(rs->getString(1)); TIMER_STOP("getString"); TIMER_START("Blob Check 1"); passed=checkBlob(s); TIMER_STOP("Blob Check 1"); ASSERT_MESSAGE(passed, "Inserted BLOB data did not match retrieved BLOB data for getString()."); s.clear(); TIMER_START("getBlob"); boost::scoped_ptr inStr(rs->getBlob(1)); TIMER_STOP("getBlob"); TIMER_START("Stream Reading"); char buff[1048]; while (!inStr->eof()) { inStr->read(buff, sizeof (buff)); s.append(buff, inStr->gcount()); } TIMER_STOP("Stream Reading"); TIMER_START("Blob Check 2"); passed=checkBlob(s); TIMER_STOP("Blob Check 2"); ASSERT_MESSAGE(passed, "Inserted BLOB data did not match retrieved BLOB data for getBlob()."); /* inStr = rs->getAsciiStream(1); bOut = new ByteArrayOutputStream(); while ((b = inStr.read()) != -1) { bOut.write((byte) b); } retrBytes = bOut.toByteArray(); passed = checkBlob(retrBytes); assertTrue( "Inserted BLOB data did not match retrieved BLOB data for getAsciiStream().", passed); inStr = rs->getUnicodeStream(1); bOut = new ByteArrayOutputStream(); while ((b = inStr.read()) != -1) { bOut.write((byte) b); } retrBytes = bOut.toByteArray(); passed = checkBlob(retrBytes); assertTrue( "Inserted BLOB data did not match retrieved BLOB data for getUnicodeStream().", passed);*/ } /* throws Exception */ void BlobTest::createBlobFile(int size) { if (testBlobFile.get() != NULL && testBlobFile->getSize() != size) { TestsListener::messagesLog("creating file!!!"); testBlobFile->deleteFile(); //testBlobFile.reset( FileUtils::ccppFile::createTempFile(TEST_BLOB_FILE_PREFIX, ".dat") ); //cleanupTempFiles(testBlobFile, TEST_BLOB_FILE_PREFIX); std::ostream & bOut=testBlobFile->getStream(); ASSERT(!bOut.fail()); int dataRange=BYTE_MAX_VALUE - BYTE_MIN_VALUE + 1; srand((unsigned) time(NULL)); for (int i=0; i < size; ++i) { bOut << static_cast (((rand() % dataRange) + BYTE_MIN_VALUE) & 0xff); } bOut.flush(); testBlobFile->close(); } } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/simple/BlobTest.h000644 015771 000012 00000005373 12645244437 025157 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "../../common/file.h" #include "../BaseTestFixture.h" /** * Tests BLOB functionality in the driver. * * @author Mark Matthews * @version $Id: BlobTest.java 6707 2008-01-04 22:06:31Z mmatthews $ */ namespace testsuite { namespace simple { class BlobTest : public BaseTestFixture { private: typedef BaseTestFixture super; boost::scoped_ptr testBlobFile; bool realFrameworkTiming; /** * Tests inserting blob data as a stream * * @throws std::exception * * if an error occurs */ /* throws std::exception * */ void testBlobInsert( Connection & c, bool asString= false ); /* throws std::exception * */ bool checkBlob( const String & retrBytes ); /* throws std::exception * */ void createTestTable(); /** * Mark this as deprecated to avoid warnings from compiler... * * @deprecated * * @throws std::exception * * if an error occurs retrieving the value */ /* throws std::exception * */ void doRetrieval(); static const String TEST_BLOB_FILE_PREFIX; void createBlobFile(int size) ; protected: public: TEST_FIXTURE( BlobTest ) { TEST_CASE( testBlobStreamInsert ); TEST_CASE( testBlobStringInsert ); } /** * Setup the test case * * @throws std::exception * * if an error occurs */ void setUp() ; /** * Destroy resources created by test case * * @throws std::exception * * if an error occurs */ void tearDown() ; /* throws std::exception * */ void testBlobStreamInsert(); void testBlobStringInsert(); }; REGISTER_FIXTURE( BlobTest ); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/simple/TransactionTest.cpp000644 015771 000012 00000005551 12645244437 027117 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "TransactionTest.h" #include namespace testsuite { namespace simple { const double TransactionTest::DOUBLE_CONST= 25.4312; /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ /* throws Exception */ void TransactionTest::setUp() { super::setUp(); createTestTable(); } /** * DOCUMENT ME! * * @throws SQLException * DOCUMENT ME! */ /* throws SQLException */ void TransactionTest::testTransaction() { bool prevAutoCommit= conn->getAutoCommit(); conn->setAutoCommit( false ); stmt->executeUpdate("INSERT INTO trans_test (id, decdata) VALUES (1, 1.0)"); conn->rollback(); rs.reset( stmt->executeQuery("SELECT * from trans_test") ); bool hasResults = rs->next(); ASSERT_MESSAGE((hasResults != true) , "Results returned, rollback to empty table failed" ); std::ostringstream str; str << "INSERT INTO trans_test (id, decdata) VALUES (2, " << DOUBLE_CONST << ")"; stmt->executeUpdate( str.str() ); conn->commit(); rs.reset( stmt->executeQuery("SELECT * from trans_test where id=2") ); hasResults = rs->next(); ASSERT_MESSAGE( hasResults, "No rows in table after INSERT" ); double doubleVal = rs->getDouble(2); str.str(""); str << "Double value returned != " << DOUBLE_CONST; ASSERT_EQUALS( DOUBLE_CONST, doubleVal ); //no need to setAutoCommit to old value - connection reset after each test. conn->setAutoCommit( prevAutoCommit ); } /* throws SQLException */ void TransactionTest::createTestTable() { try { stmt->executeUpdate("DROP TABLE trans_test"); } catch ( sql::SQLException & /*sqlEx*/ ) { } stmt->executeUpdate("CREATE TABLE trans_test (id INT NOT NULL PRIMARY KEY, decdata DOUBLE) ENGINE=InnoDB"); } } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/simple/TransactionTest.h000644 015771 000012 00000003601 12645244437 026556 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "cppconn/exception.h" #include "../BaseTestFixture.h" /** * * @author Mark Matthews * @version $Id: TransactionTest.java,v 1.1.2.1 2005/05/13 18:58:37 mmatthews * Exp $ */ namespace testsuite { namespace simple { class TransactionTest : public BaseTestFixture { private: typedef BaseTestFixture super; // --------------------------------------------- static const double DOUBLE_CONST; /* throws sql::DbcException */ void createTestTable() ; protected: public: TEST_FIXTURE( TransactionTest ) { TEST_CASE( testTransaction ); } /* throws std::exception * */ void setUp(); /** * DOCUMENT ME! * * @throws sql::SQLException * DOCUMENT ME! */ /* throws sql::SQLException */ void testTransaction(); }; REGISTER_FIXTURE(TransactionTest); } } mysql-connector-c++-1.1.7/test/CJUnitTestsPort/sql.properties000644 015771 000012 00000101753 12645244437 024713 0ustar00pb2userwheel000000 000000 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # %W% %E% #------------------------------------------------- #All sql DML statements used in the test cases against cloudscape #------------------------------------------------- ftable=ctstable2 binarySize=24 varbinarySize=48 longvarbinarySize=50 cofSize=9 cofTypeSize=9 Dbschema_Tab1_Insert=insert into ctstable2 values(?, ?, ?, ?) Dbschema_Tab2_Insert=insert into ctstable1 values(?, ?) Dbschema_Tab1_Delete=delete from ctstable2 Dbschema_Tab2_Delete=delete from ctstable1 #****************************************************************** # SQL Statements for creating procedures in side the test. #****************************************************************** UpdCoffee_Proc=create method alias UpdCoffee_Proc for com.sun.cts.tests.jdbc.ee.common.CS_Procs.UpdCoffee_Proc #****************************************************************** # SQL Statements for deleting tables for appropriate JDBC Datatypes #****************************************************************** Numeric_Tab_Delete=delete from Numeric_Tab Decimal_Tab_Delete=delete from Decimal_Tab Double_Tab_Delete=delete from Double_Tab Float_Tab_Delete=delete from Float_Tab Real_Tab_Delete=delete from Real_Tab Bit_Tab_Delete=delete from Bit_Tab Smallint_Tab_Delete=delete from Smallint_Tab Tinyint_Tab_Delete=delete from Tinyint_Tab Integer_Tab_Delete=delete from Integer_Tab Bigint_Tab_Delete=delete from Bigint_Tab Char_Tab_Delete=delete from Char_Tab Varchar_Tab_Delete=delete from Varchar_Tab Longvarchar_Tab_Delete=delete from Longvarchar_Tab Longvarcharnull_Tab_Delete=delete from Longvarcharnull_Tab Date_Tab_Delete=delete from Date_Tab Time_Tab_Delete=delete from Time_Tab Timestamp_Tab_Delete=delete from Timestamp_Tab Binary_Tab_Delete=delete from Binary_Tab Varbinary_Tab_Delete=delete from Varbinary_Tab Longvarbinary_Tab_Delete=delete from Longvarbinary_Tab #**************************************************** # SQL Statements for inserting values into the tables #**************************************************** #Numeric_Tab_Insert=insert into Numeric_Tab values(999999999999999,0.000000000000001, null) Numeric_Tab_Insert=insert into Numeric_Tab values(9999999999,0.0000000001, null) #Decimal_Tab_Insert= insert into Decimal_Tab values(999999999999999,0.000000000000001, null) Decimal_Tab_Insert= insert into Decimal_Tab values(9999999999,0.0000000001, null) #Double_Tab_Insert=insert into Double_Tab values(1.7976931348623157E308,4.9E-324,null) Double_Tab_Insert=insert into Double_Tab values(1.0E125,1.0E-130,null) Float_Tab_Insert=insert into Float_Tab values(3.4028235E37,1.4E-45,null) Real_Tab_Insert= insert into Real_Tab values(3.4E38,1.4E-45, null) Bit_Tab_Insert=insert into Bit_Tab values(1,0,null) Smallint_Tab_Insert= insert into Smallint_Tab values(32767,-32768,null) Tinyint_Tab_Insert=insert into Tinyint_Tab values(127,0,null) Integer_Tab_Insert=insert into Integer_Tab values(2147483647,-2147483648,null) Bigint_Tab_Insert= insert into Bigint_Tab values(9223372036854775807,-9223372036854775808,null) Char_Tab_Insert= insert into Char_Tab values('Test Coffee', null) Varchar_Tab_Insert= insert into Varchar_Tab values('Test Coffee',null) Longvarchar_Tab_Insert= insert into Longvarchar_Tab values('Test Coffee') Longvarcharnull_Tab_Insert= insert into Longvarcharnull_Tab values(null) Date_Tab_Insert=insert into Date_Tab values({d '1999-5-5'}, null) Time_Tab_Insert= insert into Time_Tab values({t '12:59:59'}, null) Timestamp_Tab_Insert= insert into Timestamp_Tab values({ts '1999-12-31 12:59:59'}, null) Binary_Tab_Insert= insert into Binary_Tab values(null) Varbinary_Tab_Insert= insert into Varbinary_Tab values(null) Longvarbinary_Tab_Insert= insert into Longvarbinary_Tab values(null) Boolean_Tab_Insert = insert into Boolean_Tab values(1,0,null) #***************************************************** # SQL Statements for retrieving values from the tables #***************************************************** SelCoffeeAll=SELECT COF_NAME, PRICE FROM ctstable2 SelCoffeeNull=select * from ctstable2 where TYPE_ID=0 Numeric_Query_Max=Select MAX_VAL from Numeric_Tab Numeric_Query_Min=Select MIN_VAL from Numeric_Tab Numeric_Query_Null=Select NULL_VAL from Numeric_Tab Decimal_Query_Max=Select MAX_VAL from Decimal_Tab Decimal_Query_Min=Select MIN_VAL from Decimal_Tab Decimal_Query_Null=Select NULL_VAL from Decimal_Tab Double_Query_Max=Select MAX_VAL from Double_Tab Double_Query_Min=Select MIN_VAL from Double_Tab Double_Query_Null=Select NULL_VAL from Double_Tab Float_Query_Max=Select MAX_VAL from Float_Tab Float_Query_Min=Select MIN_VAL from Float_Tab Float_Query_Null=Select NULL_VAL from Float_Tab Real_Query_Max=Select MAX_VAL from Real_Tab Real_Query_Min=Select MIN_VAL from Real_Tab Real_Query_Null=Select NULL_VAL from Real_Tab Bit_Query_Max=Select MAX_VAL from Bit_Tab Bit_Query_Min=Select MIN_VAL from Bit_Tab Bit_Query_Null=Select NULL_VAL from Bit_Tab Smallint_Query_Max=Select MAX_VAL from Smallint_Tab Smallint_Query_Min=Select MIN_VAL from Smallint_Tab Smallint_Query_Null=Select NULL_VAL from Smallint_Tab Tinyint_Query_Max=Select MAX_VAL from Tinyint_Tab Tinyint_Query_Min=Select MIN_VAL from Tinyint_Tab Tinyint_Query_Null=Select NULL_VAL from Tinyint_Tab Integer_Query_Max=Select MAX_VAL from Integer_Tab Integer_Query_Min=Select MIN_VAL from Integer_Tab Integer_Query_Null=Select NULL_VAL from Integer_Tab Bigint_Query_Max=Select MAX_VAL from Bigint_Tab Bigint_Query_Min=Select MIN_VAL from Bigint_Tab Bigint_Query_Null=Select NULL_VAL from Bigint_Tab Char_Query_Name=Select COFFEE_NAME from Char_Tab Char_Query_Null=Select NULL_VAL from Char_Tab Varchar_Query_Name=Select COFFEE_NAME from Varchar_Tab Varchar_Query_Null=Select NULL_VAL from Varchar_Tab Longvarchar_Query_Name=Select COFFEE_NAME from Longvarchar_Tab Longvarchar_Query_Null=Select NULL_VAL from Longvarcharnull_Tab Date_Query_Mfg=Select MFG_DATE from Date_Tab Date_Query_Null=Select NULL_VAL from Date_Tab Time_Query_Brk=Select BRK_TIME from Time_Tab Time_Query_Null=Select NULL_VAL from Time_Tab Timestamp_Query_In=Select IN_TIME from Timestamp_Tab Timestamp_Query_Null=Select NULL_VAL from Timestamp_Tab Binary_Query_Val=Select BINARY_VAL from Binary_Tab Varbinary_Query_Val=Select VARBINARY_VAL from Varbinary_Tab Longvarbinary_Query_Val=Select LONGVARBINARY_VAL from Longvarbinary_Tab #*************************************** # SQL Statements for updating the tables #*************************************** Numeric_Tab_Max_Update=update Numeric_Tab set MAX_VAL=? Numeric_Tab_Min_Update=update Numeric_Tab set MIN_VAL=? Numeric_Tab_Null_Update=update Numeric_Tab set NULL_VAL=? Decimal_Tab_Max_Update=update Decimal_Tab set MAX_VAL=? Decimal_Tab_Min_Update=update Decimal_Tab set MIN_VAL=? Decimal_Tab_Null_Update=update Decimal_Tab set NULL_VAL=? Double_Tab_Max_Update=update Double_Tab set MAX_VAL=? Double_Tab_Min_Update=update Double_Tab set MIN_VAL=? Double_Tab_Null_Update=update Double_Tab set NULL_VAL=? Float_Tab_Max_Update=update Float_Tab set MAX_VAL=? Float_Tab_Min_Update=update Float_Tab set MIN_VAL=? Float_Tab_Null_Update=update Float_Tab set NULL_VAL=? Real_Tab_Max_Update=update Real_Tab set MAX_VAL=? Real_Tab_Min_Update=update Real_Tab set MIN_VAL=? Real_Tab_Null_Update=update Real_Tab set NULL_VAL=? Bit_Tab_Max_Update=update Bit_Tab set MAX_VAL=? Bit_Tab_Min_Update=update Bit_Tab set MIN_VAL=? Bit_Tab_Null_Update=update Bit_Tab set NULL_VAL=? Smallint_Tab_Max_Update=update Smallint_Tab set MAX_VAL=? Smallint_Tab_Min_Update=update Smallint_Tab set MIN_VAL=? Smallint_Tab_Null_Update=update Smallint_Tab set NULL_VAL=? Tinyint_Tab_Max_Update=update Tinyint_Tab set MAX_VAL=? Tinyint_Tab_Min_Update=update Tinyint_Tab set MIN_VAL=? Tinyint_Tab_Null_Update=update Tinyint_Tab set NULL_VAL=? Integer_Tab_Max_Update=update Integer_Tab set MAX_VAL=? Integer_Tab_Min_Update=update Integer_Tab set MIN_VAL=? Integer_Tab_Null_Update=update Integer_Tab set NULL_VAL=? Bigint_Tab_Max_Update=update Bigint_Tab set MAX_VAL=? Bigint_Tab_Min_Update=update Bigint_Tab set MIN_VAL=? Bigint_Tab_Null_Update=update Bigint_Tab set NULL_VAL=? Char_Tab_Name_Update=update Char_Tab set COFFEE_NAME=? Char_Tab_Null_Update=update Char_Tab set NULL_VAL=? Varchar_Tab_Name_Update=update Varchar_Tab set COFFEE_NAME=? Varchar_Tab_Null_Update=update Varchar_Tab set NULL_VAL=? Longvarchar_Tab_Name_Update=update Longvarchar_Tab set COFFEE_NAME=? Longvarchar_Tab_Null_Update=update Longvarcharnull_Tab set NULL_VAL=? Date_Tab_Mfgdate_Update=update Date_Tab set MFG_DATE=? Date_Tab_Null_Update=update Date_Tab set NULL_VAL=? Time_Tab_Brktime_Update=update Time_Tab set BRK_TIME=? Time_Tab_Null_Update=update Time_Tab set NULL_VAL=? Timestamp_Tab_Intime_Update=update Timestamp_Tab set IN_TIME=? Timestamp_Tab_Null_Update=update Timestamp_Tab set NULL_VAL=? Binary_Tab_Val_Update=update Binary_Tab set BINARY_VAL=? Varbinary_Tab_Val_Update=update Varbinary_Tab set VARBINARY_VAL=? Longvarbinary_Tab_Val_Update=update Longvarbinary_Tab set LONGVARBINARY_VAL=? CoffeeTab_Query=select COF_NAME,PRICE from ctstable2 where TYPE_ID=? CoffeeTab_Delete=delete from ctstable2 where KEY_ID=? CoffeeTab_Select=select PRICE from ctstable2 where KEY_ID=? CoffeeTab_Update=update ctstable2 set PRICE=PRICE*20 where TYPE_ID=? Ins_Coffee_Tab=insert into ctstable2 values (9,'COFFEE-9',9.0,5) Del_Coffee_Tab=delete from ctstable2 where KEY_ID=9 Upd_Coffee_Tab=update ctstable2 set PRICE=PRICE*20 where TYPE_ID=1 Sel_Coffee_Tab=select PRICE from ctstable2 where KEY_ID>4 #********************************************************************************** # is used in ResultSet. To update with BIT value. #********************************************************************************** Update_decimal_tab=update Decimal_Tab set MAX_VAL=1.0, MIN_VAL=0.0, NULL_VAL=null Update_numeric_tab=update Numeric_Tab set MAX_VAL=1.0, MIN_VAL=0.0, NULL_VAL=null Update_char_tab1=update Char_Tab set COFFEE_NAME=1, NULL_VAL=null Update_char_tab2=update Char_Tab set COFFEE_NAME=0, NULL_VAL=null Update_varchar_tab1=update Varchar_Tab set COFFEE_NAME=1, NULL_VAL=null Update_varchar_tab2=update Varchar_Tab set COFFEE_NAME=0, NULL_VAL=null #********************************************************************************** # is used in BatchUpdate exception #********************************************************************************** Coffee_InsTab=insert into ctstable2 values (9,'COFFEE-9',9.0,5) Coffee_DelTab=delete from ctstable2 where KEY_ID=2 Coffee_UpdTab=update ctstable2 set PRICE=PRICE*20 where TYPE_ID=1 Coffee_SelTab=select PRICE from ctstable2 where KEY_ID>4 Coffee_Inscount_Query=select count(*) from ctstable2 where KEY_ID=9 Coffee_Delcount_Query=select count(*) from ctstable2 where KEY_ID=2 Coffee_Updcount_Query=select count(*) from ctstable2 where TYPE_ID=1 CoffeeTab_Continue1=update ctstable2 set KEY_ID=?, COF_NAME=? where COF_NAME=? CoffeeTab_ContinueSelect1=Select count(*) from ctstable2 where COF_NAME in ('Continue-1') CoffeeTab_Continue2=update ctstable2 set KEY_ID=1,COF_NAME = 'Continue-1' where COF_NAME='COFFEE-1' CoffeeTab_Continue3=update ctstable2 set KEY_ID=1 ,COF_NAME = 'Invalid' where COF_NAME='COFFEE-3' CoffeeTab_Continue4=update ctstable2 set KEY_ID=2,COF_NAME = 'Continue-3' where COF_NAME='COFFEE-2' Coffee_Proc1=create procedure Coffee_Proc1(keyid in Numeric) as begin update ctstable2 set KEY_ID=keyid,COF_NAME = 'Continue-1' where KEY_ID=1;end; Coffee_Proc1_Delete=Drop procedure Coffee_Proc1 #********************************************************************************** # is used in DataTruncation exception #********************************************************************************** DTrunc_Ins_Coffee=insert into ctstable2 values (10,'kumarjadjsjdhsjhdjsjdajhdjasdsdsdsd',21.00,1) #********************************************************************************** # is used in SQLException #********************************************************************************** Error_Query=select * from #********************************************************************************** # Constructor arguments for exceptions #********************************************************************************** Reason_BatUpdExec=Message SQLState_BatUpdExec=S100 VendorCode_BatUpdExec=10 IntialValue_BatUpdExec={1,1,1} Index_DataTrunc=1 Param_DataTrunc=true Read_DataTrunc=true DataSize_DataTrunc=100 TranSize_DataTrunc=50 #********************************************************************************** # is used to print a message to the current logging writer #********************************************************************************** JDBCLogstream_Message=Hello World #********************************************************************************** #The following pair of values are related and so must be changed simultaneously #The first one is a reference value and the second one is a equivalent in millisecond after epoch #********************************************************************************** DateTime_Str_Val1=1970-01-02 00:00:00.001 DateTime_Long_Val1=86400001 #********************************************************************************** #The following pair of values are related and so must be changed simultaneously #The first one is a reference value and the second one is a equivalent in millisecond after epoch #********************************************************************************** DateTime_Str_Val2=1969-12-30 23:59:59.999 DateTime_Long_Val2=-86400001 #********************************************************************************** #value in millisecond for testing after() and before() in Timestamp #********************************************************************************** Ref_Milli_Val = 86400000 #********************************************************************************** #Value in nanoseconds for testing time values #********************************************************************************** Ref_Nano_Val = 999999999 #********************************************************************************** #Value in nanoseconds and must be equivalent equivalent to multiples of milliseconds #********************************************************************************** Ref_Nano_Val2 = 1000000 Trial_String=TrialSetting Escape_Seq_Query=select count(*) from ctstable2 where cof_name like '\%-%' { escape '\\' } Escape_Seq_ChkQuery=select count(*) from ctstable2 Max_Set_Val=10 #********************************************************************************** #The SQL Statements which are used to test the Scalar functions using escape syntax #********************************************************************************** Concat_Fn_Query=SELECT {FN CONCAT(STRING1,STRING2)} FROM ctstable3 Ascii_Fn_Query=SELECT {FN ASCII(STRING1)} FROM ctstable3 Insert_Fn_Query=SELECT {FN INSERT(STRING1,2,4,STRING2)} FROM ctstable3 Lcase_Fn_Query=SELECT {FN LCASE(STRING1)} FROM ctstable3 Left_Fn_Query=SELECT {FN LEFT(STRING1,2)} FROM ctstable3 Length_Fn_Query=SELECT {FN LENGTH(STRING1)} FROM ctstable3 Locate_Fn_Query=SELECT {FN LOCATE(STRING1,STRING2)} FROM ctstable3 Ltrim_Fn_Query=SELECT {FN LTRIM(STRING2)} FROM ctstable3 Repeat_Fn_Query=SELECT {FN REPEAT(STRING1,3)} FROM ctstable3 Right_Fn_Query=SELECT {FN RIGHT(STRING1,3)} FROM ctstable3 Rtrim_Fn_Query=SELECT {FN RTRIM(STRING2)} FROM ctstable3 Soundex_Fn_Query=SELECT {FN SOUNDEX(STRING1)} FROM ctstable3 Space_Fn_Query=SELECT {FN SPACE(5)} FROM ctstable3 Substring_Fn_Query=SELECT {FN SUBSTRING(STRING2,2,3)} FROM ctstable3 Ucase_Fn_Query=SELECT {FN UCASE(STRING1)} FROM ctstable3 Char_Fn_Query=SELECT {FN CHAR(NUMCOL)} FROM ctstable3 Replace_Fn_Query=SELECT {FN REPLACE(STRING2,STRING1,STRING3)} FROM ctstable3 User_Fn_Query=SELECT {FN USER()} FROM ctstable3 Ifnull_Fn_Query=SELECT {FN IFNULL(STRING1,100)} FROM ctstable3 Sin_Fn_Query=SELECT {FN SIN(0)} FROM ctstable3 Abs_Fn_Query=SELECT {FN ABS(NUMCOL)} FROM ctstable3 Power_Fn_Query=SELECT {FN POWER(NUMCOL,2)} FROM ctstable3 Round_Fn_Query=SELECT {FN ROUND(FLOATCOL,2)} FROM ctstable3 Sign_Fn_Query=SELECT {FN SIGN(NUMCOL)} FROM ctstable3 Sqrt_Fn_Query=SELECT {FN SQRT(FLOATCOL)} FROM ctstable3 Truncate_Fn_Query=SELECT {FN TRUNCATE(FLOATCOL,1)} FROM ctstable3 Mod_Fn_Query=SELECT {FN MOD(NUMCOL,7)} FROM ctstable3 Floor_Fn_Query=SELECT {FN FLOOR(FLOATCOL)} FROM ctstable3 Ceiling_Fn_Query=SELECT {FN CEILING(NUMCOL)} FROM ctstable3 Log10_Fn_Query=SELECT {FN LOG10(NUMCOL)} FROM ctstable3 Log_Fn_Query=SELECT {FN LOG(NUMCOL)} FROM ctstable3 Exp_Fn_Query=SELECT {FN EXP(FLOATCOL)} FROM ctstable3 Cos_Fn_Query=SELECT {FN COS(FLOATCOL)} FROM ctstable3 Tan_Fn_Query=SELECT {FN TAN(FLOATCOL)} FROM ctstable3 Cot_Fn_Query=SELECT {FN COT(FLOATCOL)} FROM ctstable3 Curdate_Fn_Query=SELECT {FN CURDATE()} FROM ctstable3 Dayname_Fn_Query=SELECT {FN DAYNAME(DATECOL)} FROM ctstable3 Dayofmonth_Fn_Query=SELECT {FN DAYOFMONTH(DATECOL)} FROM ctstable3 Dayofweek_Fn_Query=SELECT {FN DAYOFWEEK(DATECOL)} FROM ctstable3 Dayofyear_Fn_Query=SELECT {FN DAYOFYEAR(DATECOL)} FROM ctstable3 Week_Fn_Query=SELECT {FN WEEK(DATECOL)} FROM ctstable3 Month_Fn_Query=SELECT {FN MONTH(DATECOL)} FROM ctstable3 Year_Fn_Query=SELECT {FN YEAR(DATECOL)} FROM ctstable3 Monthname_Fn_Query=SELECT {FN MONTHNAME(DATECOL)} FROM ctstable3 Quarter_Fn_Query=SELECT {FN QUARTER(DATECOL)} FROM ctstable3 Now_Fn_Query=SELECT {FN NOW()} FROM ctstable3 Hour_Fn_Query=SELECT {FN HOUR(TIMECOL)} FROM ctstable3 Minute_Fn_Query=SELECT {FN MINUTE(TIMECOL)} FROM ctstable3 Second_Fn_Query=SELECT {FN SECOND(TIMECOL)} FROM ctstable3 Database_Fn_Query=SELECT {FN DATABASE()} FROM ctstable3 Acos_Fn_Query=SELECT {FN ACOS(FLOATCOL)} FROM ctstable3 Asin_Fn_Query=SELECT {FN ASIN(FLOATCOL)} FROM ctstable3 Atan_Fn_Query=SELECT {FN ATAN(FLOATCOL)} FROM ctstable3 Atan2_Fn_Query=SELECT {FN ATAN2(FLOATCOL,FLOATCOL)} FROM ctstable3 Degrees_Fn_Query=SELECT {FN DEGREES(NUMCOL)} FROM ctstable3 Radians_Fn_Query=SELECT {FN RADIANS(NUMCOL)} FROM ctstable3 Pi_Fn_Query=SELECT {FN PI()} FROM ctstable3 Rand_Fn_Query=SELECT {FN RAND(1)} FROM ctstable3 Difference_Fn_Query=SELECT {FN DIFFERENCE(STRING1,STRING2)} FROM ctstable3 Locate_Fn_Query=SELECT {FN LOCATE(STRING1,STRING2,2)} FROM ctstable3 Timestampaddfrac_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_FRAC_SECOND,2,TSCOL1)} FROM ctstable3 Timestampaddsecond_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_SECOND,2,TSCOL1)} FROM ctstable3 Timestampaddminute_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_MINUTE,2,TSCOL1)} FROM ctstable3 Timestampaddhour_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_HOUR,2,TSCOL1)} FROM ctstable3 Timestampaddday_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_DAY,2,TSCOL1)} FROM ctstable3 Timestampaddweek_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_WEEK,2,TSCOL1)} FROM ctstable3 Timestampaddmonth_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_MONTH,2,TSCOL1)} FROM ctstable3 Timestampaddquarter_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_QUARTER,2,TSCOL1)} FROM ctstable3 Timestampaddyear_Fn_Query=SELECT {FN TIMESTAMPADD(SQL_TSI_YEAR,2,TSCOL1)} FROM ctstable3 Timestampdifffrac_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_FRAC_SECOND,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffsecond_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_SECOND,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffminute_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_MINUTE,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffhour_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_HOUR,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffday_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_DAY,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffweek_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_WEEK,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffmonth_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_MONTH,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffquarter_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_QUARTER,TSCOL1,TSCOL2)} FROM ctstable3 Timestampdiffyear_Fn_Query=SELECT {FN TIMESTAMPDIFF(SQL_TSI_YEAR,TSCOL1,TSCOL2)} FROM ctstable3 #***************************************************************************** #The SQL Statements which are used to test the Outer Joins using escape syntax #***************************************************************************** Left_Oj_Query=SELECT * FROM {OJ ctstable3 LEFT OUTER JOIN ctstable4 ON ctstable3.NUMCOL=ctstable4.NUMCOL} Right_Oj_Query=SELECT * FROM {OJ ctstable3 RIGHT OUTER JOIN ctstable4 ON ctstable3.NUMCOL=ctstable4.NUMCOL} Full_Oj_Query=SELECT * FROM {OJ ctstable3 FULL OUTER JOIN ctstable4 ON ctstable3.NUMCOL=ctstable4.NUMCOL} #***************************************************************************** #The SQL Statements for creating, inserting and dropping the tables which are #used in testing the scalar functions and outer joins using escape syntax #***************************************************************************** Fnschema_Tab1_Insert=INSERT INTO ctstable3 VALUES ('Java',' HotJava ','JAVA',100,0.5,{d '1993-07-13'},{t '10:30:55'},{ts '1994-06-12 11:20:10'},{ts '1996-05-10 10:07:05'}) Fnschema_Tab2_Insert=INSERT INTO ctstable4 VALUES ('STRING3',100) Fnschema_Tab1_Delete=delete from ctstable3 Fnschema_Tab2_Delete=delete from ctstable4 #***************************************************************************** #The SQL Statements which are used in TxBean (Session bean) #***************************************************************************** TxBean_insert1=insert into TxBean_Tab1 values(?, ?, ?) TxBean_insert2=insert into TxBean_Tab2 values(?, ?, ?) TxBean_delete1=delete from TxBean_Tab1 where KEY_ID = ? TxBean_delete2=delete from TxBean_Tab2 where KEY_ID = ? TxBean_update1=update TxBean_Tab1 set TABONE_NAME = ? where KEY_ID = ? TxBean_update2=update TxBean_Tab2 set TABTWO_NAME = ? where KEY_ID = ? TxBean_update3=update TxBean_Tab1 set PRICE = ? where KEY_ID = ? TxBean_update4=update TxBean_Tab2 set PRICE = ? where KEY_ID = ? TxBean_query1=select * from TxBean_Tab1 TxBean_query2=select * from TxBean_Tab2 TxBean_query3=select KEY_ID, TABONE_NAME, PRICE from TxBean_Tab1 where KEY_ID = ? TxBean_query4=select KEY_ID, TABTWO_NAME, PRICE from TxBean_Tab2 where KEY_ID = ? TxBean_Tab1_Delete=delete from TxBean_Tab1 TxBean_Tab2_Delete=delete from TxBean_Tab2 #***************************************************************************** #The SQL Statements which are used in TxEBean (Entity bean) #***************************************************************************** TxEBean_updateString1=insert into TxEBean_Tab values(?, ?, ?) TxEBean_updateString2=delete from TxEBean_Tab where KEY_ID = ? TxEBean_updateString3=update TxEBean_Tab set BRAND_NAME = ?, PRICE = ? where KEY_ID = ? TxEBean_selectString1=select KEY_ID from TxEBean_Tab where KEY_ID = ? TxEBean_selectString2=select KEY_ID from TxEBean_Tab where BRAND_NAME = ? TxEBean_selectString3=select KEY_ID from TxEBean_Tab where PRICE = ? TxEBean_selectString4=select KEY_ID, BRAND_NAME, PRICE from TxEBean_Tab where KEY_ID = ? TxEBean_selectString5=select BRAND_NAME from TxEBean_Tab where KEY_ID = ? TxEBean_selectString6=select PRICE from TxEBean_Tab where KEY_ID = ? TxEBean_queryStr1=select KEY_ID from TxEBean_Tab where KEY_ID = ? TxEBean_Delete=delete from TxEBean_Tab #***************************************************************************** #The SQL Statements which are used in the integration/session and #integration/entity tests #***************************************************************************** Integration_Tab_Delete=delete from Integration_Tab Integration_Insert=insert into Integration_Tab values(?, ?) Integration_Insert1=insert into Integration_Tab values(1000, 50000.0) Integration_Insert2=insert into Integration_Tab values(1075, 10490.75) Integration_Insert3=insert into Integration_Tab values(40, 200.50) Integration_Insert4=insert into Integration_Tab values(30564, 25000.0) Integration_Insert5=insert into Integration_Tab values(387, 1000000.0) Integration_Select_Account=select * from Integration_Tab WHERE ACCOUNT = ? Integration_Select_All=select * from Integration_Tab Integration_Update_Account=update Integration_Tab set BALANCE = ? where ACCOUNT = ? Integration_Delete_Account=delete from Integration_Tab where ACCOUNT = ? #***************************************************************************** #The SQL Statements which are used in the integration/sec tests #***************************************************************************** Integration_Sec_Tab_Delete=delete from Integration_Sec_Tab Integration_Sec_Tab_Insert=insert into Integration_Sec_Tab values(?, ?, ?) Integration_Sec_Tab_Delete1=delete from Integration_Sec_Tab WHERE LOG_NO=? Integration_Sec_Tab_Delete2=delete FROM Integration_Sec_Tab where LOG_NO=? and not ( LINE_NO = ? ) Integration_Sec_Tab_Update=update Integration_Sec_Tab set MESSAGE= ? where LOG_NO = ? and LINE_NO = ? Integration_Sec_Tab_Select1=select MESSAGE, LINE_NO from Integration_Sec_Tab where LOG_NO = ? and not( LINE_NO= ? ) order by LINE_NO Integration_Sec_Tab_Select2=select MESSAGE FROM Integration_Sec_Tab where LOG_NO = ? and LINE_NO = ? Integration_Sec_Tab_Select3=select MAX(LOG_NO) FROM Integration_Sec_Tab Integration_Sec_Tab_Select4=select LOG_NO from Integration_Sec_Tab where MESSAGE = ? and LINE_NO = ? Integration_Sec_Tab_Select5=select LINE_NO from Integration_Sec_Tab where LOG_NO = ? and LINE_NO= ? #***************************************************************************** #The SQL Statements which are used in DBSupport used by ejb/ee/bb tests #***************************************************************************** BB_Tab_Delete=delete from BB_Tab BB_Insert1=insert into BB_Tab values(?, ?, ?) BB_Select1=select KEY_ID from BB_Tab where KEY_ID = ? BB_Select2=select KEY_ID from BB_Tab where BRAND_NAME = ? BB_Select3=select KEY_ID from BB_Tab where PRICE = ? BB_Select4=select KEY_ID from BB_Tab where PRICE >= ? and PRICE <= ? BB_Select5=select KEY_ID from BB_Tab where KEY_ID >= ? and KEY_ID <= ? BB_Select6=select PRICE from BB_Tab where KEY_ID = ? BB_Update1=update BB_Tab set PRICE = ? where KEY_ID = ? BB_Delete1=delete from BB_Tab where KEY_ID = ? #***************************************************************************** #The SQL Statements which are used in DBSupport in jta/ee/txpropagationtest #***************************************************************************** JTA_Tab1_Delete=delete from JTA_Tab1 JTA_Tab2_Delete=delete from JTA_Tab2 JTA_Tab1_Insert=insert into JTA_Tab1 values(?, ?, ?) JTA_Tab2_Insert=insert into JTA_Tab2 values(?, ?, ?) JTA_Delete1=delete from JTA_Tab1 where KEY_ID = ? JTA_Delete2=delete from JTA_Tab2 where KEY_ID = ? JTA_Tab1_Update1=update JTA_Tab1 set COF_NAME = ? where KEY_ID = ? JTA_Tab2_Update1=update JTA_Tab2 set CHOC_NAME = ? where KEY_ID = ? JTA_Tab1_Update2=update JTA_Tab1 set PRICE = ? where KEY_ID = ? JTA_Tab2_Update2=update JTA_Tab2 set PRICE = ? where KEY_ID = ? JTA_Tab1_Select=select * from JTA_Tab1 JTA_Tab2_Select=select * from JTA_Tab2 JTA_Tab1_Select1=select KEY_ID, COF_NAME, PRICE FROM JTA_Tab1 where KEY_ID = ? JTA_Tab2_Select1=select KEY_ID, CHOC_NAME, PRICE FROM JTA_Tab2 where KEY_ID = ? #***************************************************************************** # SQL Statements used by deployment tests # # See /tests/assembly/util/dbsupport for more details # #***************************************************************************** # # BMP table with Integer Primary Key # DEPLOY_intPKTable_Insert=insert into Deploy_Tab1 values(?, ?, ?) DEPLOY_intPKTable_Select_PK=select KEY_ID from Deploy_Tab1 where KEY_ID = ? DEPLOY_intPKTable_Select_Price=select PRICE from Deploy_Tab1 where KEY_ID = ? DEPLOY_intPKTable_Update=update Deploy_Tab1 set PRICE = ? where KEY_ID = ? DEPLOY_intPKTable_Delete=delete from Deploy_Tab1 where KEY_ID = ? DEPLOY_intPKTable_Cleanup=delete from Deploy_Tab1 # # BMP table with String Primary Key # DEPLOY_strPKTable_Insert=insert into Deploy_Tab2 values(?, ?, ?) DEPLOY_strPKTable_Select_PK=select KEY_ID from Deploy_Tab2 where KEY_ID = ? DEPLOY_strPKTable_Select_Price=select PRICE from Deploy_Tab2 where KEY_ID = ? DEPLOY_strPKTable_Update=update Deploy_Tab2 set PRICE = ? where KEY_ID = ? DEPLOY_strPKTable_Delete=delete from Deploy_Tab2 where KEY_ID = ? DEPLOY_strPKTable_Cleanup=delete from Deploy_Tab2 # # BMP table with Long Primary Key # DEPLOY_longPKTable_Insert=insert into Deploy_Tab3 values(?, ?, ?) DEPLOY_longPKTable_Select_PK=select KEY_ID from Deploy_Tab3 where KEY_ID = ? DEPLOY_longPKTable_Select_Price=select PRICE from Deploy_Tab3 where KEY_ID = ? DEPLOY_longPKTable_Update=update Deploy_Tab3 set PRICE = ? where KEY_ID = ? DEPLOY_longPKTable_Delete=delete from Deploy_Tab3 where KEY_ID = ? DEPLOY_longPKTable_Cleanup=delete from Deploy_Tab3 # # BMP table with Float Primary Key # DEPLOY_floatPKTable_Insert=insert into Deploy_Tab4 values(?, ?, ?) DEPLOY_floatPKTable_Select_PK=select KEY_ID from Deploy_Tab4 where KEY_ID = ? DEPLOY_floatPKTable_Select_Price=select PRICE from Deploy_Tab4 where KEY_ID = ? DEPLOY_floatPKTable_Update=update Deploy_Tab4 set PRICE = ? where KEY_ID = ? DEPLOY_floatPKTable_Delete=delete from Deploy_Tab4 where KEY_ID = ? DEPLOY_floatPKTable_Cleanup=delete from Deploy_Tab4 # # BMP table with Compound Primary Key # DEPLOY_compoundPKTable_Insert=insert into Deploy_Tab5 values(?, ?, ?, ?, ?) DEPLOY_compoundPKTable_Select_PK=select KEY_ID1, KEY_ID2, KEY_ID3 from Deploy_Tab5 where KEY_ID1 = ? and KEY_ID2 = ? and KEY_ID3 = ? DEPLOY_compoundPKTable_Select_Price=select PRICE from Deploy_Tab5 where KEY_ID1 = ? and KEY_ID2 = ? and KEY_ID3 = ? DEPLOY_compoundPKTable_Update=update Deploy_Tab5 set PRICE = ? where KEY_ID1 = ? and KEY_ID2 = ? and KEY_ID3 = ? DEPLOY_compoundPKTable_Delete=delete from Deploy_Tab5 where KEY_ID1 = ? and KEY_ID2 = ? and KEY_ID3 = ? DEPLOY_compoundPKTable_Cleanup=delete from Deploy_Tab5 #***************************************************************************** #The SQL Statements which are used in DBSupport2 used by secpropagation tests #***************************************************************************** SEC_Insert1=insert into SEC_Tab1 values(?, ?, ?) SEC_Select1=select KEY_ID from SEC_Tab1 where KEY_ID = ? SEC_Select2=select KEY_ID from SEC_Tab1 where BRAND = ? SEC_Select3=select KEY_ID from SEC_Tab1 where PRICE = ? SEC_Select4=select KEY_ID from SEC_Tab1 where PRICE >= ? and PRICE <= ? SEC_Select5=select KEY_ID from SEC_Tab1 where KEY_ID >= ? and KEY_ID <= ? SEC_Select6=select PRICE from SEC_Tab1 where KEY_ID = ? SEC_Update1=update SEC_Tab1 set PRICE = ? where KEY_ID = ? SEC_Delete1=delete from SEC_Tab1 where KEY_ID = ? SEC_Tab1_Delete=delete from SEC_Tab1 #***************************************************************************** # Connector tests in src/tests/connector #***************************************************************************** ConnectorTable_Insert=insert into Connector_Tab values(?, ?, ?) ConnectorTable_Delete=delete from Connector_Tab #***************************************************************************** #The SQL Statements which are used in xa multires tests #***************************************************************************** # delete Xa_Tab1_Delete=delete from Xa_Tab1 Xa_Tab2_Delete=delete from Xa_Tab2 #initial insert Xa_Tab1_insert_init=insert into Xa_Tab1 values (1, 'Table1 Line one ', 1.0 ) Xa_Tab2_insert_init=insert into Xa_Tab2 values (1, 'Table2 Line one ', 2.0 ) #subsequent insert Xa_Tab1_insert1=insert into Xa_Tab1 values (2, 'Table1 Line two ', 11.0 ) Xa_Tab1_insert2=insert into Xa_Tab1 values (3, 'Table1 Line three ',111.0 ) Xa_Tab2_insert1=insert into Xa_Tab2 values (2, 'Table2 Line two ', 22.0 ) Xa_Tab2_insert2=insert into Xa_Tab2 values (3, 'Table2 Line three ', 222.0 ) #get results Xa_Tab1_query=select col1 from Xa_Tab1 order by col1 Xa_Tab2_query=select col1 from Xa_Tab2 order by col1 mysql-connector-c++-1.1.7/test/CMakeLists.txt000644 015771 000012 00000004540 12645244437 021506 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # IF(WIN32) IF(CMAKE_BUILD_TYPE STREQUAL "Debug") LINK_DIRECTORIES(${MYSQL_DIR}/lib/debug) ELSEIF(CMAKE_BUILD_TYPE STREQUAL "") LINK_DIRECTORIES(${MYSQL_DIR}/lib/opt) ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn) ELSEIF(NOT WIN32) SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn) ENDIF(WIN32) IF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(MY_GCOV_LINK_LIBRARIES gcov) ENDIF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) ADD_EXECUTABLE(static_test static_test.cpp) SET_TARGET_PROPERTIES(static_test PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(static_test ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) LINK_DIRECTORIES(${GLIB_DIR}/lib) ADD_EXECUTABLE(driver_test driver_test.cpp) SET_TARGET_PROPERTIES(driver_test PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(driver_test ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring test cases") mysql-connector-c++-1.1.7/test/README000644 015771 000012 00000003006 12645244437 017622 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ Disclaimer: yes, running our tests is annoying, yes, we have put "make test" (or similar) functionality on our TODO. However, for the moment have a look at the following notes: All tests support the option --verbose for verbose output. Verbose really means verbose. If you want to run all tests for code coverage checks, turn verbose output on to maximize coverage. Also, for code coverage, make sure you use: cmake -DMYSQLCPPCONN_TEST_NOT_IMPLEMENTED:BOOL=1 \ -DMYSQLCPPCONN_GCOV_ENABLE:BOOL=1 \ -DMYSQLCPPCONN_BUILD_EXAMPLES:BOOL=1 To run all tests: test/CJUnitTestsPort/CJUnitTestsPort --verbose ; test/driver_test --verbose ; test/static_test --verbose ; examples/connect --verbose ; examples/connection_meta_schemaobj --verbose ; examples/debug --verbose ; examples/dynamic_load --verbose ; examples/exceptions --verbose ; examples/prepared_statement --verbose ; examples/resultset --verbose ; examples/resultset_binary --verbose ; examples/resultset_meta --verbose ; examples/resultset_types --verbose ; examples/statement --verbose ; test/unit/classes/art_resultset --verbose ; test/unit/classes/connection --verbose ; test/unit/classes/databasemetadata --verbose ; test/unit/classes/parametermetadata --verbose ; test/unit/classes/preparedstatement --verbose ; test/unit/classes/resultset --verbose ; test/unit/classes/resultsetmetadata --verbose ; test/unit/classes/savepoint --verbose ; test/unit/classes/statement mysql-connector-c++-1.1.7/test/common/ccppTypes.h000644 015771 000012 00000011241 12645244437 022355 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Some common definitions and inclusions for C/C++ tests. */ #ifndef __C_CPP_TYPES_H_ #define __C_CPP_TYPES_H_ #if defined(_WIN32) || defined(_WIN64) /* MySQL 5.1 might have defined it before in include/config-win.h */ # ifdef strncasecmp # undef strncasecmp # endif # define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n) #else # include #endif #include "cppconn/config.h" #if !defined(_WIN32) || (_MSC_VER >=1800) # include # ifndef HAVE_FUNCTION_STRTOLL # ifdef HAVE_FUNCTION_STRTOL # define strtoll(__a, __b, __c) strtol((__a), (__b), (__c)) # else # ifdef HAVE_FUNCTION_STRTOIMAX # define strtoll(__a, __b, __c) strtoimax((__a), NULL, 10) # else # error "Compilation will fail because code does not know an equivalent of strtol/strtoll" # endif # endif # define HAVE_FUNCTION_STRTOLL 1 # endif # ifndef HAVE_FUNCTION_STRTOULL # ifdef HAVE_FUNCTION_STRTOUL # define strtoull(__a, __b, __c) strtoul((__a), (__b), (__c)) # else # ifdef HAVE_FUNCTION_STRTOUMAX # define strtoull(__a, __b, __c) strtoumax((__a), NULL, 10) # else # error Compilation will fail because code does not know an equivalent of strtoul/strtoull # endif # endif # define HAVE_FUNCTION_STRTOULL 1 # endif #else # define strtoll(x, e, b) _strtoi64((x), (e), (b)) # define strtoull(x, e, b) _strtoui64((x), (e), (b)) #endif // _WIN32 #include #include #include #include #include #include #include /*#include */ #ifndef _ABSTRACT #define _ABSTRACT #endif #ifndef _PURE #define _PURE =0 #endif #ifndef L64 #ifdef _WIN32 #define L64(x) x##i64 #else #define L64(x) x##LL #endif #endif #ifndef UL64 #ifdef _WIN32 #define UL64(x) x##ui64 #else #define UL64(x) x##ULL #endif #endif /*---------------------------------------------------------------------------- ci_char_traits : Case-insensitive char traits. ----------------------------------------------------------------------------*/ template struct ci_char_traits : public std::char_traits // just inherit all the other functions // that we don't need to override { static bool eq (charT c1, charT c2) { return std::tolower(c1) == std::tolower(c2); } static bool ne (charT c1, charT c2) { return std::tolower(c1) != std::tolower(c2); } static bool lt (charT c1, charT c2) { return std::tolower(c1) < std::tolower(c2); } static int compare (const charT* s1, const charT* s2, size_t n) { return strncasecmp(s1, s2, n); } static const charT* find (const charT* s, std::allocator::size_type n, charT a) { while ( --n != static_cast::size_type>(-1) && std::tolower(*s) != std::tolower(a)) { ++s; } return (n != static_cast::size_type>(-1) ? s : 0); } }; //Some stubs for unicode use. Following usual win scheme #ifdef UNICODE_32BIT typedef std::basic_string , std::allocator > String; #ifndef _T #define _T(strConst) L ## strConst #endif #else typedef std::basic_string , std::allocator > String; typedef std::basic_string , std::allocator > ciString; #ifndef _T #define _T(strConst) strConst #endif #endif typedef std::vector List; typedef List::iterator Iterator; typedef List::const_iterator ConstIterator; typedef std::map Properties; typedef Properties::iterator PropsIterator; typedef List::const_iterator PropsConstIterator; #endif /* __C_CPP_TYPES_H_ */ mysql-connector-c++-1.1.7/test/common/file.cpp000644 015771 000012 00000014701 12645244437 021661 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "file.h" #include "stringutils.h" #include #include namespace FileUtils { std::map ccppFile::_2deleteAtexit; ccppFile::ccppFile( const String & fileName ) : name ( fileName ) , binary ( true ) { init(); //fileExists ||= } void ccppFile::init() { fileExists= ( stat( name.c_str(), &fileInfo ) == 0 ); } ccppFile::~ccppFile() { close(); removeObjectFromDeleteList( name ); } void ccppFile::removeFileFromDeleteList( const String & fileName ) { FilesMap::iterator it= _2deleteAtexit.find( fileName ); if ( it != _2deleteAtexit.end() ) _2deleteAtexit.erase( it ); } void ccppFile::removeObjectFromDeleteList( const String & fileName ) { FilesMap::iterator it= _2deleteAtexit.find( fileName ); if ( it != _2deleteAtexit.end() ) it->second= NULL; } void ccppFile::reset() { fileExists= false; } std::fstream & ccppFile::getStream() { if ( ! stream.is_open() ) { if ( exists() ) stream.open( name.c_str(), std::ios_base::out | std::ios_base::in | ( binary ? std::ios_base::binary : static_cast(0) ) ); else stream.open( name.c_str(), std::ios_base::out | ( binary ? std::ios_base::binary : static_cast(0) ) ); } else { stream.clear(); stream.seekg(0); } return stream; } int ccppFile::getSize () const { if ( ! fileExists ) return -1; return static_cast( fileInfo.st_size ); } String::size_type ccppFile::readFile( String & str ) { str.reserve(getSize()); char buff[1024]; std::fstream & fStr= getStream(); //String::size_type size = 0; while ( ! fStr.eof() ) { fStr.read( buff, sizeof(buff) ); if ( fStr.bad() ) { throw std::runtime_error("Error while reading from file stream (bad)"); } else if ( fStr.fail() ) { if (! fStr.eof() ) { throw std::runtime_error("Error while reading from file stream (fail)"); } } str.append( buff,fStr.gcount() ); //size+= fStr.gcount(); } return str.length(); } bool ccppFile::exists () const { return fileExists; } bool ccppFile::readable() const { return exists() && ( fileInfo.st_mode & S_IREAD ); } bool ccppFile::writable() const { return exists() && ( fileInfo.st_mode & S_IWRITE ); } bool ccppFile::isDirectory() const { return exists() && ( fileInfo.st_mode & S_IFDIR ); } void ccppFile::deleteFile() { if( std::remove( name.c_str() ) == 0 ) { removeFileFromDeleteList( name ); reset(); } } void ccppFile::deleteAtExit() { deleteAtExit( name, this ); } void ccppFile::deleteAtExit( const String & fileName ) { deleteAtExit( fileName, NULL ); } void ccppFile::deleteAtExit( const String & fileName , ccppFile * fileObject ) { _2deleteAtexit.insert( std::make_pair( fileName, fileObject ) ); //if ( _2deleteAtexit.size() == 1 ) //atexit( filesDeleter ); } void ccppFile::filesDeleter() { // the possible problem i can see at the moment - more than one object created // for one file. for ( FilesMap::iterator it= _2deleteAtexit.begin(); it !=_2deleteAtexit.end(); ++it ) { if ( it->second != NULL ) { it->second->deleteFile(); } else std::remove( it->first.c_str() ); } } ccppFile * ccppFile::createTempFile( const String & prefix, const String & suffix ) { /* String name= prefix; name+= suffix;*/ //probably had to add vacant file name picking. ccppFile * file= new ccppFile( prefix + suffix ); file->deleteAtExit(); return file; } void ccppFile::close() { if ( stream.is_open() ) { stream.close(); } init(); } String::size_type loadFile( String & container ) { return container.length(); } /* bool OpenFile(std::ifstream & fileStream, const String & fileName , const char * _possibleLocations[]) { fileStream.open(fileName.c_str()); int i=0; while (!fileStream.is_open() && _possibleLocations != NULL && _possibleLocations[ i ] != NULL) { fileStream.clear(); fileStream.open((String(_possibleLocations[ i ]) + "/" + fileName).c_str()); ++i; } return fileStream.is_open(); } int LoadProperties(const String & fileName, Properties & props , const char * _possibleLocations[]) { int counter=0; std::ifstream propsFile; if (OpenFile(propsFile, fileName, _possibleLocations)) { String line; while (getline(propsFile, line)) { StringUtils::trim(line); // Not empty line or a comment if (!propsFile.eof() && line.size() > 0 && line.c_str()[0] != '#') { String::size_type pos=line.find("="); if (pos != String::npos && pos > 0) { String key=StringUtils::trim(line.substr(0, pos)); String val=StringUtils::trim(line.substr(pos + 1)); props.insert(Properties::value_type(key, val)); ++counter; } } } propsFile.close(); } else { std::cout << "Unable to open file" << std::endl; return -1; } return counter; }*/ } mysql-connector-c++-1.1.7/test/common/file.h000644 015771 000012 00000005014 12645244437 021323 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _CCPP_FILE_H_ #define _CCPP_FILE_H_ #include #include #include "ccppTypes.h" namespace FileUtils { class ccppFile { private: typedef std::map FilesMap; static FilesMap _2deleteAtexit; String name; struct stat fileInfo; bool fileExists; std::fstream stream; bool binary; ccppFile(){} void init (); void reset (); static void removeFileFromDeleteList ( const String & fileName ); static void removeObjectFromDeleteList ( const String & fileName ); static void deleteAtExit ( const String & fileName , ccppFile * fileObject ); static void filesDeleter(); public: ccppFile( const String & fileName ); ~ccppFile(); std::fstream & getStream(); String::size_type readFile( String & ); int getSize () const; bool exists () const; bool readable() const; bool writable() const; bool isDirectory () const; void deleteFile (); void deleteAtExit(); static void deleteAtExit( const String & fileName ); void close (); static ccppFile * createTempFile( const String & prefix, const String & suffix= "" ); String::size_type loadFile( String & container ); }; } #endif mysql-connector-c++-1.1.7/test/common/singleton.h000644 015771 000012 00000003030 12645244437 022402 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CCPP_SINGLETON_H #define __CCPP_SINGLETON_H #include namespace policies { template class Singleton: public boost::noncopyable { protected: Singleton(){} public: static T & theInstance() { static T instance; return instance; } }; } // namespace policies // macros to use in private/protected part of singletoned class #define CCPP_SINGLETON(classname) classname();\ friend class policies::Singleton #endif mysql-connector-c++-1.1.7/test/common/stringutils.cpp000644 015771 000012 00000012201 12645244437 023322 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "stringutils.h" #include #include namespace StringUtils { template StdStringType & _trim( StdStringType & victim ) { static const String::value_type * space = _T(" "); String::size_type begin = victim.find_first_not_of( space ); String::size_type end = victim.find_last_not_of( space ); if ( begin == String::npos ) begin = 0; if ( end == String::npos ) end = victim.size(); else ++end; return victim.assign( victim, begin, end - begin ); } template unsigned _split( std::vector & list, const StdStringType & str, const StdStringType & delim , bool trimItems, bool includeEmpty ) { unsigned int count= 0; String::size_type prevPos= 0; String::size_type newPos= 0; String::size_type delimSize= delim.size(); String::size_type strSize= str.size(); StdStringType item; while ( prevPos < strSize && (newPos = str.find(delim, prevPos)) != String::npos ) { if ( newPos == prevPos && delimSize == 0 ) ++newPos; if ( newPos > prevPos || includeEmpty ) { item = str.substr(prevPos, newPos - prevPos ); if ( trimItems ) _trim( item ); list.push_back( item ); ++count; } prevPos = newPos + delimSize; } /* if string has delimiter at the end, and includeEmpty flag is set - we are doing that if delimiter is present (delimSize > 0) */ if ( prevPos == strSize && includeEmpty && delimSize > 0 ) { list.push_back( _T("") ); ++count; } /* else - adding part after last token*/ else if (prevPos < strSize ) { item = str.substr(prevPos); if (trimItems) _trim(item); list.push_back( item ); ++count; } return count; } // This function skips empties unsigned split( List & list, const String & str, const String & delim , bool trimItems, bool includeEmpty) { return _split( list, str, delim, trimItems, includeEmpty ); } // hack for split template //ciString trim ( const String & victim ) unsigned split( std::vector & list, const ciString & str, const ciString & delim , bool trimItems, bool includeEmpty) { return _split( list, str, delim, trimItems, includeEmpty ); } String & trim( String & victim ) { return _trim( victim ); } int toInt( const String & str, bool isNull ) { if ( isNull ) return 0; return atoi( str.c_str() ); } bool toBoolean ( const String & str, bool isNull ) { return toInt( str, isNull ) != 0; } long long toLong( const String & str, bool isNull ) { if (isNull) return 0L; return strtoll(str.c_str(), NULL, 10); } float toFloat( const String & str, bool isNull ) { return static_cast( toDouble( str.c_str() ) ); } double toDouble( const String & str, bool isNull ) { if (isNull) return 0.0; return atof(str.c_str()); } const String & defaultIfEmpty ( const String & str, const String & defStr ) { if ( str.empty() ) return defStr; else return str; } String toHexString( char c, bool leading0x ) { String result; if ( leading0x ) result= "0x"; std::stringstream buf; buf << std::hex << (int)(c & 0xff); result.append( buf.str() ); return result; } String::size_type toHexString( String & buff, const char c[], int count, bool leading0x ) { while( --count >= 0 ) { buff+= toHexString( *c, leading0x ); if ( count ) { buff+= " "; ++c; } } return buff.size(); } String toHexString( const char * c, int count, bool leading0x ) { String tmp; toHexString( tmp, c, count, leading0x ); return tmp; } String & concatSeparated( String & to, const String & add, const String & separator ) { if ( to.length() > 0 && add.length() > 0 ) to+= separator; to+= add; return to; } } mysql-connector-c++-1.1.7/test/common/stringutils.h000644 015771 000012 00000005107 12645244437 022776 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CCPP_STRINGUTILS_H #define __CCPP_STRINGUTILS_H #include "ccppTypes.h" namespace StringUtils { template unsigned _split ( std::vector & list , const StdStringType & str , const StdStringType & delim , bool trimItems= true , bool includeEmpty= false); // just a shortcut for split() unsigned split ( List & list , const String & str , const String & delim , bool trimItems= true , bool includeEmpty= false); template StdStringType & _trim ( StdStringType & victim ); /* Unlike Java's trim, this trims only blank spaces */ String & trim ( String & victim ); int toInt ( const String & str, bool isNull = false ); bool toBoolean ( const String & str, bool isNull = false ); long long toLong ( const String & str, bool isNull = false ); float toFloat ( const String & str, bool isNull = false ); double toDouble ( const String & str, bool isNull = false ); const String & defaultIfEmpty ( const String & str, const String & defStr ); String toHexString( char c, bool leading0x= false ); String toHexString( const char * c, int count, bool leading0x= false ); String & concatSeparated( String & to, const String & add, const String & separator= " " ); } #endif mysql-connector-c++-1.1.7/test/driver_test.cpp000644 015771 000012 00000005046 12645244437 022006 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include using namespace std; int loops = 2; static sql::Driver * mysql_driver = NULL; /* {{{ */ static sql::Connection * get_connection(const std::string & host, const std::string & user, const std::string & pass) { try { /* There will be concurrency problem if we had threads, but don't have, then it's ok */ if (!mysql_driver) { mysql_driver = get_driver_instance(); } if (loops % 2) { return mysql_driver->connect(host, user, pass); } else { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"] = host; connection_properties["userName"] = user; connection_properties["password"] = pass; return mysql_driver->connect(connection_properties); } } catch (sql::SQLException &e) { cout << "sql::SQLException caught during connect" << endl; cout << e.what() << endl; throw; } } /* }}} */ #define DRIVER_TEST 1 #define TEST_COMMON_TAP_NAME "driver_test" #include "test_common.cpp" static void driver_test_new_driver_exception() { try { new sql::mysql::MySQL_Driver(); ensure("Exception not thrown", false); } catch (sql::InvalidArgumentException) { } } /* {{{ */ int main(int argc, const char **argv) { driver_test_new_driver_exception(); return run_tests(argc, argv); } /* }}} */ mysql-connector-c++-1.1.7/test/framework/CMakeLists.txt000644 015771 000012 00000004574 12645244437 023512 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # IF(WIN32) # LINK_DIRECTORIES(${MYSQL_DIR}/lib/$(ConfigurationName)) # ADD_DEFINITIONS("-D_SECURE_SCL") ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") ELSEIF(NOT WIN32) ENDIF(WIN32) IF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(MY_GCOV_LINK_LIBRARIES gcov) ENDIF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(testframework_sources test_suite.cpp test_factory.cpp test_listener.cpp test_asserts.cpp test_tapOutputter.cpp test_runner.cpp test_container.cpp test_timer.cpp ../common/stringutils.cpp ../common/file.cpp start_options.cpp test_filter.cpp ) # It's convinient for VS users to have headers as part of project IF(WIN32) SET(testframework_sources ${testframework_sources} framework.h test_runner.h test_suite.h test_case.h test_factory.h test_listener.h test_asserts.h test_outputter.h test_tapOutputter.h test_container.h test_timer.h start_options.h test_filter.h ../common/stringutils.h ../common/file.h ) ENDIF(WIN32) ADD_LIBRARY(test_framework STATIC ${testframework_sources}) SET_TARGET_PROPERTIES(test_framework PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") MESSAGE(STATUS "Configuring tests framework lib") mysql-connector-c++-1.1.7/test/framework/framework.h000644 015771 000012 00000004260 12645244437 023110 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FRAMEWORK_H #define __FRAMEWORK_H #include "test_case.h" #include "test_suite.h" #include "test_asserts.h" #include "test_listener.h" #include "test_runner.h" #include "test_factory.h" #include "test_timer.h" #ifdef _WIN32 #include #define SLEEP(x) Sleep((x)*1000) #else #include #define SLEEP(x) sleep((x)) #endif #define REGISTER_FIXTURE( theFixtureClass ) \ \ static int dummy##theFixtureClass = TestSuiteFactory::RegisterTestSuite( #theFixtureClass \ , & CreateTestCase ) // probably pretty much useless ifndef #ifndef TEST_FIXTURE #define TEST_FIXTURE( theFixtureClass ) typedef theFixtureClass TestSuiteClass;\ theFixtureClass( const String & name )\ : TestSuite( #theFixtureClass ) #endif #define TEST_CASE( methodName ) \ RegisterTestCase( new TestCase( *this, &TestSuiteClass::methodName, #methodName ) ) #define SKIP( message ) TestsListener::setTestExecutionComment( String("SKIP ") + message );\ return #define TODO( message ) TestsListener::setTestExecutionComment( String("TODO ") + message ); throw TestFailedException(); #endif // __FRAMEWORK_H mysql-connector-c++-1.1.7/test/framework/start_options.cpp000644 015771 000012 00000013310 12645244437 024352 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "start_options.h" namespace testsuite { /*** TODO figure out will i need it * static const String::value_type * defaultUnnamedParam[]= { "dbUrl" , "dbUser" , "dbPasswd" , "dbSchema" }; */ static const String::value_type * trueStrings[]= {"y", "yes", "true", "t", "1" , NULL}; static const String::value_type * falseStrings[]= {"n", "no", "false", "f", "0" , NULL}; bool equal2any(const ciString & val, const String::value_type * arr[]) { while( *arr != NULL ) { if ( val == *arr ) return true; ++arr; } return false; } StartOptions::StartOptions() { } /* Last orderedParams array member must be NULL */ StartOptions::StartOptions( const String::value_type * orderedParams[] , const Properties * defStrVals , const std::map* defBoolVals ) { while ( *orderedParams != NULL ) { unnamedParams.push_back( *orderedParams ); ++orderedParams; } if ( defStrVals != NULL ) defStringValues= *defStrVals; if ( defBoolVals != NULL ) defBoolValues= *defBoolVals; } StartOptions::StartOptions( const List & orderedParams , const Properties * defStrVals , const std::map* defBoolVals ) { for ( List::const_iterator cit= orderedParams.begin(); cit != orderedParams.end(); ++cit ) { unnamedParams.push_back( *cit ); } if ( defStrVals != NULL ) defStringValues= *defStrVals; if ( defBoolVals != NULL ) defBoolValues= *defBoolVals; } bool StartOptions::paramAsBool( const ciString & param ) const { // not actually needed. since true is default if ( equal2any( param, trueStrings ) ) return true; if ( equal2any( param, falseStrings ) ) return false; return true; } bool StartOptions::parseParams(int paramsNumber, char** paramsValues) { List paramPair; if (paramsNumber > 1) { List::const_iterator curParam= unnamedParams.begin(); while (--paramsNumber) { ciString param(*(++paramsValues)); if (param.substr(0, 2) == "--") { paramPair.clear(); StringUtils::split( paramPair, param.substr(2).c_str(), "=" ); // Latter shouldn't really ever happen if ( paramPair.size() > 2 || paramPair.size() == 0 ) { std::cerr << "Can't parse. Wrong start parameter: " << *paramsValues << std::endl; return false; } if ( paramPair.size() == 2 ) { sOptions[paramPair[0]]= paramPair[1]; bOptions[paramPair[0]]= paramAsBool( ciString( paramPair[1].c_str() ) ); } else { BoolParamsType::const_iterator cit= defBoolValues.find( paramPair[0] ); if ( cit != defBoolValues.end() ) bOptions[paramPair[0]]= cit->second; else bOptions[paramPair[0]]= true; } } else if ( curParam != unnamedParams.end() ) { sOptions[ *curParam ]= String(param.c_str()); ++curParam; } } } return true; } bool StartOptions::defaultBoolValue( const String & name ) const { BoolParamsType::const_iterator cit= defBoolValues.find( name ); if ( (cit) != defBoolValues.end() ) return cit->second; return false; } // false is default bool value bool StartOptions::getBool( const String & name ) const { BoolParamsType::const_iterator cit= bOptions.find( name ); if ( cit != bOptions.end() ) return cit->second; return defaultBoolValue( name ); } const String & StartOptions::defaultStringValue( const String & name ) const { static String empty; Properties::const_iterator cit= defStringValues.find( name ); if ( cit != defStringValues.end() ) return cit->second; return empty; } const String & StartOptions::getString( const String & param) const { Properties::const_iterator cit= sOptions.find( param ); if ( cit != sOptions.end() ) return cit->second; return defaultStringValue( param ); } int StartOptions::getInt( const String & param) const { return StringUtils::toInt( getString( param ) ); } } // namespace testsuite mysql-connector-c++-1.1.7/test/framework/start_options.h000644 015771 000012 00000005023 12645244437 024021 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TEST_FRAMEWORK_START_OPTIONS #define __TEST_FRAMEWORK_START_OPTIONS #include "../common/ccppTypes.h" #include "../common/stringutils.h" namespace testsuite { class StartOptions { private: typedef std::map BoolParamsType; List unnamedParams; BoolParamsType defBoolValues; Properties defStringValues; BoolParamsType bOptions; Properties sOptions; protected: bool paramAsBool ( const ciString & param ) const; bool defaultBoolValue ( const String & name ) const; const String & defaultStringValue( const String & name ) const; public: StartOptions(); StartOptions( const List & orderedParams , const Properties * defStrVals = NULL , const std::map * defBoolVals = NULL ); /* Last array member must be NULL */ StartOptions( const String::value_type * orderedParams[] , const Properties * defStrVals = NULL , const std::map * defBoolVals = NULL ); bool parseParams(int paramsNumber, char** paramsValues); bool getBool ( const String & name ) const; const String & getString ( const String & param) const; int getInt ( const String & param) const; }; } // namespace testsuite #endif // __TEST_FRAMEWORK_START_OPTIONS mysql-connector-c++-1.1.7/test/framework/test_asserts.cpp000644 015771 000012 00000023512 12645244437 024172 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_asserts.h" #include "test_listener.h" #include "math.h" #include namespace testsuite { void assertTrue(const String & msg, bool expression, const char * file, int line) { if (!expression) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertTrue() failed in " << file << ", line #" << line; errmsg << ": '" << msg << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertEquals(const char * expected, const char * result, const char * file, int line) { String s1(expected), s2(result); assertEquals(s1, s2, file, line); } void assertEquals(bool expected, bool result, const char * file, int line) { if (expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(boolean) failed in " << file << ", line #" << line; TestsListener::testHasFailed(errmsg.str()); } } void assertEquals(int expected, unsigned int result , const char * file, int line) { if ((unsigned) expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertEquals(int expected, int result , const char * file, int line) { if (expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertEquals(unsigned int expected, unsigned int result , const char * file, int line) { if (expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(unsigned int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertEquals(int64_t expected, int64_t result , const char * file, int line) { if (expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(int64_t) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertEquals(uint64_t expected, uint64_t result , const char * file, int line) { if (expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(uint64_t) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } bool isNaN(double smth) { bool lessThanZero=(smth < 0.0); bool moreOrEqualZero=(smth >= 0.0); return !(lessThanZero || moreOrEqualZero); } double scaledEpsilon(const double & expected, const double & fuzzyEpsilon) { const double aa=fabs(expected) + 1; return ( true) ? fuzzyEpsilon : fuzzyEpsilon * aa; } double scaledEpsilon(const long double & expected, const long double & fuzzyEpsilon) { const long double aa=fabs(expected) + 1; return ( true) ? fuzzyEpsilon : fuzzyEpsilon * aa; } bool fuzzyEquals(double expected, double result, double fuzzyEpsilon) { return ( expected == result) || (fabs(expected - result) <= scaledEpsilon(expected, fuzzyEpsilon)); } bool fuzzyEquals(long double expected, long double result, long double fuzzyEpsilon) { return ( expected == result) || (fabs(expected - result) <= scaledEpsilon(expected, fuzzyEpsilon)); } void assertEquals(const long double & expected, const long double & result, const char * file, int line) { const long double fuzzyEpsilon=0.000001; assertEqualsEpsilon(expected, result, fuzzyEpsilon, file, line); } void assertEquals(const double & expected, const long double & result, const char * file, int line) { const long double fuzzyEpsilon=0.000001; assertEqualsEpsilon(expected, result, fuzzyEpsilon, file, line); } void assertEquals(const double & expected, const double & result, const char * file, int line) { const double fuzzyEpsilon=0.000001; assertEqualsEpsilon(expected, result, fuzzyEpsilon, file, line); } void assertEquals(const float & expected, const float & result, const char * file, int line) { assertEquals(static_cast (expected), static_cast (result) , file, line); } void assertEqualsEpsilon(const long double & expected, const long double & result , const long double & epsilon, const char * file, int line) { if ( ( isNaN(expected) && isNaN(result) ) || ( !isNaN(expected) && !isNaN(result) && fuzzyEquals(expected, result, epsilon) ) ) { return; } std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(double) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } void assertEqualsEpsilon(const double & expected, const double & result , const double & epsilon, const char * file, int line) { if ( ( isNaN(expected) && isNaN(result) ) || ( !isNaN(expected) && !isNaN(result) && fuzzyEquals( expected, result, epsilon ) ) ) { return; } std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(double) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } void assertEquals(const String & expected, const String & result , const char * file, int line) { if (expected != result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertEquals(std::string) failed in" << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertLessThan(int expected, unsigned int result , const char * file, int line) { if ((unsigned) expected < result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertLessThan(int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertLessThan(int expected, int result , const char * file, int line) { if (expected < result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertLessThan(int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertLessThan(unsigned int expected, unsigned int result , const char * file, int line) { if (expected < result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertLessThan(unsigned int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertGreaterThan(int expected, unsigned int result , const char * file, int line) { if ((unsigned) expected > result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertGreaterThan(int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertGreaterThan(int expected, int result , const char * file, int line) { if (expected > result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertGreaterThan(int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void assertGreaterThan(unsigned int expected, unsigned int result , const char * file, int line) { if (expected > result) { std::stringstream errmsg; errmsg.str(""); errmsg << "assertGreaterThan(unsigned int) failed in " << file << ", line #" << line; errmsg << " expecting '" << expected << "' got '" << result << "'"; TestsListener::testHasFailed(errmsg.str()); } } void fail(const char* reason, const char * file, int line) { // if( verbose... // TestsListener std::stringstream errmsg; errmsg.str(""); errmsg << "failed in " << file << ", line #" << line; errmsg << ". Reason: '" << reason << "'"; TestsListener::testHasFailed(errmsg.str()); } } mysql-connector-c++-1.1.7/test/framework/test_asserts.h000644 015771 000012 00000011037 12645244437 023636 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTASSERTS_H_ #define __TESTASSERTS_H_ #include "../../cppconn/resultset.h" #include "../common/ccppTypes.h" #ifndef __LINE__ #define __LINE__ "(line number n/a)" #endif namespace testsuite { void fail(const char* reason, const char * file, int line); void assertTrue(const String & msg, bool expression , const char * file, int line); void assertEquals(const char * expected, const char * result , const char * file, int line); void assertEquals(int expected, unsigned int result , const char * file, int line); void assertEquals(int expected, int result , const char * file, int line); void assertEquals(unsigned int expected, unsigned int result , const char * file, int line); void assertEquals(int64_t expected, int64_t result , const char * file, int line); void assertEquals(uint64_t expected, uint64_t result , const char * file, int line); void assertEquals(bool expected, bool result , const char * file, int line); void assertEquals(const double & expected, const long double & result , const char * file, int line); void assertEquals(const long double & expected, const long double & result , const char * file, int line); void assertEquals(const double & expected, const double & result , const char * file, int line); void assertEquals(const float & expected, const float & result , const char * file, int line); void assertEquals(const long double & expected , const long double & result , const char * file, int line); void assertEqualsEpsilon(const double & expected, const double & result , const double & epsilon, const char * file, int line); void assertEquals(const String & expected, const String & result , const char * file, int line); void assertTrueMessage(bool exp, const String & msg, const char * file , int line); void assertGreaterThan(int expected, unsigned int result , const char * file, int line); void assertGreaterThan(int expected, int result , const char * file, int line); void assertGreaterThan(unsigned int expected, unsigned int result , const char * file, int line); void assertLessThan(int expected, unsigned int result , const char * file, int line); void assertLessThan(int expected, int result , const char * file, int line); void assertLessThan(unsigned int expected, unsigned int result , const char * file, int line); bool fuzzyEquals(double expected, double result, double fuzzyEpsilon); } // Macros should be used inside testsuite namespace #define ASSERT_EQUALS( expected, result) \ assertEquals( (expected), (result), __FILE__, __LINE__ ) #define ASSERT_LT( expected, result) \ assertLessThan( (expected), (result), __FILE__, __LINE__ ) #define ASSERT_GT( expected, result) \ assertGreaterThan( (expected), (result), __FILE__, __LINE__ ) #define ASSERT_EQUALS_EPSILON( expected, result, epsilon) \ assertEqualsEpsilon( (expected), (result), (epsilon), __FILE__, __LINE__ ) #define ASSERT( exp ) assertTrue( (#exp), (exp), __FILE__, __LINE__) #define ASSERT_MESSAGE( exp, message ) \ assertTrue( (message), (exp), __FILE__, __LINE__ ) #define FAIL( why ) fail( (#why), __FILE__, __LINE__ ) #endif // __TESTASSERTS_H_ mysql-connector-c++-1.1.7/test/framework/test_case.h000644 015771 000012 00000004445 12645244437 023072 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTCASE_H_ #define __TESTCASE_H_ #include #include #include #include #include #include "../common/ccppTypes.h" #include "../common/stringutils.h" #include "test_container.h" namespace testsuite { _ABSTRACT class Test: virtual private Private::TestContainer { friend class Private::TestContainer::StorableTest; protected: virtual ~Test() { } public: virtual void runTest () _PURE; virtual const String & name () const _PURE; }; template class TestCase : public Test { protected: typedef void (SuiteClass::*TestCaseMethod)(); private: SuiteClass * suite; TestCaseMethod aTest; String testName; TestCase(); TestCase(const TestCase &other); public: TestCase( SuiteClass & obj , TestCaseMethod testMethod , const String & _name) : Test (), suite ( &obj ), aTest ( testMethod ), testName ( _name ) { } virtual void runTest() { (suite->*aTest)(); } virtual const String & name() const { return testName; } }; } #endif // ifndef __TESTCASE_H_ mysql-connector-c++-1.1.7/test/framework/test_container.cpp000644 015771 000012 00000003224 12645244437 024466 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_case.h" #include "test_container.h" #include "../common/ccppTypes.h" namespace testsuite { namespace Private { TestContainer::StorableTest::~StorableTest() { delete test; } TestContainer::StorableTest::StorableTest( Test & test2decorate ) { test= &test2decorate; } /*Test & TestContainer::StorableTest::operator * () { return *test; } Test * TestContainer::StorableTest::operator ->() { return get(); }*/ Test * TestContainer::StorableTest::get() { //assert(test); return test; } } } mysql-connector-c++-1.1.7/test/framework/test_container.h000644 015771 000012 00000003175 12645244437 024140 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTCONTAINER_H_ #define __TESTCONTAINER_H_ #include "../common/ccppTypes.h" #include namespace testsuite { class Test; namespace Private { class TestContainer { protected: class StorableTest : public boost::noncopyable { StorableTest(){} Test * test; public: virtual ~StorableTest(); StorableTest( Test & test2decorate ); /*Test & operator * (); Test * operator ->();*/ Test * get(); }; }; } } #endif // ifndef __TESTCONTAINER_H_ mysql-connector-c++-1.1.7/test/framework/test_factory.cpp000644 015771 000012 00000004545 12645244437 024162 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_factory.h" namespace testsuite { TestSuiteFactory::TestSuiteFactory() { } Test * TestSuiteFactory::createTest( const String::value_type * name ) { TestSuites::iterator it= testSuites.find( name ); if ( it != testSuites.end() ) { // if Object hasn't yet been created... if ( it->second.second == NULL ) it->second.second= new StorableTest( *(it->second.first( it->first )) ); //ASSERT( it->second.second ); return it->second.second->get();//it->second(it->first); } return NULL; } int TestSuiteFactory::RegisterTestSuite(const String::value_type * name, TestSuiteCreator creator) { TestSuiteFactory::theInstance().testSuites.insert(std::make_pair(name , std::make_pair(creator, static_cast(NULL) ) ) ); return static_cast(TestSuiteFactory::theInstance().testSuites.size()); } List::size_type TestSuiteFactory::getTestsList( std::vector & list ) const { for ( TestSuites::const_iterator cit= testSuites.begin(); cit != testSuites.end(); ++cit ) { list.push_back( cit->first ); } return list.size(); } TestSuiteFactory::~TestSuiteFactory() { for ( TestSuites::iterator it= testSuites.begin(); it != testSuites.end(); ++it ) { delete it->second.second; } } } // namespace testsuite mysql-connector-c++-1.1.7/test/framework/test_factory.h000644 015771 000012 00000004124 12645244437 023620 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTFACTORY_H_ #define __TESTFACTORY_H_ #include "../common/singleton.h" #include "test_container.h" namespace testsuite { typedef Test* (*TestSuiteCreator)(const String::value_type * name); template Test * CreateTestCase(const String::value_type * name) { return new SuiteClass(name); } class TestSuiteFactory : public policies::Singleton, Private::TestContainer { private: // should be private/protected CCPP_SINGLETON(TestSuiteFactory); typedef std::map > TestSuites; TestSuites testSuites; ~TestSuiteFactory(); public: Test * createTest ( const String::value_type * name ); static int RegisterTestSuite ( const String::value_type * name , TestSuiteCreator creator); List::size_type getTestsList ( std::vector & list ) const; }; } // namespace testsuite #endif // __TESTFACTORY_H_ mysql-connector-c++-1.1.7/test/framework/test_filter.cpp000644 015771 000012 00000012650 12645244437 023774 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_filter.h" namespace testsuite { static const char * wildCardCharacter= "*"; // We suppose we receive trimmed string here SingleFilter::SingleFilter( const String & filterStr , const String & NOTsymbol /*= "!"*/ ) { String filterString; if ( filterStr.find( NOTsymbol ) == 0 ) { negative= true; filterString= filterStr.substr( NOTsymbol.length() ).c_str(); } else { negative= false; filterString= filterStr; } StringUtils::trim( filterString ); StringUtils::split( staticPart, filterString, wildCardCharacter, true, true ); } bool SingleFilter::Admits( const String & testName ) const { const ciString test2filter( testName.c_str() ); ciString::size_type searchStartPos= 0; ciString::size_type partPosition= 0; const List::size_type parts= staticPart.size(); bool meetPrevEndExactly= true; bool result= true; for ( List::size_type i= 0; i < parts; ++i ) { const String & part= staticPart[ i ]; // empty staticPart means wildcard at the begin or end of filter string // empty parts in the middle (can be caused by two successive wild cards) ignored if ( part.empty() ) { meetPrevEndExactly= false; continue; } else { partPosition= test2filter.find( part.c_str(), searchStartPos ); if ( partPosition == ciString::npos || ( meetPrevEndExactly && partPosition != searchStartPos ) ) { result= false; break; } searchStartPos= partPosition + part.size(); meetPrevEndExactly= true; } } // Last part wasn't wildcard and and didn't match the end of the tested string if ( result && meetPrevEndExactly && searchStartPos != test2filter.size() ) result= false; return (negative ? ! result : result); // negative != result } /************************************************************************/ /* SerialFilter methods */ /************************************************************************/ SerialFilter::SerialFilter( const String & filterString , const String & ANDsymbol /*= "&&"*/ , const String & NOTsymbol /*= "!"*/) { List series; StringUtils::split( series, filterString, ANDsymbol ); for ( List::const_iterator cit= series.begin(); cit != series.end(); ++cit ) { // Skipping empty filters - they are always true if ( cit->length() > 0 ) filter.push_back( new SingleFilter( *cit, NOTsymbol ) ); } } SerialFilter::~SerialFilter() { for ( FiltersList::iterator it= filter.begin(); it != filter.end(); ++it ) { delete *it; } } bool SerialFilter::Admits( const String & testName ) const { for ( FiltersList::const_iterator cit= filter.begin(); cit != filter.end(); ++cit ) { if ( ! (*cit)->Admits( testName ) ) return false; } return true; } /************************************************************************/ /* FiltersSuperposition methods */ /************************************************************************/ FiltersSuperposition::FiltersSuperposition( const String & filterString , const String & ORsymbol /*= "||" */ , const String & ANDsymbol/*= "&&" */ , const String & NOTsymbol/* = "!" */ ) { List series; StringUtils::split( series, filterString, ORsymbol ); for ( List::const_iterator cit= series.begin(); cit != series.end(); ++cit ) filter.push_back( new SerialFilter( *cit, ANDsymbol, NOTsymbol ) ); } FiltersSuperposition::~FiltersSuperposition() { for ( FiltersList::iterator it= filter.begin(); it != filter.end(); ++it ) { delete *it; } } bool FiltersSuperposition::Admits( const String & testName ) const { for ( FiltersList::const_iterator cit= filter.begin(); cit != filter.end(); ++cit ) { if ( (*cit)->Admits( testName ) ) return true; } //return true if filter is empty return filter.size() == 0; } } // namespace testsuite mysql-connector-c++-1.1.7/test/framework/test_filter.h000644 015771 000012 00000004757 12645244437 023452 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TEST_FILTRE_H_ #define __TEST_FILTRE_H_ #include "../common/ccppTypes.h" #include "../common/stringutils.h" #include namespace testsuite { _ABSTRACT class Filter { protected: typedef std::vector FiltersList; public: virtual ~Filter(){} virtual bool Admits( const String & name2test ) const _PURE; }; class SingleFilter : public Filter { private: List staticPart; bool negative; public: SingleFilter( const String & filterStr , const String & NOTsymbol= "!" ); bool Admits ( const String & testName ) const; }; // Sequence of "&&" filters class SerialFilter : public Filter { FiltersList filter; public: SerialFilter ( const String & filterString , const String & ANDsymbol= "&&" , const String & NOTsymbol= "!" ); ~SerialFilter (); bool Admits ( const String & testName ) const; }; // Sequence of "||" filters class FiltersSuperposition : public Filter { FiltersList filter; public: FiltersSuperposition ( const String & filterString , const String & ORsymbol= "||" , const String & ANDsymbol= "&&" , const String & NOTsymbol= "!" ); ~FiltersSuperposition (); bool Admits ( const String & testName ) const; }; } // namespace testsuite #endif // __TEST_FILTRE_H_ mysql-connector-c++-1.1.7/test/framework/test_listener.cpp000644 015771 000012 00000015323 12645244437 024334 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "test_listener.h" #include "test_timer.h" namespace testsuite { TestsListener::TestsListener() : curSuiteName("n/a") , curTestName("n/a") , curTestOrdNum(0) , executed(0) , exceptions(0) , verbose(false) , timing(false) { //TODO: Make StartOptions dependent outputter.reset(new TAP()); } void TestsListener::setVerbose(bool verbosity) { theInstance().verbose=verbosity; } bool TestsListener::doTiming(bool timing) { bool preserve= theInstance().timing; theInstance().timing=timing; return preserve; } //TODO: "set" counterparts std::ostream & TestsListener::errorsLog() { if (theInstance().verbose) return theInstance().outputter->errorsLog(); else { theInstance().devNull.str(""); return theInstance().devNull; } } void TestsListener::errorsLog(const String::value_type * msg) { if (msg != NULL) errorsLog() << msg << std::endl; } void TestsListener::errorsLog(const String & msg) { errorsLog() << msg << std::endl; } void TestsListener::errorsLog(const String::value_type * msg , const String::value_type * file , int line) { if (msg != NULL) { errorsLog() << msg << " File: " << file << " Line: " << line << std::endl; } } std::ostream & TestsListener::messagesLog() { if (theInstance().verbose) return theInstance().outputter->messagesLog(); else { theInstance().devNull.str(""); return theInstance().devNull; } } void TestsListener::messagesLog(const String::value_type * msg) { if (msg != NULL) messagesLog() << msg; } void TestsListener::messagesLog(const String & msg) { if (theInstance().verbose) messagesLog() << msg; } void TestsListener::currentTestName(const String & name) { theInstance().curTestName=name; } const String & TestsListener::currentSuiteName() { return theInstance().curSuiteName; } String TestsListener::testFullName() { return theInstance().curSuiteName + "::" + theInstance().curTestName; } void TestsListener::incrementCounter(int incrVal) { theInstance().curTestOrdNum+=incrVal; } int TestsListener::recordFailed() { failedTests.push_back(curTestOrdNum); return static_cast (failedTests.size()); } void TestsListener::nextSuiteStarts(const String & name, int testsNumber) { /* if ( name.length() > 0 ) theInstance().messagesLog() << "=============== " << name << " ends. " << "===============" << std::endl;*/ theInstance().curSuiteName=name; /* theInstance().messagesLog() << "=============== " << name << " starts. " << "===============" << std::endl;*/ theInstance().outputter->SuiteHeader(name, theInstance().curTestOrdNum + 1 , testsNumber); } void TestsListener::testHasStarted() { //std::cout << "."; ++theInstance().executed; theInstance().executionComment= ""; if (theInstance().timing) { Timer::startTest(testFullName()); } } void TestsListener::testHasFinished(TestRunResult result, const String & msg) { static String timingResult(""); if (theInstance().timing) { clock_t time=Timer::stopTest(testFullName()); float total = Timer::translate2seconds(time); static std::stringstream tmp; tmp.precision(10); tmp.str(""); tmp << std::showpoint; tmp << std::endl << "# " << std::setw(40) << std::left << "Total" << " = "; tmp << std::setw(13) << std::right << total << "s"; tmp << " (100.00%)" << std::endl; const List & names=Timer::getNames(testFullName()); ConstIterator it=names.begin(); for (; it != names.end(); ++it) { time=Timer::getTime(*it); tmp << "# " << std::setw(38) << std::left << *it; tmp << " = " << std::setw(13) << std::right << Timer::translate2seconds(time) << "s"; tmp << " ("; tmp << std::setw(6) << std::right; if (total > 0.0) { tmp.precision(5); tmp << ((100 / total) * Timer::translate2seconds(time)); tmp.precision(10); } else { tmp << "n/a "; } tmp << "%)"; tmp << " (line " << Timer::getLine(*it) << ")" << std::endl; } timingResult=tmp.str(); } else timingResult=""; if (!msg.empty()) StringUtils::concatSeparated(theInstance().executionComment, msg); if (!timingResult.empty()) StringUtils::concatSeparated(theInstance().executionComment, timingResult); if (result != trrPassed) { // Output about test fail and recording info theInstance().recordFailed(); if (result == trrThrown) ++theInstance().exceptions; theInstance().outputter->TestFailed(theInstance().curTestOrdNum , theInstance().curTestName , theInstance().executionComment); } else { // Output about test success theInstance().outputter->TestPassed(theInstance().curTestOrdNum , theInstance().curTestName , theInstance().executionComment); } } void TestsListener::setTestExecutionComment(const String & msg) { theInstance().executionComment= msg; } void TestsListener::testHasFailed(const String & msg) { setTestExecutionComment(msg); errorsLog(msg); throw TestFailedException(); } void TestsListener::summary() { outputter->Summary(executed , failed() /*+ exceptions - exceptions are already counted in failed()*/ , failedTests); } bool TestsListener::allTestsPassed() { return theInstance().exceptions && !theInstance().failed() == 0; } void TestsListener::bailSuite(const String & reason) { static const String bail("BAIL "); theInstance().outputter->Comment(bail + reason); } } mysql-connector-c++-1.1.7/test/framework/test_listener.h000644 015771 000012 00000007132 12645244437 024000 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTLISTENER_H_ #define __TESTLISTENER_H_ #include #include #include #include #include #include #include "start_options.h" #include "test_tapOutputter.h" #include #include "../common/stringutils.h" #include "../common/singleton.h" namespace testsuite { enum TestRunResult { trrPassed = 0, trrFailed, trrThrown }; class TestsListener : public policies::Singleton { CCPP_SINGLETON(TestsListener); boost::scoped_ptr outputter; String curSuiteName; String curTestName; unsigned curTestOrdNum; std::ostringstream devNull; unsigned executed; std::vector failedTests; // don't really need to count exceptions unsigned exceptions; bool verbose; bool timing; String executionComment; public: static std::ostream & errorsLog(); static void errorsLog (const String::value_type * msg); static void errorsLog ( const String::value_type * msg , const String::value_type * file, int line); static void errorsLog (const String & msg); static std::ostream & messagesLog(); static void messagesLog (const String::value_type * msg); static void messagesLog (const String & msg); static void incrementCounter( int incrVal= 1); int recordFailed (); static void setVerbose( bool verbosity ); static bool doTiming ( bool timing= true ); inline int failed() { return static_cast( failedTests.size() ); } static void currentTestName (const String & name); static const String & currentSuiteName (); static String testFullName (); static void nextSuiteStarts (const String & name , int testsNumber); static void testHasStarted (); static void testHasFinished ( TestRunResult result , const String & msg = "" ); static void testHasFailed (const String & msg); /** This sets comment to the test which output along w/ test result (it will be output in silent(non-verbose) mode too) */ static void setTestExecutionComment ( const String & msg ); static void bailSuite (const String & reason); void summary (); static bool allTestsPassed (); }; class TestFailedException { }; } #endif mysql-connector-c++-1.1.7/test/framework/test_outputter.h000644 015771 000012 00000005227 12645244437 024231 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TEST_OUTPUTTER_H_ #define __TEST_OUTPUTTER_H_ #include "../common/ccppTypes.h" namespace testsuite { // TODO: Add listener state passing - verbose/trace/streams // TODO: Add failed tests list passing _ABSTRACT class TestOutputter { public: virtual ~TestOutputter() { } virtual void Header (const String & text= "") _PURE; virtual void SuiteHeader(const String & name , unsigned first , int testsInSuite) _PURE; virtual void TestPassed(unsigned ordNum , const String & name , const String & comment= "") _PURE; virtual void TestFailed(unsigned ordNum , const String & name , const String & comment= "") _PURE; virtual void Comment(const String & comment) _PURE; virtual void Summary(unsigned testsRun , unsigned testsFailed // a bit TAP-bound... However listener can complete // needed info , std::vector & failedTestsNum) _PURE; virtual void SuiteSummary(const String & suiteName , unsigned testsRun , unsigned testsFailed) _PURE; // Make string from anything shouldn't be a problem virtual void Assert(const String & expected , const String & result , const String & file , int line) _PURE; virtual std::ostream & messagesLog() _PURE; virtual std::ostream & errorsLog() _PURE; }; } #endif mysql-connector-c++-1.1.7/test/framework/test_runner.cpp000644 015771 000012 00000004704 12645244437 024021 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_runner.h" #include "test_factory.h" #include "test_case.h" #include "test_listener.h" #include "test_filter.h" namespace testsuite { TestsRunner::TestsRunner() : startOptions( NULL ) , filter ( NULL ) { } bool TestsRunner::runTests() { TestSuiteNames.empty(); TestSuiteFactory::theInstance().getTestsList( TestSuiteNames ); TestsListener::setVerbose(startOptions->getBool( "verbose") ); TestsListener::doTiming( startOptions->getBool( "timer" ) ); String dummy; for ( constStrListCit cit= TestSuiteNames.begin(); cit != TestSuiteNames.end(); ++cit ) { dummy= *cit; dummy+= "::"; // to be caught by filters like "!SuiteName::*" if ( 1 ) //TestsWillRunCount( suiteName, testCases )( dummy ) ) { Test * ts= TestSuiteFactory::theInstance().createTest( *cit ); ts->runTest(); } //else TODO: Add skipping by filter condition message } TestsListener::theInstance().summary(); return TestsListener::allTestsPassed(); } void TestsRunner::setStartOptions(StartOptions * options) { startOptions=options; } void TestsRunner::setTestsFilter ( Filter & _filter ) { filter= &_filter; } StartOptions * TestsRunner::getStartOptions() { return theInstance().startOptions; } bool TestsRunner::Admits( const String & testName ) { if ( theInstance().filter != NULL ) return theInstance().filter->Admits( testName ); return true; } } mysql-connector-c++-1.1.7/test/framework/test_runner.h000644 015771 000012 00000003571 12645244437 023467 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTSRUNNER_H_ #define __TESTSRUNNER_H_ #include "../common/singleton.h" #include "start_options.h" namespace testsuite { class Filter; class TestsRunner : public policies::Singleton { private: typedef std::vector constStrList; typedef constStrList::const_iterator constStrListCit; // should be private/protected CCPP_SINGLETON(TestsRunner); constStrList TestSuiteNames; StartOptions * startOptions; Filter * filter; public: bool runTests (); void setStartOptions ( StartOptions * options ); void setTestsFilter ( Filter & _filter ); static StartOptions * getStartOptions (); static bool Admits ( const String & testName ); }; } #endif // __TESTSRUNNER_H_ mysql-connector-c++-1.1.7/test/framework/test_suite.cpp000644 015771 000012 00000011412 12645244437 023633 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_suite.h" #include "test_runner.h" //#include "deletable_wrapper.h" namespace testsuite { const String & TestSuite::name() const { return suiteName; }; TestSuite::TestSuite( const String& name ) : suiteName( name ) { } void TestSuite::RegisterTestCase( Test * test ) { if ( test != NULL ) testCases.push_back( new TestContainer::StorableTest( *test ) ); } int TestSuite::TestsWillRunCount( const String & suiteName, const testsList & tl ) { int count= static_cast( tl.size() ); String fullName; for ( testsList::const_iterator cit=tl.begin(); cit != tl.end(); ++cit ) { fullName= suiteName; fullName+= "::"; fullName+= (*cit)->get()->name(); if ( ! TestsRunner::Admits( fullName ) ) { --count; } } return count; } /** calls each test after setUp and tearDown TestFixture methods */ void TestSuite::runTest() { TestsListener::nextSuiteStarts( suiteName, TestsWillRunCount( suiteName, testCases ) ); String fullName; for ( testsList_it it=testCases.begin(); it != testCases.end(); ++it) { fullName= suiteName; fullName+= "::"; fullName+= (*it)->get()->name(); if ( ! TestsRunner::Admits( fullName ) ) { // TODO: Add skipping by filter condition message continue; } //Incrementing order number of current test TestsListener::incrementCounter(); TestsListener::currentTestName( (*it)->get()->name() ); try { setUp(); } catch ( std::exception & e ) { TestsListener::bailSuite( String( "An exception occurred while running setUp before " ) + (*it)->get()->name() + ". Message: " + e.what() + ". Skipping all tests in the suite" ); //not really needed probably //TestsListener::testHasFinished( trrThrown, "Test setup has failed, all tests in the suite will be skipped" ); TestsListener::incrementCounter( static_cast(testCases.size() - ( it - testCases.begin() + 1 )) ); break; } TestRunResult result= trrPassed; try { TestsListener::testHasStarted(); (*it)->get()->runTest(); } // TODO: move interpretation of exception to TestSuite descendants // framework shouldn't know about sql::* exceptions catch ( sql::MethodNotImplementedException & sqlni ) { String msg( "SKIP relies on method " ); // or should it be TODO msg= msg + sqlni.what() + ", which is not implemented at the moment."; TestsListener::setTestExecutionComment( msg ); } catch ( std::exception & e ) { result= trrThrown; String msg( "Standard exception occurred while running test: " ); msg+= (*it)->get()->name(); msg+= ". Message: "; msg+= e.what(); TestsListener::setTestExecutionComment( msg ); TestsListener::errorsLog( msg ); } catch ( TestFailedException &) { // Thrown by fail. Just used to stop test execution result= trrFailed; } catch (...) { result= trrThrown; TestsListener::errorsLog() << "Unknown exception occurred while running:" << (*it)->get()->name() << std::endl; } TestsListener::testHasFinished( result ); try { tearDown(); } catch ( std::exception & e ) { TestsListener::errorsLog() << "Not trapped exception occurred while running while tearDown after:" << (*it)->get()->name() << ". Message: " << e.what() << std::endl; } // TODO: check why did i add it and is it still needed. //TestsListener::theInstance().currentTestName( "n/a" ); } } TestSuite::~TestSuite() { for ( testsList_it it=testCases.begin(); it != testCases.end(); ++it) delete (*it); } } mysql-connector-c++-1.1.7/test/framework/test_suite.h000644 015771 000012 00000003674 12645244437 023313 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TESTSUITE_H_ #define __TESTSUITE_H_ #include #include "../common/ccppTypes.h" #include "../common/stringutils.h" #include "start_options.h" #include #include "test_case.h" #include "test_listener.h" namespace testsuite { class TestSuite : public Test, virtual public Private::TestContainer { private: typedef std::vector testsList; typedef testsList::iterator testsList_it; testsList testCases; String suiteName; protected: static int TestsWillRunCount( const String & suiteName, const testsList & tl ); public: TestSuite(const String& name="Unnamed Test Suite"); ~TestSuite(); virtual void setUp() { } virtual void tearDown() { } const String & name() const; virtual void RegisterTestCase(Test * test); void runTest(); }; } // namespace testsuite #endif // __TESTSUITE_H_ mysql-connector-c++-1.1.7/test/framework/test_tapOutputter.cpp000644 015771 000012 00000010321 12645244437 025220 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_tapOutputter.h" #include #include namespace testsuite { TAP::TAP() : output( std::cout ) , msgLog( std::cerr ) , errLog( std::cerr ) { /* TODO - Discuss with Lawrin output << std::unitbuf; msgLog << std::unitbuf; errLog << std::unitbuf; */ } void TAP::Header(const String & text) { } void TAP::SuiteHeader( const String & name , unsigned first , int testsInSuite) { suiteName= name; Comment( name ); if ( testsInSuite > 0 ) output << first << ".." << first + testsInSuite - 1 << std::endl; else Comment( "doesn't contain any tests" ); } void TAP::TestPassed(unsigned ordNum , const String & name , const String & comment) { output << "ok " << ordNum << " - " << suiteName << "::" << name; if (comment.length() > 0) { output << " # " << comment; } output << std::endl; } void TAP::TestFailed( unsigned ordNum , const String & name , const String & comment ) { output << "not ok " << ordNum << " - " << suiteName << "::" << name; if ( comment.length() > 0 ) { output << " # " << comment; } output << std::endl; } void TAP::Comment(const String & comment) { output << "# " << comment << std::endl; } void TAP::Summary( unsigned testsRun , unsigned testsFailed , std::vector & failedTestsNum) { std::stringstream percentage; // Little data validation - otherwise sprintf can corrupt our precious stack if ( testsRun < testsFailed ) testsFailed= testsRun; if ( testsRun != 0 ) percentage << std::fixed < (testsRun - testsFailed)*100.0 / testsRun; else percentage << std::fixed < 0 ) { //TODO: move is string utils as "join" or smth std::vector::const_iterator cit=failedTestsNum.begin(); output << std::endl << "FAILED tests " << *cit; while (++cit != failedTestsNum.end()) { output << ", " << *cit; } } output << std::endl << "Failed " << testsFailed << "/" << testsRun << ", " << percentage.str() << "% okay" << std::endl; } void TAP::SuiteSummary(const String & _suiteName , unsigned testsRun , unsigned testsFailed) { } void TAP::Assert(const String & expected, const String & result , const String & file, int line) { std::ostringstream tmp("Assertion Failed in file "); tmp << file << " Line " << line; Comment(tmp.str()); tmp.flush(); tmp << "Expected: " << expected; Comment(tmp.str()); tmp.flush(); tmp << "Received: " << result; Comment(tmp.str()); } std::ostream & TAP::messagesLog() { // if they need log for smth... we have to make it TAP conmment // there is risk that user doesn't output endl and that will break TAP format. So, possibly // it's better to supply some str stream as a buffer msgLog << "# "; return msgLog; } std::ostream & TAP::errorsLog() { errLog << "# "; return errLog; } } mysql-connector-c++-1.1.7/test/framework/test_tapOutputter.h000644 015771 000012 00000004732 12645244437 024676 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TEST_TAPOUTPUTTER_H_ #define __TEST_TAPOUTPUTTER_H_ #include "test_outputter.h" namespace testsuite { class TAP : public TestOutputter { String suiteName; std::ostream & output; std::ostream & msgLog; std::ostream & errLog; public: TAP(); virtual ~TAP() { } virtual void Header(const String & text); virtual void SuiteHeader(const String & name , unsigned first , int testsInSuite); virtual void TestPassed(unsigned ordNum , const String & name , const String & comment); virtual void TestFailed(unsigned ordNum , const String & name , const String & comment); virtual void Comment(const String & comment); virtual void Summary(unsigned testsRun , unsigned testsFailed , std::vector & failedTestsNum); virtual void SuiteSummary(const String & suiteName , unsigned testsRun , unsigned testsFailed); virtual void Assert(const String & expected , const String & result , const String & file , int line); // Methods returning messages and error out streams. virtual std::ostream & messagesLog(); virtual std::ostream & errorsLog(); }; } #endif mysql-connector-c++-1.1.7/test/framework/test_timer.cpp000644 015771 000012 00000016250 12645244437 023627 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_timer.h" namespace testsuite { Timer::Timer() { } clock_t Timer::startTest(const String & test) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) { theInstance().currentTest=test; test_timer t=test_timer(); theInstance().timeRecorder[test]=t; return theInstance().timeRecorder[test].cpu; } return static_cast (-1); } clock_t Timer::stopTest(const String & test) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit != theInstance().timeRecorder.end()) { clock_t now=clock(); theInstance().timeRecorder[test].cpu=now - theInstance().timeRecorder[test].cpu; return theInstance().timeRecorder[test].cpu; } return static_cast (-1); } clock_t Timer::startTimer(const String & name, const String & file, const unsigned int line) { // HACK return startTimer(theInstance().currentTest, name, file, line); } clock_t Timer::startTimer(const String & test, const String & name, const String & file, const unsigned int line) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) // unknown test - must not happen return static_cast (-1); std::map::const_iterator it=theInstance().timeRecorder[test].timers.find(name); clock_t now=clock(); if (it == theInstance().timeRecorder[test].timers.end()) { timer t=timer(now, file, line); theInstance().timeRecorder[test].timers[name]=t; } else { /* TODO: API semantics are somewhat unclear - not sure what is best */ theInstance().timeRecorder[test].timers[name].start=now; theInstance().timeRecorder[name].timers[name].stopped=false; } return theInstance().timeRecorder[name].timers[name].start; } clock_t Timer::stopTimer(const String & name) { // hack return stopTimer(theInstance().currentTest, name); } clock_t Timer::stopTimer(const String & test, const String & name) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) // unknown test - must not happen return static_cast (-1); std::map::const_iterator it=theInstance().timeRecorder[test].timers.find(name); if (it == theInstance().timeRecorder[test].timers.end()) // unknown timer return static_cast (-1); if (theInstance().timeRecorder[test].timers[name].stopped) // has been stopped before return static_cast (-1); clock_t runtime=clock() - theInstance().timeRecorder[test].timers[name].start; theInstance().timeRecorder[test].timers[name].stopped=true; theInstance().timeRecorder[test].timers[name].total_cpu+=runtime; theInstance().timeRecorder[test].timers[name].start=static_cast (0); return runtime; } clock_t Timer::getTime(const String &name) { return getTime(theInstance().currentTest, name); } clock_t Timer::getTime(const String & test, const String & name) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) // unknown test - must not happen return static_cast (-1); std::map::const_iterator it=theInstance().timeRecorder[test].timers.find(name); if (it == theInstance().timeRecorder[test].timers.end()) // unknown timer return static_cast (-1); return theInstance().timeRecorder[test].timers[name].total_cpu; } float Timer::getSeconds(const String & name) { return translate2seconds(getTime(name)); } float Timer::translate2seconds(clock_t inWallClocks) { #ifdef CLOCKS_PER_SEC /* it looks like CLOCKS_PER_SEC should be defined on all platforms... just to feel safe. Maybe use sysconf(_SC_CLK_TCK) */ return static_cast (inWallClocks) / CLOCKS_PER_SEC; #else return static_cast (inWallClocks); #endif } unsigned int Timer::getLine(const String &name) { return getLine(theInstance().currentTest, name); } unsigned int Timer::getLine(const String & test, const String & name) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) // unknown test - must not happen return 0; std::map::const_iterator it=theInstance().timeRecorder[test].timers.find(name); if (it == theInstance().timeRecorder[test].timers.end()) // unknown timer return 0; return theInstance().timeRecorder[test].timers[name].line; } const String Timer::getFile(const String &name) { return getFile(theInstance().currentTest, name); } const String Timer::getFile(const String & test, const String & name) { std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) // unknown test - must not happen return 0; std::map::const_iterator it=theInstance().timeRecorder[test].timers.find(name); if (it == theInstance().timeRecorder[test].timers.end()) // unknown timer return 0; return theInstance().timeRecorder[test].timers[name].file; } const List & Timer::getNames() { static List names; std::map::const_iterator cit=theInstance().timeRecorder.find("perf_statement::anonymousSelect"); std::map::const_iterator it; for (; cit != theInstance().timeRecorder.end(); ++cit) { for (it=theInstance().timeRecorder[cit->first].timers.begin(); it != theInstance().timeRecorder[cit->first].timers.end(); ++it) { names.push_back(it->first); } } return names; } const List & Timer::getNames(const String & test) { static List names; std::map::const_iterator cit=theInstance().timeRecorder.find(test); if (cit == theInstance().timeRecorder.end()) { return names; } std::map::const_iterator it; for (it=theInstance().timeRecorder[cit->first].timers.begin(); it != theInstance().timeRecorder[cit->first].timers.end(); ++it) { names.push_back(it->first); } return names; } } mysql-connector-c++-1.1.7/test/framework/test_timer.h000644 015771 000012 00000007137 12645244437 023300 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TEST_TIMER_H_ #define __TEST_TIMER_H_ #include #include "../common/ccppTypes.h" #include "../common/singleton.h" namespace testsuite { struct timer { clock_t start; clock_t total_cpu; bool stopped; String file; unsigned int line; timer(clock_t _start, clock_t _total_cpu, bool _stopped) : start(_start), total_cpu(_total_cpu), stopped(_stopped), file(""), line(0) { } timer(clock_t _start) : start(_start), total_cpu(static_cast (0)), stopped(false), file(""), line(0) { } timer(clock_t _start, String _file, unsigned int _line) : start(_start), total_cpu(static_cast (0)), stopped(false), file(_file), line(_line) { } timer() : start(static_cast (0)), total_cpu(static_cast (0)), stopped(false), file(""), line(0) { this->start=clock(); } timer(const timer & rhs) : start(rhs.start), total_cpu(rhs.total_cpu), stopped(rhs.stopped), file(rhs.file), line(rhs.line) { } }; struct test_timer { clock_t cpu; std::map timers; test_timer() { this->cpu=clock(); } test_timer(const test_timer & rhs) : cpu(rhs.cpu), timers(rhs.timers) { } }; class Timer : public policies::Singleton { CCPP_SINGLETON(Timer); std::map timeRecorder; String currentTest; public: static clock_t startTest(const String & test); static clock_t stopTest(const String & test); static clock_t startTimer(const String & test, const String & name, const String & file, const unsigned int line); static clock_t startTimer(const String & name, const String & file, const unsigned int line); static clock_t stopTimer(const String & test, const String & name); static clock_t stopTimer(const String & name); static const List & getNames(); static const List & getNames(const String & test); static clock_t getTime(const String & test, const String & name); static clock_t getTime(const String & test); static float getSeconds(const String & test, const String & name); static float getSeconds(const String & test); static unsigned int getLine(const String & test, const String & name); static unsigned int getLine(const String & test); static const String getFile(const String & test, const String & name); static const String getFile(const String & test); static float translate2seconds(clock_t); }; } #define TIMER_START(label) Timer::startTimer(#label, __FILE__, __LINE__); #define TIMER_STOP(label) Timer::stopTimer(#label); #endif // ifndef __TEST_TIMER_H_ mysql-connector-c++-1.1.7/test/static_test.cpp000644 015771 000012 00000003757 12645244437 022011 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "driver/mysql_public_iface.h" #include int loops = 2; /* {{{ */ static sql::Connection * get_connection(const std::string& host, const std::string& user, const std::string& pass) { static sql::Driver * driver = sql::mysql::get_driver_instance(); if (loops % 2) { return driver->connect(host, /*port,*/ user, pass); } else { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"] = host; connection_properties["userName"] = user; connection_properties["password"] = pass; return driver->connect(connection_properties); } } /* }}} */ #define TEST_COMMON_TAP_NAME "static_test" #include "test_common.cpp" static void driver_test_new_driver_exception() { try { // new sql::mysql::MySQL_Driver(); // ensure("Exception not thrown", false); } catch (sql::InvalidArgumentException) { } } int main(int argc, const char **argv) { driver_test_new_driver_exception(); return run_tests(argc, argv); } mysql-connector-c++-1.1.7/test/test_common.cpp000644 015771 000012 00000346537 12645244437 022020 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #ifndef _WIN32 #include #endif #include /* __FUNCTION__/__func__ is not portable. We do not promise that our example definition covers each and every compiler. If not, it is up to you to find a different definition for your setup. */ #if __STDC_VERSION__ < 199901L # if __GNUC__ >= 2 # define CPPCONN_FUNC __FUNCTION__ # else # define CPPCONN_FUNC "(function n/a)" # endif #elif defined(_MSC_VER) # if _MSC_VER < 1300 # define CPPCONN_FUNC "(function n/a)" # else # define CPPCONN_FUNC __FUNCTION__ # endif #elif (defined __func__) # define CPPCONN_FUNC __func__ #else # define CPPCONN_FUNC "(function n/a)" #endif #ifndef __LINE__ #define __LINE__ "(line number n/a)" #endif #define ensure(msg, stmt) do {++total_tests;if(!(stmt)){printf("\n# Error! line=%d: %s\n# ",__LINE__,msg);++total_errors;throw sql::SQLException("error");} else { printf(".");}} while (0) #define ensure_equal(msg, op1, op2) do {++total_tests;if((op1)!=(op2)){printf("\n# Error! line=%d: %s\n# ",__LINE__,msg);++total_errors;throw sql::SQLException("error");} else { printf(".");}}while(0) #define ensure_equal_int(msg, op1, op2) do {++total_tests;if((op1)!=(op2)){printf("\n# Error! line=%d: %s Op1=%d Op2=%d\n# ",__LINE__,msg,op1,op2);++total_errors;throw sql::SQLException("error");} else { printf(".");}}while(0) #define ensure_equal_str(msg, op1, op2) do {++total_tests;if((op1)!=(op2)){printf("\n# Error! line=%d: %s Op1=%s Op2=%s\n# ",__LINE__,msg,op1.c_str(),op2.c_str());++total_errors;throw sql::SQLException("error");} else { printf(".");}}while(0) #define ensure_equal_int64(msg, op1, op2) do {++total_tests;if((op1)!=(op2)){printf("\n# Error! line=%d: %s Op1=%lld Op2=%lld\n# ",__LINE__,msg,(long long)op1,(long long)op2);++total_errors;throw sql::SQLException("error");} else { printf(".");}}while(0) #define ensure_equal_uint64(msg, op1, op2) do {++total_tests;if((op1)!=(op2)){printf("\n# Error! line=%d: %s Op1=%llu Op2=%llu\n# ",__LINE__,msg,(unsigned long long)op1,(unsigned long long)op2);++total_errors;throw sql::SQLException("error");} else { printf(".");}}while(0) static int total_errors = 0; static int total_tests = 0; static int silent = 1; #define USED_DATABASE "test" #define ENTER_FUNCTION() if (!silent) printf("# >>>> %s\n# ", CPPCONN_FUNC); #define LEAVE_FUNCTION() if (!silent) printf("# <<<< %s\n# ", CPPCONN_FUNC); else printf("\n# "); #if defined(_WIN32) || defined(_WIN64) #pragma warning(disable:4251) #pragma warning(disable:4800) #endif #ifdef _WIN32 #include "my_global.h" #endif extern "C" { #include "mysql.h" } /* mysql.h introduces bool */ #undef bool #if defined(_WIN32) || defined(_WIN64) #pragma warning(disable:4251) #endif #include #ifndef L64 #ifdef _WIN32 #define L64(x) x##i64 #else #define L64(x) x##LL #endif #endif #ifndef UL64 #ifdef _WIN32 #define UL64(x) x##ui64 #else #define UL64(x) x##ULL #endif #endif /* {{{ */ static bool populate_blob_table(boost::scoped_ptr & conn, std::string database) { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); stmt->execute("USE " + database); stmt->execute("DROP TABLE IF EXISTS test_blob"); if (true == stmt->execute("CREATE TABLE test_blob (a longblob) ENGINE=MYISAM")) { return false; } return true; } /* }}} */ /* {{{ */ static bool populate_insert_data(sql::Statement * stmt) { return stmt->execute("INSERT INTO test_function (a,b,c,d,e) VALUES(1, 111, NULL, '222', 'xyz')"); } /* }}} */ /* {{{ */ static bool populate_test_table(boost::scoped_ptr & conn, std::string database) { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); stmt->execute("USE " + database); stmt->execute("DROP TABLE IF EXISTS test_function"); if (true == stmt->execute("CREATE TABLE test_function (a integer unsigned not null, b integer, c integer default null, d char(10), e varchar(10) character set utf8 collate utf8_bin) ENGINE=MYISAM")) { return false; } if (true == populate_insert_data(stmt.get())) { stmt->execute("DROP TABLE test_function"); return false; } return true; } /* }}} */ /* {{{ */ static bool populate_TX_insert_data(sql::Statement * stmt) { return stmt->execute("INSERT INTO test_function_tx (a,b,c,d,e) VALUES(1, 111, NULL, '222', 'xyz')"); } /* }}} */ /* {{{ */ static bool populate_TX_test_table(boost::scoped_ptr & conn, std::string database) { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); stmt->execute("USE " + database); stmt->execute("DROP TABLE IF EXISTS test_function_tx"); if (true == stmt->execute("CREATE TABLE test_function_tx(a integer unsigned not null, b integer, c integer default null, d char(10), e varchar(10) character set utf8 collate utf8_bin) engine = innodb")) { return false; } if (true == populate_TX_insert_data(stmt.get())) { stmt->execute("DROP TABLE test_function_tx"); return false; } stmt->getConnection()->commit(); return true; } /* }}} */ /* {{{ */ static bool populate_test_table_PS(boost::scoped_ptr & conn, std::string database) { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); stmt1->execute("USE " + database); boost::scoped_ptr stmt2(conn->prepareStatement("DROP TABLE IF EXISTS test_function")); ensure("stmt2 is NULL", stmt2.get() != NULL); stmt2->executeUpdate(); boost::scoped_ptr stmt3(conn->prepareStatement("CREATE TABLE test_function(a integer unsigned not null, b integer, c integer default null, d char(10), e varchar(10) character set utf8 collate utf8_bin)")); ensure("stmt3 is NULL", stmt3.get() != NULL); stmt3->executeUpdate(); boost::scoped_ptr stmt4(conn->prepareStatement("INSERT INTO test_function (a,b,c,d,e) VALUES(1, 111, NULL, '222', 'xyz')")); ensure("stmt4 is NULL", stmt4.get() != NULL); stmt4->executeUpdate(); return true; } /* }}} */ /* {{{ */ static bool populate_TX_test_table_PS(boost::scoped_ptr & conn, std::string database) { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt is NULL", stmt1.get() != NULL); stmt1->execute("USE " + database); boost::scoped_ptr stmt2(conn->prepareStatement("DROP TABLE IF EXISTS test_function_tx")); ensure("stmt2 is NULL", stmt2.get() != NULL); stmt2->executeUpdate(); boost::scoped_ptr stmt3(conn->prepareStatement("CREATE TABLE test_function_tx(a integer unsigned not null, b integer, c integer default null, d char(10), e varchar(10) character set utf8 collate utf8_bin) engine = innodb")); ensure("stmt3 is NULL", stmt3.get() != NULL); stmt3->executeUpdate(); boost::scoped_ptr stmt4(conn->prepareStatement("INSERT INTO test_function_tx (a,b,c,d,e) VALUES(1, 111, NULL, '222', 'xyz')")); ensure("stmt4 is NULL", stmt4.get() != NULL); stmt4->executeUpdate(); return true; } /* }}} */ /* {{{ */ static bool populate_test_table_PS_integers(boost::scoped_ptr & conn, std::string database) { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); stmt1->execute("USE " + database); boost::scoped_ptr stmt2(conn->prepareStatement("DROP TABLE IF EXISTS test_function_int")); ensure("stmt2 is NULL", stmt2.get() != NULL); stmt2->executeUpdate(); boost::scoped_ptr stmt3(conn->prepareStatement("CREATE TABLE test_function_int(i integer, i_uns integer unsigned, b bigint, b_uns bigint unsigned)")); ensure("stmt3 is NULL", stmt3.get() != NULL); stmt3->executeUpdate(); return true; } /* }}} */ /* {{{ */ static void test_autocommit(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { conn->setAutoCommit(1); ensure("AutoCommit", conn->getAutoCommit() == true); conn->setAutoCommit(0); ensure("AutoCommit", conn->getAutoCommit() == false); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_connection_0(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { char buff[64]; boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT CONNECTION_ID()")); ensure("res1 is NULL", rset1.get() != NULL); ensure("res1 is empty", rset1->next() != false); ensure("connection is closed", !conn->isClosed()); sprintf(buff, "KILL %d", rset1->getInt(1)); try { stmt1->execute(buff); } catch (sql::SQLException &) { /* If this is mac, we will get an error. MySQL on Mac closes the connection without sending response */ } try { boost::scoped_ptr rset2(stmt1->executeQuery("SELECT CONNECTION_ID()")); ensure("no exception", false); } catch (sql::SQLException &) { ensure("Exception correctly thrown", true); } ensure("connection is open", conn->isClosed() == false); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_connection_1(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); ensure("connection is closed", !conn->isClosed()); conn->setAutoCommit(false); ensure("Data not populated", true == populate_TX_test_table(conn, database)); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res1 is NULL", rset1.get() != NULL); ensure("res1 is empty", rset1->next() != false); int count_full_before = rset1->getInt(1); ensure_equal_int("res1 has more rows ", rset1->next(), false); std::string savepointName("firstSavePoint"); boost::scoped_ptr savepoint(conn->setSavepoint(savepointName)); populate_TX_insert_data(stmt1.get()); boost::scoped_ptr rset2(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res2 is NULL", rset2.get() != NULL); ensure_equal_int("res2 is empty", rset2->next(), true); int count_full_after = rset2->getInt(1); ensure_equal_int("res2 has more rows ", rset2->next(), false); ensure_equal_int("wrong number of rows", count_full_after, (count_full_before * 2)); conn->rollback(savepoint.get()); boost::scoped_ptr rset3(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res3 is NULL", rset3.get() != NULL); ensure_equal_int("res3 is empty", rset3->next(), true); int count_full_after_rollback = rset3->getInt(1); ensure_equal_int("res3 has more rows ", rset3->next(), false); ensure_equal_int("wrong number of rows", count_full_after_rollback, count_full_before); conn->releaseSavepoint(savepoint.get()); try { /* The second call should throw an exception */ conn->releaseSavepoint(savepoint.get()); ++total_errors; } catch (sql::SQLException &) {} /* Clean */ stmt1->execute("USE " + database); stmt1->execute("DROP TABLE test_function_tx"); } catch (sql::MethodNotImplementedException &) { printf("\n# SKIP: RELEASE SAVEPOINT not available in this MySQL version\n"); printf("# "); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_connection_2(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt1 is NULL", stmt.get() != NULL); ensure("Wrong catalog", conn->getCatalog() == "def" || conn->getCatalog() == ""); stmt->execute("USE " + database); std::string newCatalog(conn->getSchema()); ensure(std::string("Wrong catalog '" + newCatalog + "'/'" + database + "'").c_str(), newCatalog == std::string(database)); try { conn->setCatalog(std::string("doesnt_actually_exist")); // printf("\n# ERR: Accepting invalid catalog"); // ++total_errors; } catch (sql::SQLException &) {} conn->setSchema(std::string("information_schema")); std::string newCatalog2(conn->getSchema()); ensure("Wrong catalog", newCatalog2 == std::string("information_schema")); } catch (sql::SQLException &e) { /* Error: 1049 SQLSTATE: 42000 (ER_BAD_DB_ERROR) - information_schema not available */ if (e.getErrorCode() != 1049) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_connection_3(boost::scoped_ptr & conn, std::string user) { ENTER_FUNCTION(); try { sql::DatabaseMetaData * meta = conn->getMetaData(); ensure("getUserName() failed", user == meta->getUserName().substr(0, user.length())); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_statement_0(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("AutoCommit", conn.get() == stmt->getConnection()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test simple update statement against statement object */ static void test_statement_1(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); if (false == stmt->execute("SELECT * FROM test_function")) ensure("False returned for SELECT", false); /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test simple query against statement object */ static void test_statement_2(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); if (false == stmt->execute("SELECT * FROM test_function")) ensure("False returned for SELECT", false); /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test executeQuery() - returning a result set*/ static void test_statement_3(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); /* Get a result set */ try { boost::scoped_ptr rset(stmt->executeQuery("SELECT * FROM test_function")); ensure("NULL returned for result set", rset.get() != NULL); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); ++total_errors; printf("# "); } /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test executeQuery() - returning empty result set */ static void test_statement_4(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); /* Get a result set */ try { boost::scoped_ptr rset(stmt->executeQuery("SELECT * FROM test_function WHERE 1=2")); ensure("NULL returned for result set", rset.get() != NULL); ensure_equal_int("Non-empty result set", false, rset->next()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test executeQuery() - use it for inserting, should generate an exception */ static void test_statement_5(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); /* Get a result set */ try { boost::scoped_ptr rset(stmt->executeQuery("INSERT INTO test_function VALUES(2,200)")); ensure("NULL returned for result set", rset.get() == NULL); ensure_equal_int("Non-empty result set", false, rset->next()); } catch (sql::SQLException &) { } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test executeUpdate() - check the returned value */ static void test_statement_6(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); /* Get a result set */ try { ensure("Number of updated rows", stmt->executeUpdate("UPDATE test_function SET a = 123") == 1); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); ++total_errors; } /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test executeUpdate() - execute a SELECT, should get an exception */ static void test_statement_7(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); /* Get a result set */ try { stmt->executeUpdate("SELECT * FROM test_function"); ensure("No exception thrown", false); } catch (sql::SQLException &) { } catch (...) { printf("\n# ERR: Incorrectly sql::SQLException ist not thrown\n"); printf("# "); ++total_errors; } /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ #if 0 /* {{{ Test getFetchSize() - should return int value */ /* XXX: Test fails because getFetchSize() is not implemented*/ static void test_statement_xx(boost::scoped_ptr & conn, boost::scoped_ptr & conn2) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("fetchSize is negative", stmt->getFetchSize() > 0); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test setFetchSize() - set and get the value */ /* XXX: Doesn't pass because setFetchSize() is unimplemented */ static void test_statement_xx(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); int setFetchSize = 50; stmt->setFetchSize(setFetchSize); ensure_equal("Non-equal", setFetchSize, stmt->getFetchSize()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } } /* }}} */ /* {{{ Test setFetchSize() - set negative value and expect an exception */ /* XXX: Doesn't pass because setFetchSize() is unimplemented */ static void test_statement_xx(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); try { stmt->setFetchSize(-1); ensure("No exception", false); } catch (sql::InvalidArgumentException) { printf("INFO: Caught sql::InvalidArgumentException\n"); } } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test setQueryTimeout() - set negative value and expect an exception */ /* XXX: Doesn't pass because setQueryTimeout() is unimplemented */ static void test_statement_xx(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); try { stmt->setQueryTimeout(-1); printf("\n# ERR:No exception\n"); } catch (sql::InvalidArgumentException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ #endif /* {{{ Test getResultSet() - execute() a query and get the result set */ static void test_statement_8(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); ensure("sql::Statement::execute returned false", true == stmt->execute("SELECT * FROM test_function")); boost::scoped_ptr rset(stmt->getResultSet()); ensure("rset is NULL", rset.get() != NULL); /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } } /* }}} */ /* {{{ Test getResultSet() - execute() an update query and get the result set - should be empty */ static void test_statement_9(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); ensure("sql::Statement::execute returned true", false == stmt->execute("UPDATE test_function SET a = 222")); boost::scoped_ptr rset(stmt->getResultSet()); ensure("rset is not NULL", rset.get() == NULL); /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test metadata usage after result set has been closed */ static void test_statement_10(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("stmt is NULL", stmt.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); boost::scoped_ptr res(stmt->executeQuery("SELECT * FROM test_function")); ensure("ResultSet is empty", res->rowsCount() > 0); sql::ResultSetMetaData * meta = res->getMetaData(); ensure("Error while reading a row ", res->next()); ensure_equal_str("Table name differs", meta->getTableName(1), std::string("test_function")); res->close(); try { ensure_equal_str("Table name differs", meta->getTableName(1), std::string("test_function")); ensure("Exception not correctly thrown", false); } catch (sql::SQLException &/*e*/) { // exception correctly thrown } /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); stmt2->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_result_set_0(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); ensure("AutoCommit", conn.get() == stmt->getConnection()); boost::scoped_ptr result(stmt->setResultSetType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE)->executeQuery("SELECT 1, 2, 3")); ensure_equal_int("isFirst", result->isFirst(), false); ensure_equal_int("isLast", result->isLast(), false); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_result_set_1(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); stmt1->setResultSetType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT 1")); ensure("res1 is NULL", rset1.get() != NULL); boost::scoped_ptr rset2(stmt1->executeQuery("SELECT 1")); ensure("res2 is NULL", rset2.get() != NULL); ensure("res1 is empty", rset1->next() != false); ensure("res2 is empty", rset2->next() != false); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_result_set_2(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); ensure("Data not populated", true == populate_test_table(conn, database)); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT 1")); ensure("res1 is NULL", rset1.get() != NULL); ensure_equal_int("res1 is empty", rset1->next(), true); ensure_equal_int("res1 is empty", rset1->next(), false); ensure("No rows updated", stmt1->executeUpdate("UPDATE test_function SET a = 2") > 0); stmt1->execute("DROP TABLE test_function"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ static void test_result_set_3(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); ensure_equal("sql::Connection differs", conn.get(), stmt1->getConnection()); int old_commit_mode = conn->getAutoCommit(); conn->setAutoCommit(0); ensure("Data not populated", true == populate_TX_test_table(conn, database)); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res1 is NULL", rset1.get() != NULL); ensure("res1 is empty", rset1->next() != false); int count_full_before = rset1->getInt(1); ensure("res1 has more rows ", rset1->next() == false); /* Let's delete and then rollback */ ensure_equal("Deleted less rows", stmt1->executeUpdate("DELETE FROM test_function_tx WHERE 1"), count_full_before); boost::scoped_ptr rset2(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res2 is NULL", rset2.get() != NULL); ensure("res2 is empty", rset2->next() != false); ensure("Table not empty after delete", rset2->getInt(1) == 0); ensure("res2 has more rows ", rset2->next() == false); stmt1->getConnection()->rollback(); boost::scoped_ptr rset3(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res3 is NULL", rset3.get() != NULL); ensure("res3 is empty", rset3->next() != false); int count_full_after = rset3->getInt(1); ensure("res3 has more rows ", rset3->next() == false); ensure("Rollback didn't work", count_full_before == count_full_after); /* Now let's delete and then commit */ ensure_equal("Deleted less rows", stmt1->executeUpdate("DELETE FROM test_function_tx WHERE 1"), count_full_before); stmt1->getConnection()->commit(); boost::scoped_ptr rset4(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res4 is NULL", rset4.get() != NULL); ensure("res4 is empty", rset4->next() != false); ensure("Table not empty after delete", rset4->getInt(1) == 0); ensure("res4 has more rows ", rset4->next() == false); stmt1->execute("DROP TABLE test_function_tx"); conn->setAutoCommit(old_commit_mode); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test commit and rollback (autocommit on) */ static void test_result_set_4(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); ensure_equal("sql::Connection differs", conn.get(), stmt1->getConnection()); int old_commit_mode = conn->getAutoCommit(); conn->setAutoCommit(true); ensure_equal_int("Data not populated", true, populate_TX_test_table(conn, database)); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res1 is NULL", rset1.get() != NULL); ensure_equal_int("res1 is empty", rset1->next(), true); int count_full_before = rset1->getInt(1); ensure_equal_int("res1 has more rows ", rset1->next(), false); /* Let's delete and then rollback */ ensure_equal_int("Deleted less rows", stmt1->executeUpdate("DELETE FROM test_function_tx WHERE 1"), count_full_before); boost::scoped_ptr rset2(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res2 is NULL", rset2.get() != NULL); ensure_equal_int("res2 is empty", rset2->next(), true); ensure_equal_int("Table not empty after delete", rset2->getInt(1), 0); ensure_equal_int("res2 has more rows ", rset2->next(), false); /* In autocommit on, this is a no-op */ stmt1->getConnection()->rollback(); boost::scoped_ptr rset3(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res3 is NULL", rset3.get() != NULL); ensure_equal_int("res3 is empty", rset3->next(), true); ensure_equal_int("Rollback didn't work", rset3->getInt(1), 0); ensure_equal_int("res3 has more rows ", rset3->next(), false); ensure("Data not populated", true == populate_TX_test_table(conn, database)); /* Now let's delete and then commit */ ensure_equal("Deleted less rows", stmt1->executeUpdate("DELETE FROM test_function_tx WHERE 1"), count_full_before); /* In autocommit on, this is a no-op */ stmt1->getConnection()->commit(); boost::scoped_ptr rset4(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res4 is NULL", rset4.get() != NULL); ensure_equal_int("res4 is empty", rset4->next(), true); ensure_equal_int("Table not empty after delete", rset4->getInt(1), 0); ensure_equal_int("res4 has more rows ", rset4->next(), false); conn->setAutoCommit(false); ensure("Data not populated", true == populate_TX_test_table(conn, database)); ensure_equal("Deleted less rows", stmt1->executeUpdate("DELETE FROM test_function_tx WHERE 1"), count_full_before); /* In autocommit iff, this is an op */ stmt1->getConnection()->rollback(); boost::scoped_ptr rset5(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx")); ensure("res5 is NULL", rset5.get() != NULL); ensure_equal_int("res5 is empty", rset5->next(), true); ensure_equal_int("Table empty after delete", rset5->getInt(1), count_full_before); ensure_equal_int("res5 has more rows ", rset5->next(), false); stmt1->execute("DROP TABLE test_function_tx"); conn->setAutoCommit(old_commit_mode); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test multistatement off - send two queries in one call */ static void test_result_set_5(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); try { boost::scoped_ptr rset1(stmt1->executeQuery("SELECT COUNT(*) FROM test_function_tx; DELETE FROM test_function_tx")); ensure("ERR: Exception not thrown", false); } catch (sql::SQLException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_result_set_check_out_of_bound(sql::ResultSet *rset1) { ensure("res1 is empty", rset1->next() != false); try { rset1->getInt(0); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getInt(123); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getInt("no_such_column"); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getString(0); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getString(123); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getString("no_such_column"); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getDouble(0); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getDouble(123); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getDouble("no_such_column"); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->getInt(rset1->getInt(1) + 1000); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->isNull(0); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->isNull(123); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { rset1->isNull("no_such_column"); ensure("ERR: No sql::InvalidArgumentException thrown", false); } catch (sql::InvalidArgumentException &) {} try { ensure_equal_int("res1 has more rows ", rset1->getInt(1), 1); ensure_equal_int("res1 has more rows ", rset1->getInt("count of rows"), 1); // ensure("res1 has more rows ", rset1->getDouble(1) - 1 < 0.1); // ensure("res1 has more rows ", rset1->getDouble("count of rows") - 1 < 0.1); // with libmysq we don't support these conversions, on the fly :( // ensure("res1 has more rows ", rset1->getString(1).compare("1")); // ensure("res1 has more rows ", rset1->getString("count of rows").compare("1")); ensure_equal_int("c is not null", rset1->isNull(1), false); ensure_equal_int("res1 has more rows ", rset1->next(), false); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } } /* {{{ Test out of bound extraction of data */ static void test_result_set_6(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); ensure_equal("sql::Connection differs", conn.get(), stmt1->getConnection()); ensure("Data not populated", true == populate_TX_test_table(conn, database)); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT COUNT(*) AS 'count of rows' FROM test_function_tx")); ensure("res1 is NULL", rset1.get() != NULL); test_result_set_check_out_of_bound(rset1.get()); stmt1->execute("DROP TABLE test_function_tx"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test out of bound extraction of data - PS version */ static void test_result_set_7(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { ensure("Data not populated", true == populate_TX_test_table(conn, database)); boost::scoped_ptr stmt1(conn->prepareStatement("SELECT COUNT(*) AS 'count of rows' FROM test_function_tx")); ensure("stmt1 is NULL", stmt1.get() != NULL); ensure_equal("sql::Connection differs", conn.get(), stmt1->getConnection()); boost::scoped_ptr rset1(stmt1->executeQuery()); ensure("res1 is NULL", rset1.get() != NULL); test_result_set_check_out_of_bound(rset1.get()); boost::scoped_ptr stmt2(conn->prepareStatement("DROP TABLE test_function_tx")); stmt2->execute(); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test commit and rollback (autocommit on) - PS version */ static void test_result_set_8(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { int count_full_before; boost::scoped_ptr stmt0(conn->prepareStatement("SELECT 1")); ensure("stmt0 is NULL", stmt0.get() != NULL); ensure_equal("sql::Connection differs", conn.get(), stmt0->getConnection()); int old_commit_mode = conn->getAutoCommit(); conn->setAutoCommit(true); ensure("Data not populated", true == populate_TX_test_table_PS(conn, database)); boost::scoped_ptr stmt1(conn->prepareStatement("SELECT COUNT(*) FROM test_function_tx")); boost::scoped_ptr rset1(stmt1->executeQuery()); ensure("res1 is NULL", rset1.get() != NULL); ensure_equal_int("res1 is empty", rset1->next(), true); count_full_before = rset1->getInt(1); ensure_equal_int("res1 has more rows ", rset1->next(), false); boost::scoped_ptr stmt2(conn->prepareStatement("DELETE FROM test_function_tx WHERE 1")); /* Let's delete and then rollback */ ensure_equal_int("Deleted less rows", stmt2->executeUpdate(), count_full_before); boost::scoped_ptr stmt3(conn->prepareStatement("SELECT COUNT(*) FROM test_function_tx")); boost::scoped_ptr rset2(stmt3->executeQuery()); ensure("res2 is NULL", rset2.get() != NULL); ensure_equal_int("res2 is empty", rset2->next(), true); ensure_equal_int("Table not empty after delete", rset2->getInt(1), 0); ensure_equal_int("res2 has more rows ", rset2->next(), false); /* In autocommit on, this is a no-op */ stmt1->getConnection()->rollback(); boost::scoped_ptr stmt4(conn->prepareStatement("SELECT COUNT(*) FROM test_function_tx")); boost::scoped_ptr rset3(stmt4->executeQuery()); ensure("res3 is NULL", rset3.get() != NULL); ensure_equal_int("res3 is empty", rset3->next(), true); ensure_equal_int("Rollback didn't work", rset3->getInt(1), 0); ensure_equal_int("res3 has more rows ", rset3->next(), false); ensure("Data not populated", true == populate_TX_test_table_PS(conn, database)); boost::scoped_ptr stmt5(conn->prepareStatement("DELETE FROM test_function_tx WHERE 1")); /* Let's delete and then rollback */ ensure_equal_int("Deleted less rows", stmt5->executeUpdate(), count_full_before); /* In autocommit on, this is a no-op */ stmt1->getConnection()->commit(); boost::scoped_ptr stmt6(conn->prepareStatement("SELECT COUNT(*) FROM test_function_tx")); boost::scoped_ptr rset4(stmt6->executeQuery()); ensure("res4 is NULL", rset4.get() != NULL); ensure_equal_int("res4 is empty", rset4->next(), true); ensure_equal_int("Rollback didn't work", rset4->getInt(1), 0); ensure_equal_int("res4 has more rows ", rset4->next(), false); conn->setAutoCommit(false); ensure("Data not populated", true == populate_TX_test_table_PS(conn, database)); boost::scoped_ptr stmt7(conn->prepareStatement("DELETE FROM test_function_tx WHERE 1")); /* Let's delete and then rollback */ ensure("Deleted less rows", stmt7->executeUpdate() == count_full_before); /* In autocommit iff, this is an op */ stmt1->getConnection()->rollback(); boost::scoped_ptr stmt8(conn->prepareStatement("SELECT COUNT(*) FROM test_function_tx")); boost::scoped_ptr rset5(stmt8->executeQuery()); ensure("res5 is NULL", rset5.get() != NULL); ensure_equal_int("res5 is empty", rset5->next(), true); ensure_equal_int("Rollback didn't work", rset5->getInt(1), 0); ensure_equal_int("res5 has more rows ", rset5->next(), false); boost::scoped_ptr stmt9(conn->prepareStatement("DROP TABLE test_function_tx")); stmt1->execute(); conn->setAutoCommit(old_commit_mode); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test multistatement off - send two queries in one call - PS version */ static void test_result_set_9(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { try { boost::scoped_ptr stmt1(conn->prepareStatement("SELECT COUNT(*) FROM test_function_tx; DELETE FROM test_function_tx")); ensure("ERR: Exception not thrown", false); } catch (sql::SQLException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test multiresults - SP with normal and prepared statement */ static void test_result_set_10(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt0(conn->createStatement()); ensure("stmt0 is NULL", stmt0.get() != NULL); stmt0->execute("USE " + database); #if 0 /* Doesn't work with libmysql - a limitation of the library, might work with mysqlnd if it lies under */ { /* Create procedure is not supported for preparing */ boost::scoped_ptr stmt1(conn->createStatement()); stmt1->execute("DROP PROCEDURE IF EXISTS CPP1"); stmt1->execute("CREATE PROCEDURE CPP1() SELECT 42"); boost::scoped_ptr stmt2(conn->prepareStatement("CALL CPP1()")); stmt2->execute(); boost::scoped_ptr rset1(stmt2->getResultSet()); ensure("res1 is NULL", rset1.get() != NULL); ensure_equal_int("res1 is empty", rset1->next(), true); eensure_equal_intsure("Wrong data", rset1->getInt(1), 42); ensure_equal_int("res1 has more rows ", rset1->next(), false); /* Here comes the status result set*/ boost::scoped_ptr rset2(stmt2->getResultSet()); ensure("res2 is not NULL", rset2.get() == NULL); /* drop procedure is not supported for preparing */ stmt1->execute("DROP PROCEDURE CPP1"); } { boost::scoped_ptr stmt1(conn->createStatement()); stmt1->execute("DROP PROCEDURE IF EXISTS CPP1"); stmt1->execute("CREATE PROCEDURE CPP1() SELECT 42"); stmt1->execute("CALL CPP1()"); boost::scoped_ptr rset1(stmt1->getResultSet()); ensure("res1 is NULL", rset1.get() != NULL); ensure_equal_int("res1 is empty", rset1->next(), true); ensure_equal_int("Wrong data", rset1->getInt(1), 42); ensure_equal_int("res1 has more rows ", rset1->next(), false); /* Here comes the status result set*/ boost::scoped_ptr rset2(stmt1->getResultSet()); ensure_equal_int("res2 is not NULL", rset2.get(), NULL); stmt1->execute("DROP PROCEDURE CPP1"); } #endif } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ getMetadata() */ static void test_result_set_11(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt1(conn->createStatement()); ensure("stmt1 is NULL", stmt1.get() != NULL); stmt1->setResultSetType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); ensure("Data not populated", true == populate_test_table(conn, database)); boost::scoped_ptr rset1(stmt1->executeQuery("SELECT * FROM test_function")); ensure("res1 is NULL", rset1.get() != NULL); ensure("res1 is empty", rset1->next() != false); stmt1->execute("set @old_charset_res=@@session.character_set_results"); stmt1->execute("set character_set_results=NULL"); sql::ResultSetMetaData * meta1 = rset1->getMetaData(); ensure("column name differs", !meta1->getColumnName(1).compare("a")); ensure("column name differs", !meta1->getColumnName(2).compare("b")); ensure("column name differs", !meta1->getColumnName(3).compare("c")); ensure("column name differs", !meta1->getColumnName(4).compare("d")); ensure("column name differs", !meta1->getColumnName(5).compare("e")); ensure_equal_int("bad case sensitivity", meta1->isCaseSensitive(1), false); ensure_equal_int("bad case sensitivity", meta1->isCaseSensitive(2), false); ensure_equal_int("bad case sensitivity", meta1->isCaseSensitive(3), false); ensure_equal_int("bad case sensitivity", meta1->isCaseSensitive(4), false); // ensure_equal_int("bad case sensitivity", meta1->isCaseSensitive(5), true); ensure_equal_int("bad case sensitivity", meta1->isCurrency(1), false); ensure_equal_int("bad case sensitivity", meta1->isCurrency(2), false); ensure_equal_int("bad case sensitivity", meta1->isCurrency(3), false); ensure_equal_int("bad case sensitivity", meta1->isCurrency(4), false); ensure_equal_int("bad case sensitivity", meta1->isCurrency(5), false); stmt1->execute("set character_set_results=@old_charset_res"); try { meta1->getColumnName(0); meta1->isCaseSensitive(0); meta1->isCurrency(0); ensure("Exception not correctly thrown", false); } catch (sql::SQLException &) { ensure("Exception correctly thrown", true); } try { meta1->getColumnName(100); meta1->isCaseSensitive(100); meta1->isCurrency(100); ensure("Exception not correctly thrown", false); } catch (sql::SQLException &) { ensure("Exception correctly thrown", true); } /* a integer unsigned not null, b integer, c integer default null, d char(10), e varchar(10) character set utf8 collate utf8_bin */ } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ #if 0 /* {{{ General test 0 */ static void test_general_0(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { sql::DatabaseMetaData * meta = conn->getMetaData(); boost::scoped_ptr rset(meta->getSchemata()); while (rset->next()) { boost::scoped_ptr rset2(meta->getSchemaObjects("", rset->getString("schema_name"))); while (rset2->next()) { rset2->getString("object_type").c_str(); rset2->getString("name").c_str(); rset2->getString("ddl").c_str(); } } } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ General test 1 */ static void test_general_1(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt(conn->createStatement()); stmt->execute("DROP TABLE IF EXISTS test.product"); stmt->execute("CREATE TABLE test.product(idproduct INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(80))"); conn->setAutoCommit(0); boost::scoped_ptr prepStmt(conn->prepareStatement("INSERT INTO test.product (idproduct, name) VALUES(?, ?)")); prepStmt->setInt(1, 1); prepStmt->setString(2, "The answer is 42"); prepStmt->executeUpdate(); boost::scoped_ptr rset1(stmt->executeQuery("SELECT * FROM test.product")); ensure_equal_int("Empty result set", rset1->next(), true); ensure("Wrong data", !rset1->getString(2).compare("The answer is 42")); ensure("Wrong data", !rset1->getString("name").compare("The answer is 42")); ensure_equal_int("Non-Empty result set", rset1->next(), false); conn->rollback(); boost::scoped_ptr rset2(stmt->executeQuery("SELECT * FROM test.product")); ensure_equal_int("Non-Empty result set", rset1->next(), false); stmt->execute("DROP TABLE IF EXISTS test.product"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ #endif /* {{{ */ static void test_prep_statement_0(boost::scoped_ptr & conn) { ENTER_FUNCTION(); try { try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT 1")); stmt->execute(); boost::scoped_ptr rset1(stmt->getResultSet()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?")); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } /* Bind but don't execute. There should be no leak */ try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?, ?, ?")); stmt->setInt(1, 1); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } /* Bind two different types for the same column. There should be no leak */ try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?")); stmt->setString(1, "Hello MySQL"); stmt->setInt(1, 42); stmt->execute(); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } /* Execute without fetching the result set. The connector should clean the wire */ try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?, ?, ?, ?")); stmt->setInt(1, 1); stmt->setDouble(2, 2.25); stmt->setString(3, "а—аДб€аАбб‚аИ аœySQL"); stmt->setDateTime(4, "2006-11-10 16:17:18"); stmt->execute(); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } #if 0 /* Bind one parameter less than needed - NULL should be sent to the server . Check also multibyte fetching. */ try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ? as \"а—аДб€аАаВаЕаЙ_аœySQL\" , ?, ?")); stmt->setInt(3, 42); stmt->setString(1, "а—аДб€аАаВаЕаЙ аœySQL! аšаАаК баИ?"); stmt->execute(); boost::scoped_ptr rset(stmt->getResultSet()); ensure("No result set", rset.get() != NULL); ensure("Result set is empty", rset->next() != false); ensure("Incorrect value for col 1", rset->getInt(2) == 0 && true == rset->wasNull()); ensure("Incorrect value for col 0", !rset->getString(1).compare("а—аДб€аАаВаЕаЙ аœySQL! аšаАаК баИ?") && false == rset->wasNull()); ensure("Incorrect value for col 0", !rset->getString("а—аДб€аАаВаЕаЙ_аœySQL").compare("а—аДб€аАаВаЕаЙ аœySQL! аšаАаК баИ?") && false == rset->wasNull()); ensure("Incorrect value for col 2", rset->getInt(3) == 42 && false == rset->wasNull()); ensure("Incorrect value for col 2", !rset->getString(3).compare("42") && false == rset->wasNull()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } #endif /* try double ::execute() */ try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?")); stmt->setString(1, "Hello World"); for (int i = 0; i < 100; ++i) { boost::scoped_ptr rset(stmt->executeQuery()); } } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } /* Test clearParameters() */ { try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?")); stmt->setInt(1, 13); boost::scoped_ptr rs(stmt->executeQuery()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?")); stmt->setInt(1, 13); stmt->clearParameters(); boost::scoped_ptr rs(stmt->executeQuery()); ensure("Exception not thrown", false); } catch (sql::SQLException &) {} } /* try clearParameters() call */ { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?, ?, ?, NULL")); try { stmt->setInt(3, 42); stmt->setString(1, "Hello MYSQL"); stmt->setDouble(2, 1.25); boost::scoped_ptr rset(stmt->executeQuery()); ensure("No result set", rset.get() != NULL); ensure("Result set is empty", rset->next() != false); ensure("Non empty string returned for NULL", rset->getString(4).length() == 0); ensure("wasNull() not properly set for NULL", rset->wasNull()); ensure("isNull() is wrong", rset->isNull(4)); ensure("Incorrect value for col 4", !rset->getString(4).compare("") && true == rset->wasNull()); ensure("Incorrect value for col 0", !rset->getString(1).compare("Hello MYSQL") && false == rset->wasNull()); ensure("Incorrect value for col 2", rset->getInt(3) == 42 && false == rset->wasNull()); // ensure("Incorrect value for col 2", !rset->getString(3).compare("42") && false == rset->wasNull()); ensure("Incorrect value for col 3", rset->getDouble(2) == 1.25 && false == rset->wasNull()); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } } try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT ?")); stmt->setInt(1, 1); stmt->execute(); boost::scoped_ptr rset(stmt->getResultSet()); } catch (sql::SQLException &) { printf("\n# ERR: Caught sql::SQLException at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test simple update statement against statement object */ static void test_prep_statement_1(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, const std::string & database) { ENTER_FUNCTION(); try { boost::scoped_ptr stmt0(conn->prepareStatement("SELECT 1, 2, 3")); ensure("stmt0 is NULL", stmt0.get() != NULL); ensure("Data not populated", true == populate_test_table_PS(conn, database)); boost::scoped_ptr stmt1(conn->prepareStatement("SELECT * FROM test_function")); ensure("stmt1 is NULL", stmt1.get() != NULL); if (false == stmt1->execute()) { ensure("False returned for SELECT", false); } boost::scoped_ptr rset(stmt1->getResultSet()); /* Clean */ boost::scoped_ptr stmt2(conn2->createStatement()); ensure("stmt2 is NULL", stmt2.get() != NULL); stmt2->execute("USE " + database); boost::scoped_ptr stmt3(conn2->prepareStatement("DROP TABLE test_function")); ensure("stmt3 is NULL", stmt3.get() != NULL); stmt3->execute(); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test simple update statement against statement object */ static void test_prep_statement_2(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { populate_test_table_PS_integers(conn, database); try { boost::scoped_ptr stmt(conn->prepareStatement("SELECT '1")); ensure("ERR: Exception not thrown", false); } catch (sql::SQLException &) {} /* USE still cannot be prepared */ try { boost::scoped_ptr stmt(conn->prepareStatement("USE " + database)); ensure("ERR: Exception not thrown", false); } catch (sql::SQLException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Test simple update statement against statement object */ static void test_prep_statement_3(boost::scoped_ptr & conn, boost::scoped_ptr & conn2, const std::string & database) { ENTER_FUNCTION(); try { int64_t r1_c1 = L64(2147483646), r1_c2 = L64(2147483650), r1_c3 = L64(9223372036854775806), r2_c1 = L64(2147483647), r2_c2 = L64(2147483649), r2_c3 = L64(9223372036854775807); uint64_t r1_c4 = UL64(9223372036854775810), r2_c4 = UL64(18446744073709551615); ensure("Data not populated", true == populate_test_table_PS_integers(conn, database)); boost::scoped_ptr stmt1(conn->prepareStatement("INSERT INTO test_function_int (i, i_uns, b, b_uns) VALUES(?,?,?,?)")); ensure("stmt0 is NULL", stmt1.get() != NULL); stmt1->clearParameters(); stmt1->setInt(1, static_cast(r1_c1)); stmt1->setInt64(2, r1_c2); stmt1->setInt64(3, r1_c3); stmt1->setUInt64(4, r1_c4); ensure("True returned for INSERT", false == stmt1->execute()); stmt1->clearParameters(); stmt1->setInt(1, static_cast(r2_c1)); stmt1->setInt64(2, r2_c2); stmt1->setInt64(3, r2_c3); stmt1->setUInt64(4, r2_c4); ensure("True returned for INSERT", false == stmt1->execute()); { boost::scoped_ptr stmt2(conn->prepareStatement("SELECT i, i_uns, b, b_uns FROM test_function_int")); ensure("stmt1 is NULL", stmt2.get() != NULL); ensure("False returned for SELECT", stmt2->execute()); boost::scoped_ptr rset(stmt2->getResultSet()); ensure("No first line", rset->next()); ensure_equal_int64("Different data", rset->getInt("i"), r1_c1); ensure_equal_int64("Different data", rset->getInt(1), r1_c1); ensure_equal_int64("Different data", rset->getInt64("i_uns"), r1_c2); ensure_equal_int64("Different data", rset->getInt64(2), r1_c2); ensure_equal_int64("Different data", rset->getInt64("b"), r1_c3); ensure_equal_int64("Different data", rset->getInt64(3), r1_c3); ensure_equal_uint64("Different data", rset->getUInt64("b_uns"), r1_c4); ensure_equal_uint64("Different data", rset->getUInt64(4), r1_c4); ensure("No second line", rset->next()); ensure_equal_int64("Different data", rset->getInt("i"), r2_c1); ensure_equal_int64("Different data", rset->getInt(1), r2_c1); ensure_equal_int64("Different data", rset->getInt64("i_uns"), r2_c2); ensure_equal_int64("Different data", rset->getInt64(2), r2_c2); ensure_equal_int64("Different data", rset->getInt64("b"), r2_c3); ensure_equal_int64("Different data", rset->getInt64(3), r2_c3); ensure_equal_uint64("Different data", rset->getUInt64("b_uns"), r2_c4); ensure_equal_uint64("Different data", rset->getUInt64(4), r2_c4); ensure("Too many lines", rset->next() == false); } { boost::scoped_ptr stmt2(conn->createStatement()); ensure("stmt1 is NULL", stmt2.get() != NULL); ensure("False returned for SELECT", stmt2->execute("SELECT i, i_uns, b, b_uns FROM test_function_int")); boost::scoped_ptr rset(stmt2->getResultSet()); ensure("No first line", rset->next()); ensure_equal_int64("Different data", rset->getInt("i"), r1_c1); ensure_equal_int64("Different data", rset->getInt(1), r1_c1); ensure_equal_int64("Different data", rset->getInt64("i_uns"), r1_c2); ensure_equal_int64("Different data", rset->getInt64(2), r1_c2); ensure_equal_int64("Different data", rset->getInt64("b"), r1_c3); ensure_equal_int64("Different data", rset->getInt64(3), r1_c3); ensure_equal_uint64("Different data", rset->getUInt64("b_uns"), r1_c4); ensure_equal_uint64("Different data", rset->getUInt64(4), r1_c4); ensure("No second line", rset->next()); ensure_equal_int64("Different data", rset->getInt("i"), r2_c1); ensure_equal_int64("Different data", rset->getInt(1), r2_c1); ensure_equal_int64("Different data", rset->getInt64("i_uns"), r2_c2); ensure_equal_int64("Different data", rset->getInt64(2), r2_c2); ensure_equal_int64("Different data", rset->getInt64("b"), r2_c3); ensure_equal_int64("Different data", rset->getInt64(3), r2_c3); ensure_equal_uint64("Different data", rset->getUInt64("b_uns"), r2_c4); ensure_equal_uint64("Different data", rset->getUInt64(4), r2_c4); ensure("Too many lines", rset->next() == false); } /* Clean */ boost::scoped_ptr stmt4(conn2->createStatement()); ensure("stmt4 is NULL", stmt4.get() != NULL); stmt4->execute("USE " + database); boost::scoped_ptr stmt5(conn2->prepareStatement("DROP TABLE test_function_int")); ensure("stmt5 is NULL", stmt5.get() != NULL); stmt5->execute(); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ Tests blob with PS */ static void test_prep_statement_blob(boost::scoped_ptr & conn, std::string database) { ENTER_FUNCTION(); try { populate_blob_table(conn, database); /* USE still cannot be prepared */ boost::scoped_ptr use_stmt(conn->createStatement()); use_stmt->execute("USE " + database); boost::scoped_ptr stmt(conn->prepareStatement("INSERT INTO test_blob VALUES(?)")); std::string value("A\0B", sizeof("A\0B") - 1); std::istringstream tmp_blob(value); stmt->setBlob(1, &tmp_blob); stmt->execute(); boost::scoped_ptr stmt2(conn->createStatement()); stmt2->execute("SELECT * FROM test_blob"); boost::scoped_ptr rset2(stmt2->getResultSet()); ensure("res2 is NULL", rset2.get() != NULL); ensure_equal_int("res2 is empty", rset2->next(), true); ensure_equal_str("Wrong data", rset2->getString(1), value); boost::scoped_ptr blob(rset2->getBlob(1)); std::string::iterator it; for (it = value.begin() ; it < value.end(); ++it) { if ((blob->rdstate() & std::istream::eofbit)) { ensure("premature eof", 0); } char ch; blob->get(ch); if ((blob->rdstate() & std::istream::badbit) != 0) { ensure("badbit set", false); } else if ((blob->rdstate() & std::istream::failbit) != 0) { if ((blob->rdstate() & std::istream::eofbit) == 0) { ensure("failbit set without eof being set", false); } } if (*it != ch) { ensure("character differ", false); } } ensure("BLOB doesn't match, has more data", (blob->rdstate() & std::istream::eofbit) == 0); ensure_equal_int("res2 has more rows ", rset2->next(), false); stmt2->execute("DELETE FROM test_blob WHERE 1"); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ #define DEBUG_TABLE_PRIVS 0 /* {{{ Tests getTablePrivileges */ /* TODO - broken static void test_get_table_privileges_1(const std::string & host, const std::string & user, const std::string & pass) { ENTER_FUNCTION(); int a; char buf[20] = "p"; snprintf(buf+1, sizeof(buf) - 2, "%u", ((unsigned int) &a) % 10000); std::string plain_user(std::string("tu").append(buf)); std::string plain_user_w_host(std::string("").append(plain_user). #if A0 append("@%")); #else append("@localhost")); #endif std::string plain_user_db(std::string("test_someuser_db").append(buf)); std::string plain_user_table("table1"); std::string create_db(std::string("CREATE DATABASE `").append(plain_user_db).append("`")); std::string create_table(std::string("CREATE TABLE `").append(plain_user_db).append("`.`").append(plain_user_table).append("`(a int)")); std::string create_user(std::string("CREATE USER ").append(plain_user_w_host).append(" IDENTIFIED BY 'pass'")); std::string grant_user1(std::string("GRANT ALL ON `").append(plain_user_db).append("`.`"). append(plain_user_table).append("` TO ").append(plain_user_w_host)); std::string grant_user2(std::string("GRANT DELETE ON `").append(plain_user_db).append("`.`"). append(plain_user_table).append("` TO ").append(plain_user_w_host)); std::string grant_user3(std::string("GRANT SELECT, INSERT ON `").append(plain_user_db).append("`.`"). append(plain_user_table).append("` TO ").append(plain_user_w_host)); std::string drop_user(std::string("DROP USER ").append(plain_user_w_host)); std::string drop_db(std::string("DROP DATABASE `").append(plain_user_db).append("`")); std::list< std::string > grantsList; grantsList.push_back(grant_user1); grantsList.push_back(grant_user2); grantsList.push_back(grant_user3); std::list< std::list< std::string > > expectedPrivilegesList; std::list< std::string > expectedPrivileges1; expectedPrivileges1.push_back(std::string("ALTER")); expectedPrivileges1.push_back(std::string("DELETE")); expectedPrivileges1.push_back(std::string("DROP")); expectedPrivileges1.push_back(std::string("INDEX")); expectedPrivileges1.push_back(std::string("INSERT")); expectedPrivileges1.push_back(std::string("LOCK TABLES")); expectedPrivileges1.push_back(std::string("SELECT")); expectedPrivileges1.push_back(std::string("UPDATE")); expectedPrivilegesList.push_back(expectedPrivileges1); std::list< std::string > expectedPrivileges2; expectedPrivileges2.push_back(std::string("DELETE")); expectedPrivilegesList.push_back(expectedPrivileges2); std::list< std::string > expectedPrivileges3; expectedPrivileges3.push_back(std::string("SELECT")); expectedPrivileges3.push_back(std::string("INSERT")); expectedPrivilegesList.push_back(expectedPrivileges3); std::list< std::string >::const_iterator grantsList_it = grantsList.begin(); std::list< std::list< std::string > >::const_iterator expectedPrivilegesList_it = expectedPrivilegesList.begin(); try { boost::scoped_ptr root_conn(get_connection(host, user, pass)); boost::scoped_ptr root_stmt(root_conn->createStatement()); #if DEBUG_TABLE_PRIVS std::cout << std::endl << plain_user_w_host << std::endl; #endif for (; grantsList_it != grantsList.end(); ++grantsList_it, ++expectedPrivilegesList_it) { root_stmt->execute(create_db); root_stmt->execute(create_table); root_stmt->execute(create_user); root_stmt->execute(*grantsList_it); Put it in a block, so the connection will be closed before we start dropping the user and the table try { boost::scoped_ptr user_conn(get_connection(host, plain_user, "pass")); boost::scoped_ptr user_conn_meta(user_conn->getMetaData()); boost::scoped_ptr res(user_conn_meta->getTablePrivileges("", "%", "%")); #if DEBUG_TABLE_PRIVS printf("\tTABLE_CAT\tTABLE_SCHEM\tTABLE_NAME\tGRANTOR\tGRANTEE\tPRIVILEGE\tIS_GRANTABLE\n"); #endif unsigned int found = 0, rows = 0; while (res->next()) { #if DEBUG_TABLE_PRIVS for (int i = 1; i < 8; ++i) printf("\t[%s]", res->getString(i).c_str()); printf("\n"); #endif std::list< std::string >::const_iterator it = expectedPrivilegesList_it->begin(); for (;it != expectedPrivilegesList_it->end(); ++it) { if (!it->compare(res->getString("PRIVILEGE"))) { ++found; } // ensure_equal("Bad TABLE_CAT", std::string(""), res->getString("TABLE_CAT")); // ensure_equal("Bad TABLE_SCHEM", plain_user_db, res->getString("TABLE_SCHEM")); // ensure_equal("Bad TABLE_NAME", plain_user_table, res->getString("TABLE_NAME")); // ensure_equal("Bad GRANTEE", plain_user_w_host, res->getString("GRANTEE")); } ++rows; } #if DEBUG_TABLE_PRIVS std::cout << "Found:" << found << " Rows:" << rows << "\n"; #endif ensure_equal_int("Bad PRIVILEGE data(1)", found, expectedPrivilegesList_it->size()); ensure_equal_int("Bad PRIVILEGE data(2)", found, rows); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } root_stmt->execute(drop_user); root_stmt->execute(drop_db); } } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } */ /* {{{ Invoke as many "not implemented" methods as possible for better code coverage (and to make sure we keep CHANGES current) */ static void test_not_implemented_connection(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("bar"); int int_array[] = {1, 2, 3}; sql::SQLString string_array[] = {"a", "b", "c"}; try { try { ++total_tests; conn->isReadOnly(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // prepareStatement(const std::string& /* sql */, int /* autoGeneratedKeys */) try { ++total_tests; conn->prepareStatement(bar, 1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // prepareStatement(const std::string& /* sql */, int /* columnIndexes */ []) try { ++total_tests; conn->prepareStatement(bar, int_array); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // prepareStatement(const std::string& /* sql */, int /* resultSetType */, int /* try { ++total_tests; conn->prepareStatement(bar, 1, 1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // prepareStatement(const std::string& /* sql */, int /* resultSetType */, int /* resultSetConcurrency */, int /* resultSetHoldability */) try { ++total_tests; conn->prepareStatement(bar, 1, 1, 1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // prepareStatement(const std::string& /* sql */, std::string /* columnNames*/ []) try { ++total_tests; conn->prepareStatement(bar, string_array); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setHoldability(int /* holdability */) try { ++total_tests; conn->setHoldability(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setReadOnly(bool /* readOnly */) try { ++total_tests; conn->setReadOnly(true); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setSavepoint() try { ++total_tests; conn->setSavepoint(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_statement(boost::scoped_ptr & conn, const std::string & database) { ENTER_FUNCTION(); std::string bar("foo"); boost::scoped_ptr stmt(conn->createStatement()); stmt->execute("USE " + database); try { // cancel() try { ++total_tests; stmt->cancel(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchSize() try { ++total_tests; stmt->getFetchSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setFetchSize(unsigned int) try { ++total_tests; stmt->setFetchSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getMaxFieldSize() try { ++total_tests; stmt->getMaxFieldSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getMaxRows() try { ++total_tests; stmt->getMaxRows(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setCursorName(const std::string &) try { ++total_tests; stmt->setCursorName(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setEscapeProcessing(bool) try { ++total_tests; stmt->setEscapeProcessing(true); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setMaxFieldSize(unsigned int) try { ++total_tests; stmt->setMaxFieldSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setMaxRows(unsigned int) try { ++total_tests; stmt->setMaxRows(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_conn_meta(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("foo"); sql::DatabaseMetaData * conn_meta = conn->getMetaData(); try { // getURL() try { ++total_tests; conn_meta->getURL(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // locatorsUpdateCopy() try { ++total_tests; conn_meta->locatorsUpdateCopy(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // supportsIntegrityEnhancementFacility() try { ++total_tests; conn_meta->supportsIntegrityEnhancementFacility(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // supportsResultSetConcurrency(int /* type */, int /* concurrency */) try { ++total_tests; conn_meta->supportsResultSetConcurrency(1, 2); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_ps(boost::scoped_ptr & conn, const std::string & database) { ENTER_FUNCTION(); std::string bar("jedervernunft"); boost::scoped_ptr stmt(conn->createStatement()); stmt->execute("USE " + database); boost::scoped_ptr ps1(conn->prepareStatement("SELECT 1")); boost::scoped_ptr ps2(conn->prepareStatement("SELECT ?")); ps2->setInt(1, 2); try { // execute(const std::string&) try { ++total_tests; ps1->execute(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // executeQuery(const std::string&) try { ++total_tests; ps1->executeQuery(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // executeUpdate(const std::string&) try { ++total_tests; ps1->executeUpdate(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // cancel() try { ++total_tests; ps2->cancel(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchSize() try { ++total_tests; ps2->getFetchSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setFetchSize(unsigned int) try { ++total_tests; ps2->setFetchSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setQueryTimeout(unsigned int) try { ++total_tests; ps2->setQueryTimeout(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getMaxFieldSize() try { ++total_tests; ps2->getMaxFieldSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getMaxRows() try { ++total_tests; ps2->getMaxRows(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getQueryTimeout() try { ++total_tests; ps2->getQueryTimeout(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getUpdateCount() try { ++total_tests; ps2->getUpdateCount(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setCursorName(const std::string &) try { ++total_tests; ps2->setCursorName(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setEscapeProcessing(bool) try { ++total_tests; ps2->setEscapeProcessing(true); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setMaxFieldSize(unsigned int) try { ++total_tests; ps2->setMaxFieldSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setMaxRows(unsigned int) try { ++total_tests; ps2->setMaxRows(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_resultset(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("foo"); boost::scoped_ptr stmt(conn->createStatement()); boost::scoped_ptr res(stmt->executeQuery("SELECT 1 AS 'a'")); try { // cancelRowUpdates() try { ++total_tests; res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getConcurrency() try { ++total_tests; res->getConcurrency(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getCursorName() try { ++total_tests; res->getCursorName(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchDirection() try { ++total_tests; res->getFetchDirection(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchSize() try { ++total_tests; res->getFetchSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getHoldability() try { ++total_tests; res->getHoldability(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getRowId(unsigned int) try { ++total_tests; res->getRowId(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getRowId(const std::string &) try { ++total_tests; res->getRowId(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // insertRow() try { ++total_tests; res->insertRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // moveToCurrentRow() try { ++total_tests; res->moveToCurrentRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // moveToInsertRow() try { ++total_tests; res->moveToInsertRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // refreshRow() try { ++total_tests; res->refreshRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowDeleted() try { ++total_tests; res->rowDeleted(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowInserted() try { ++total_tests; res->rowInserted(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowUpdated() try { ++total_tests; res->rowUpdated(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setFetchSize(size_t /* rows */) try { ++total_tests; res->setFetchSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_ps_resultset(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("foo"); boost::scoped_ptr stmt(conn->prepareStatement("SELECT 1 AS 'a'")); boost::scoped_ptr res(stmt->executeQuery()); try { // cancelRowUpdates() try { ++total_tests; res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getConcurrency() try { ++total_tests; res->getConcurrency(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getCursorName() try { ++total_tests; res->getCursorName(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchDirection() try { ++total_tests; res->getFetchDirection(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchSize() try { ++total_tests; res->getFetchSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getHoldability() try { ++total_tests; res->getHoldability(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getRowId(unsigned int) try { ++total_tests; res->getRowId(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getRowId(const std::string &) try { ++total_tests; res->getRowId(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // insertRow() try { ++total_tests; res->insertRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // moveToCurrentRow() try { ++total_tests; res->moveToCurrentRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // moveToInsertRow() try { ++total_tests; res->moveToInsertRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // refreshRow() try { ++total_tests; res->refreshRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowDeleted() try { ++total_tests; res->rowDeleted(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowInserted() try { ++total_tests; res->rowInserted(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowUpdated() try { ++total_tests; res->rowUpdated(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setFetchSize(size_t /* rows */) try { ++total_tests; res->setFetchSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_cs_resultset(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("foo"); sql::DatabaseMetaData * conn_meta = conn->getMetaData(); boost::scoped_ptr res(conn_meta->getSchemaObjectTypes()); try { // cancelRowUpdates() try { ++total_tests; res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getConcurrency() try { ++total_tests; res->getConcurrency(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getCursorName() try { ++total_tests; res->getCursorName(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchDirection() try { ++total_tests; res->getFetchDirection(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getFetchSize() try { ++total_tests; res->getFetchSize(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getHoldability() try { ++total_tests; res->getHoldability(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getRowId(unsigned int) try { ++total_tests; res->getRowId(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getRowId(const std::string &) try { ++total_tests; res->getRowId(bar); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // insertRow() try { ++total_tests; res->insertRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // moveToCurrentRow() try { ++total_tests; res->moveToCurrentRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // moveToInsertRow() try { ++total_tests; res->moveToInsertRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // refreshRow() try { ++total_tests; res->refreshRow(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowDeleted() try { ++total_tests; res->rowDeleted(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowInserted() try { ++total_tests; res->rowInserted(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // rowUpdated() try { ++total_tests; res->rowUpdated(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // setFetchSize(size_t /* rows */) try { ++total_tests; res->setFetchSize(1); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_rs_meta(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("foo"); boost::scoped_ptr stmt(conn->createStatement()); boost::scoped_ptr res(stmt->executeQuery("SELECT 1 AS 'a'")); try { try { ++total_tests; res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ static void test_not_implemented_cs_rs_meta(boost::scoped_ptr & conn) { ENTER_FUNCTION(); std::string bar("foo"); sql::DatabaseMetaData * conn_meta = conn->getMetaData(); boost::scoped_ptr res(conn_meta->getSchemaObjectTypes()); sql::ResultSetMetaData * meta = res->getMetaData(); try { // getColumnDisplaySize(unsigned int columnIndex) try { ++total_tests; meta->getColumnDisplaySize(1); res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getPrecision(unsigned int columnIndex) try { ++total_tests; meta->getPrecision(1); res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} // getScale(unsigned int columnIndex) try { ++total_tests; meta->getScale(1); res->cancelRowUpdates(); ensure("ERR: Exception not thrown", false); } catch (sql::MethodNotImplementedException &) {} } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); ++total_errors; } catch (...) { printf("\n# ERR: Caught unknown exception at %s::%d\n", CPPCONN_FUNC, __LINE__); printf("# "); ++total_errors; } LEAVE_FUNCTION(); } /* }}} */ /* {{{ */ int run_tests(int argc, const char **argv) { printf("1..%d\n#\n", loops); boost::scoped_ptr conn, conn2; int last_error_total = 0; int i; const std::string user(argc >=3? argv[2]:"root"); const std::string pass(argc >=4? argv[3]:"root"); const std::string database(argc >=5? argv[4]:USED_DATABASE); for (i = 0 ; i < loops; ++i) { last_error_total = total_errors; printf("# 0 - total_errors %d, last_error_total = %d\n", total_errors, last_error_total); const std::string host(argc >=2? argv[1]:"tcp://127.0.0.1"); std::cout << "# Host=" << host << std::endl; std::cout << "# User=" << user << std::endl; std::string connect_method("unknown"); if (host.find("tcp://", (size_t)0) != std::string::npos) { connect_method = "tcp"; } else if (host.find("unix://", (size_t)0) != std::string::npos) { connect_method = "socket"; } printf("#--------------- %d -----------------\n", i + 1); printf("# "); try { conn.reset(get_connection(host, user, pass)); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("not ok\n"); return 1; } /* XXX : Doing upcast, not the best thing, but tests getMySQLVariable */ // ensure("Testing getSessionVariable", // 0 == ((sql::mysql::MySQL_Connection *) conn)->getSessionVariable("version").compare( // mysql_get_server_info(((sql::mysql::MySQL_Connection *) conn)->getMySQLHandle()) // ) // ); // printf("\n"); // printf("# Server %s\n", ((sql::mysql::MySQL_Connection *) conn)->getSessionVariable("version").c_str()); // printf("# "); try { boost::scoped_ptr stmt(conn->createStatement()); stmt->execute("SHOW ENGINES"); { boost::scoped_ptr rset(stmt->getResultSet()); int found = 0; while (rset->next()) { if (rset->getString("Engine") == "InnoDB" && (rset->getString("Support") == "YES" || rset->getString("Support") == "DEFAULT")) { found = 1; break; } } if (found == 0) { printf("\n#ERR: InnoDB Storage engine not available or disabled\n"); printf("not ok\n"); return 1; } } stmt->execute("USE " + database); } catch (sql::SQLException &e) { printf("\n# ERR: Caught sql::SQLException at %s::%d [%s] (%d/%s)\n", CPPCONN_FUNC, __LINE__, e.what(), e.getErrorCode(), e.getSQLStateCStr()); printf("# "); return 1; } conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_connection_0(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_connection_1(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_connection_2(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_connection_3(conn, user); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_autocommit(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_statement_0(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_1(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_2(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_3(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_4(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_5(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_6(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_7(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_8(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_9(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_statement_10(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_0(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_1(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_2(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_3(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_4(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_5(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_6(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_7(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_8(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_9(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_10(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_result_set_11(conn, database); conn.reset(NULL); #if 0 test_general_0(conn); delete conn; test_general_1(conn); delete conn; #endif conn.reset(get_connection(host, user, pass)); test_prep_statement_0(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_prep_statement_1(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); test_prep_statement_2(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); conn2.reset(get_connection(host, user, pass)); test_prep_statement_3(conn, conn2, database); conn.reset(NULL); conn2.reset(NULL); conn.reset(get_connection(host, user, pass)); test_prep_statement_blob(conn, database); conn.reset(NULL); // test_get_table_privileges_1(host, user, pass); conn.reset(get_connection(host, user, pass)); test_not_implemented_connection(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_statement(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_conn_meta(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_ps(conn, database); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_resultset(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_ps_resultset(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_cs_resultset(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_rs_meta(conn); conn.reset(NULL); conn.reset(get_connection(host, user, pass)); test_not_implemented_cs_rs_meta(conn); conn.reset(NULL); printf("\n#--------------- %d -----------------\n", i + 1); if ((total_errors - last_error_total) == 0) { printf("ok %d - %s_%s_loop%d\n", i + 1, TEST_COMMON_TAP_NAME, connect_method.c_str(), i + 1); } else { printf("not ok %d - %s_%s_loop%d\n", i + 1, TEST_COMMON_TAP_NAME, connect_method.c_str(), i + 1); } } printf("\n# Loops=%2d Tests= %4d Failures= %3d \n", loops, total_tests, total_errors); return 0; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mysql-connector-c++-1.1.7/test/unit/CMakeLists.txt000644 015771 000012 00000007606 12645244437 022473 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # IF(WIN32) LINK_DIRECTORIES(${MYSQL_DIR}/lib/$(ConfigurationName)) LINK_DIRECTORIES(../framework/$(ConfigurationName)) SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn test_framework) SET(MY_TARGET_LINK_LIBRARIES_STATIC_CPPLIB mysqlcppconn-static test_framework) # ADD_DEFINITIONS("-D_SECURE_SCL") ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") FIND_LIBRARY(MYSQLCPPCONN_DYNLOAD_MYSQL_LIB NAMES libmysql PATHS ${MYSQL_LIB_DIR} ${MYSQL_LIB_DIR}/lib/${libsuffixDist} ${MYSQL_LIB_DIR}/lib #mysqlclient may be in lib for some c/c distros ${MYSQL_LIB_DIR}/libmysql/${libsuffixBuild} ${MYSQL_LIB_DIR}/client/${libsuffixBuild} $ENV{MYSQL_LIB_DIR} $ENV{MYSQL_LIB_DIR}/lib/${libsuffixDist} $ENV{MYSQL_LIB_DIR}/lib #mysqlclient may be in lib for some c/c distros $ENV{MYSQL_LIB_DIR}/libmysql/${libsuffixBuild} $ENV{MYSQL_LIB_DIR}/client/${libsuffixBuild} $ENV{MYSQL_DIR}/lib/${libsuffixDist} $ENV{MYSQL_DIR}/lib #mysqlclient may be in lib for some c/c distros $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} $ENV{MYSQL_DIR}/client/${libsuffixBuild} $ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist} $ENV{ProgramFiles}/MySQL/*/lib $ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist} $ENV{SystemDrive}/MySQL/*/lib NO_DEFAULT_PATH ) ELSEIF(NOT WIN32) SET(MY_TARGET_LINK_LIBRARIES mysqlcppconn test_framework) FIND_LIBRARY(MYSQLCPPCONN_DYNLOAD_MYSQL_LIB NAMES libmysqlclient_r.so libmysqlclient.so PATHS ${MYSQL_LIB_DIR} ${MYSQL_LIB_DIR}/libmysql_r/.libs ${MYSQL_LIB_DIR}/lib ${MYSQL_LIB_DIR}/lib/mysql $ENV{MYSQL_LIB_DIR} $ENV{MYSQL_LIB_DIR}/libmysql_r/.libs $ENV{MYSQL_LIB_DIR}/lib $ENV{MYSQL_LIB_DIR}/lib/mysql $ENV{MYSQL_DIR}/libmysql_r/.libs $ENV{MYSQL_DIR}/lib $ENV{MYSQL_DIR}/lib/mysql ${MYSQL_CLIB_DIR} ${MYSQL_CLIB_DIR}/libmysql_r/.libs ${MYSQL_CLIB_DIR}/lib ${MYSQL_CLIB_DIR}/lib/mysql /usr/lib/mysql /usr/local/lib/mysql /usr/local/mysql/lib /usr/local/mysql/lib/mysql /opt/mysql/mysql/lib /opt/mysql/mysql/lib/mysql NO_DEFAULT_PATH ) ENDIF(WIN32) IF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) SET(MY_GCOV_LINK_LIBRARIES gcov) ENDIF(CMAKE_COMPILER_IS_GNUCC AND MYSQLCPPCONN_GCOV_ENABLE) ADD_DEFINITIONS("-DDYNLOAD_MYSQL_LIB=\"${MYSQLCPPCONN_DYNLOAD_MYSQL_LIB}\"") MESSAGE(STATUS "MySQL dynamic load test library: ${MYSQLCPPCONN_DYNLOAD_MYSQL_LIB}") IF(MYSQLCPPCONN_TEST_NOT_IMPLEMENTED) ADD_DEFINITIONS("-DINCLUDE_NOT_IMPLEMENTED_METHODS=1") ENDIF(MYSQLCPPCONN_TEST_NOT_IMPLEMENTED) MESSAGE(STATUS "Configuring unit tests") ADD_SUBDIRECTORY(example/) ADD_SUBDIRECTORY(classes/) ADD_SUBDIRECTORY(performance/) ADD_SUBDIRECTORY(bugs/) # Copy&Paste template: change directory name and uncomment # ADD_SUBDIRECTORY(template_bug_group) ADD_SUBDIRECTORY(template_bug_group) mysql-connector-c++-1.1.7/test/unit/README000644 015771 000012 00000014422 12645244437 020605 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPL as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ INTRODUCTION This is the best place for regression tests. This is where you should add a test when you fix a bug in the Connector. For historical reason there are three distinct sets of tests for the driver: tests/CJUnitTests/ <-- ported JDBC compliance/conformance tests tests/unit/ <-- primarily regression testing tests/static_test* <-- unclassified API tests, don't add code any more! The first two sets of test are using the same unit testing framework. All new tests of any kind (compliance, conformance, regression, ...), shall be written using the unit testing framework contained in the source of the MySQL Connector/C++. If you work for MySQL Support or you would like to help us with a full-featured bug report including a test case, here is what you need to do. HOW TO RUN A REGRESSION TEST 1) Compile the driver which compiles the tests as well See the README in the root directory of the source distribution for help. Tests are build together with the driver. 2) Invoke a test When running a test binary you must pass connection parameters to it. There are no defaults currently. The syntax is: example_program tcp://[:] [username] [password] [database] For example, use: > test/unit/example/example tcp://127.0.0.1 root root test # example_test_class 1..5 ok 1 - test_hello_world1 not ok 2 - test_hello_world2 ok 3 - test_assert_equals not ok 4 - test_assert_equals_fail ok 5 - test_assert_message FAILED tests 2, 4 Failed 2/5, 60.00% okay (Connects to MySQL using TCP/IP on 127.0.0.1:3306 using user "root" with the password "root" and selects the database "test") 3) Verbose? Yes, its there. Try something like: > test/unit/example/example --verbose tcp://127.0.0.1 root root test HOW TO WRITE A REGRESSION TEST 1) Identify a proper group, a proper directory for your test If there is a suitable directory for adding a new test proceed with step 2)! If there is no suitable directory, you need to create one by copying the directory template_bug_group/. For example, use: [# cd test/unit/ - this is where this README is :-)] # cp -R template_bug_group/ mygroup/ Go to the newly create directory mygroup/. It should reside in test/unit. The directory mygroup/ contains a CMake build file (a) and two *.cpp and two *.h files (b, c): a) A CMakeLists.txt build file b) bug123.cpp + bug123.h -> compiled into binary bug123 c) bug456.cpp + bug456.h -> compiled into binary bug456 A pair of one *.cpp and the corresponding *.h file (b, c) holds the code for one bug test and is compiled into one binary. Modify the template code as needed. Make sure you keep the CMakeLists.txt (a) in sync with the code in the directory. Have a look, its Cut&Paste and Search&Replace that needs to be done. In order to build the test whenever the driver is build, you must "register" the new directory at the CMakeLists.txt found in the parent directory of your newly create mygroup/ directory. Open the CMakeLists.txt file from test/unit/). At its end you will find: # Copy&Paste template: change directory name and uncomment # ADD_SUBDIRECTORY(template_bug_group) ADD_SUBDIRECTORY(template_bug_group) Modify the CMakeLists.txt by adding: "ADD_SUBDIRECTORY(mygroup)" to its end. 2) Adding a test to a group of tests Go to the directory where you want to add your test. Write the test code. You can either copy a pair of one *.h and one *.cpp file which makes a test for another bug and modify it, or you copy example files from the directory template_bug_group for a starting point. For example, copy the template files bug123.cpp and bug123.h: > cd mygroup/ > cp ../template_bug_group/bug123.cpp bug_mynumber.cpp > cp ../template_bug_group/bug123.h bug_mynumber.h Use Cut&Past and Search&Replace to fix class and methods names in the newly created files bug_mynumber.cpp and bug_mynumber.h . Have a look at the examples/ directory for basic syntax snippets! (Yes, we should add more, but as we will proceed this is likely to grow...) 3) Add the new test to the CMakeLists.txt in its directory In order compile your new test from mygroup/bug_mynumber.cpp|h into a binary mygroup/bug_mynumber you need to modify mygroup/CMakeLists.txt . It should be easy going. Look out for a block like this: # # Instructions for compiling bug123.cpp|h into the binary bug123 # Use Copy&Paste and Search&Replace to add new tests to the build # [...] # # End of the instructions for building binary bug123 from bug123.cpp|h # Use Cut&Paste and Search&Replace to make it compile your test code contained in bug_mynumber.cpp|h instead of bug123.c|h. 4) Compile the new code In the root directory of the driver do: > cmake . && make If all goes well, it does an incemental build and builds only you latest additions. You will find the binary of you new test in test/unit/mygroup. It will have the name bug_mynumber. Of course, replace "mygroup" and "bug_mynumber" with whatever you used in steps 1-3 :-). 5) Questions? Andrey Hristov, Lawrin Novitsky and Ulf Wendel have worked on Connector/C++. Georg Richter has some good CMake skills. mysql-connector-c++-1.1.7/test/unit/bugs/CMakeLists.txt000644 015771 000012 00000002777 12645244437 023437 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(bugs_sources ../unit_fixture.cpp ../main.cpp bugs.cpp) IF(WIN32) SET(bugs_sources ${bugs_sources} bugs.h ../unit_fixture.h) ENDIF(WIN32) ADD_EXECUTABLE(unsorted_bugs ${bugs_sources}) SET_TARGET_PROPERTIES(unsorted_bugs PROPERTIES OUTPUT_NAME "unsorted_bugs") TARGET_LINK_LIBRARIES(unsorted_bugs ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring bugs test cases - unsorted") mysql-connector-c++-1.1.7/test/unit/bugs/bugs.cpp000644 015771 000012 00000070270 12645244437 022334 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "bugs.h" #include #include #include "driver/mysql_error.h" //Prevent windows min() macro because of std::numeric_limits::min() #undef min namespace testsuite { namespace regression { void bugs::net_write_timeout39878() { logMsg("Test for #39878 - not fixed. And looks like there is no way to fix it at the moment."); logMsg("If the test doesn't fail - that rather means that you should tweak parameters for your system"); logMsg("You can do that with command line parameters:"); logMsg(" --nwtTimeout= for the value net_write timeout to set to (default 1)"); logMsg(" --nwtPause= for the length of pause test shoud take while fetching rows (default 2)"); logMsg(" --nwtRows= for the number of rows to insert into table (default 9230)"); int timeout = 1; int pause = 2; int rows = 9230; int tmp = TestsRunner::getStartOptions()->getInt("nwtTimeout"); if (tmp > 0) timeout = tmp; tmp = TestsRunner::getStartOptions()->getInt("nwtPause"); if (tmp > 0) pause = tmp; tmp = TestsRunner::getStartOptions()->getInt("nwtRows"); if (tmp > 0) rows = tmp; pstmt.reset(con->prepareStatement("set net_write_timeout=?")); pstmt->setInt(1, timeout); pstmt->execute(); res.reset(stmt->executeQuery("show variables like \"net_write_timeout\"")); res->next(); TestsListener::messagesLog() << "We've set net_write_timeout to " << res->getString(2) << std::endl; stmt->executeUpdate("drop table if exists bug39878"); stmt->executeUpdate("create table bug39878 (id int unsigned not null)"); stmt->execute("lock table bug39878 write"); pstmt.reset(con->prepareStatement("insert into bug39878 ( id ) values( ? )")); for (int i = 1; i <= rows; ++i) { pstmt->setInt(1, i); pstmt->execute(); } stmt->execute("unlock tables"); res.reset(stmt->executeQuery("select count(*) from bug39878")); res->next(); uint32_t rowsCount = res->getUInt(1); TestsListener::messagesLog() << "Now we have " << rowsCount << " rows in the table" << std::endl; // Must set ResultSet Type to TYPE_FORWARD_ONLY stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY); res.reset(stmt->executeQuery("select * from bug39878")); TestsListener::messagesLog() << "ResultSetType: " << stmt->getResultSetType() << std::endl; uint32_t rowsRead = 0; try { while (res->next()) { if (rowsRead == 0) { TestsListener::messagesLog() << "Pause " << pause << "s." << std::endl; SLEEP(pause); } ++rowsRead; } } catch (sql::SQLException& /*e*/) { //if ( e.errNo == 2006 ) /* let's think that exception is a god result itself. also not sure which errno should it be */ return; } TestsListener::messagesLog() << "We've fetched " << rowsRead << " rows." << std::endl; try { stmt->execute("drop table if exists bug39878"); } catch (sql::SQLException& e) { // Expected, that Server has gone away logMsg(e.what()); // Lazy way to reconnect setUp(); stmt->execute("drop table if exists bug39878"); } ASSERT_EQUALS(rowsCount, rowsRead); } void bugs::store_result_error_51562() { std::stringstream msg; logMsg("Regression test for #51562"); try { stmt.reset(con->createStatement()); /* Running a SELECT and storing the returned result set in this->res */ res.reset(stmt->executeQuery("select 1, (select 'def' union all select 'abc')")); fail("SQL error not detected or the server has changed its behavior", __FILE__, __LINE__); } catch (sql::SQLException &e) { /* If anything goes wrong, write some info to the log... */ logMsg("Expecting error: ERROR 1242 (21000): Subquery returns more than 1 row, got:"); logMsg(e.what()); logMsg("SQLState: " + std::string(e.getSQLState())); if (e.getErrorCode() != 1242) { msg.str(""); msg << "Expecting MySQL error code 1242, got " << e.getErrorCode() << "."; msg << "This may be a compatible and acceptable code - check manually and update test if nedded!"; logMsg(msg.str()); fail("Wrong error code, check verbose output for details", __FILE__, __LINE__); } } logMsg("Checking prepared statements"); try { pstmt.reset(con->prepareStatement("select 1, (select 'def' union all select 'abc')")); /* Running a SELECT and storing the returned result set in this->res */ res.reset(pstmt->executeQuery()); fail("SQL error not detected or the server has changed its behavior", __FILE__, __LINE__); } catch (sql::SQLException &e) { /* If anything goes wrong, write some info to the log... */ logMsg("Expecting error: ERROR 1242 (21000): Subquery returns more than 1 row, got:"); logMsg(e.what()); logMsg("SQLState: " + std::string(e.getSQLState())); if (e.getErrorCode() != 1242) { msg.str(""); msg << "Expecting MySQL error code 1242, got " << e.getErrorCode() << "."; msg << "This may be a compatible and acceptable code - check manually and update test if nedded!"; logMsg(msg.str()); fail("Wrong error code, check verbose output for details", __FILE__, __LINE__); } } } void bugs::getResultSet_54840() { stmt->executeUpdate("DROP function if exists _getActivePost"); stmt->executeUpdate("CREATE Function _getActivePost(_author INT) " "RETURNS INT " "DETERMINISTIC " "BEGIN " " RETURN 55;" "END"); ASSERT(stmt->execute("select _getActivePost()")); try { res.reset(stmt->getResultSet()); } catch (::sql::SQLException & /*e*/) { stmt->executeUpdate("DROP function _getActivePost"); return; /* Everything is fine */ } stmt->executeUpdate("DROP function _getActivePost"); FAIL("Exception wasn't thrown by getResultSet"); } void bugs::supportIssue_52319() { std::stringstream msg; unsigned int uiStartTime = 1289837776; unsigned int uiProductsID = 20; unsigned int uiParSetID = 2; logMsg("Test for MySQL support issue 52319"); stmt->execute("DROP TABLE IF EXISTS products"); createSchemaObject("TABLE", "products", "(uiProductsIdx int(10) unsigned NOT NULL AUTO_INCREMENT, startTime timestamp NULL DEFAULT NULL, stopTime timestamp NULL DEFAULT NULL, uiProductsID int(10) DEFAULT NULL, uiParameterSetID int(10) unsigned DEFAULT NULL, PRIMARY KEY (uiProductsIdx))"); stmt->execute("DROP PROCEDURE IF EXISTS insertProduct"); stmt->execute("CREATE PROCEDURE insertProduct(IN dwStartTimeIN INT UNSIGNED, IN uiProductsIDIN INT UNSIGNED, IN dwParSetIDIN INT UNSIGNED) BEGIN DECLARE stStartTime TIMESTAMP; SET stStartTime = FROM_UNIXTIME(dwStartTimeIN); INSERT INTO `products` (startTime, uiProductsID, uiParameterSetID) VALUES (stStartTime, uiProductsIDIN, dwParSetIDIN); END"); pstmt.reset(con->prepareStatement("CALL insertProduct(?, ?, ?)")); pstmt->setInt(1, uiStartTime); pstmt->setInt(2, uiProductsID); pstmt->setInt(3, uiParSetID); pstmt->execute(); logMsg("Procedure called, checking products table contents"); res.reset(stmt->executeQuery("SELECT uiProductsIdx, startTime, stopTime, uiProductsID, uiParameterSetID FROM products")); ASSERT(res->next()); msg.str(""); msg << "uiProductsIdx = " << res->getString("uiProductsIdx") << "\n"; msg << "startTime = " << res->getString("startTime") << "\n"; msg << "stopTime = " << res->getString("stopTime") << "\n"; msg << "uiPrpductsID = " << res->getString("uiProductsID") << "\n"; msg << "uiParameterSetID = " << res->getString("uiParameterSetID") << "\n"; logMsg(msg.str()); /* SKIP - timezone may trick us ASSERT_EQUALS("2010-11-15 17:16:16", res->getString("startTime")); */ ASSERT_EQUALS("20", res->getString("uiProductsID")); ASSERT_EQUALS("2", res->getString("uiParameterSetID")); ASSERT(!res->next()); } /* Bug#15936764/67325 */ void bugs::expired_pwd() { logMsg("bugs::expired_pwd"); if (getMySQLVersion(con) < 56006) { SKIP("The server does not support tested functionality(expired password)"); } stmt->executeUpdate("DROP TABLE IF EXISTS test.ccpp_expired_pwd"); try { stmt->executeUpdate("DROP USER ccpp_expired_pwd"); } catch (sql::SQLException &) { // Catching exception if user did not exist } stmt->executeUpdate("CREATE USER ccpp_expired_pwd IDENTIFIED BY 'foo'"); stmt->executeUpdate("GRANT ALL ON test to ccpp_expired_pwd"); stmt->executeUpdate("ALTER USER ccpp_expired_pwd PASSWORD EXPIRE"); sql::ConnectOptionsMap opts; opts["userName"]= sql::SQLString("ccpp_expired_pwd"); opts["password"]= sql::SQLString(""); try { if (getConnection(&opts)) { SKIP("The expired password does not work with anonymous-user accounts."); } } catch (sql::SQLException &e) { /* If no anonymous user present then continue */ } opts["password"]= sql::SQLString("foo"); testsuite::Connection c2; /* Seeing error first without OPT_CAN_HANDLE_EXPIRED_PASSWORDS ... */ try { c2.reset(getConnection(&opts)); } catch (sql::SQLException &e) { ASSERT_EQUALS(1862, e.getErrorCode()/*ER_MUST_CHANGE_PASSWORD_LOGIN*/); } /* ... Now with it */ opts["OPT_CAN_HANDLE_EXPIRED_PASSWORDS"]= true; try { c2.reset(getConnection(&opts)); } catch (sql::SQLException &e) { /* In case of sql::mysql::mydeCL_CANT_HANDLE_EXP_PWD tests fail - means that in the setup where test is run the driver does not support expired password */ ASSERT_EQUALS(1820, e.getErrorCode()/*ER_MUST_CHANGE_PASSWORD*/); } // Now setting new password and getting fully functional connection opts["preInit"]= sql::SQLString("set password= password('bar')"); // Connect should go thru fine try { c2.reset(getConnection(&opts)); } catch(sql::SQLException &e) { // We can get here in case of old libmysql library ASSERT_EQUALS(sql::mysql::deCL_CANT_HANDLE_EXP_PWD, e.getErrorCode()); // Wrong libmysql - we can't test anything else as we can't get connection return; } // Trying to connect with new pwd opts.erase("preInit"); opts.erase("OPT_CAN_HANDLE_EXPIRED_PASSWORDS"); opts["password"]= sql::SQLString("bar"); opts["CLIENT_MULTI_STATEMENTS"]= true; opts["postInit"]= sql::SQLString("create table test.ccpp_expired_pwd(i int);" "insert into test.ccpp_expired_pwd(i) values(2)"); c2.reset(getConnection(&opts)); // postInit is introduced anong with preInit - testing it too Statement s2(c2->createStatement()); /* Checking 2 things - that executeUpdate detects a resultset returning stmt, and that connection is usable after that */ try { s2->executeUpdate("insert into test.ccpp_expired_pwd(i) values(7);select i from test.ccpp_expired_pwd"); FAIL("Driver had to throw \"Query returning resultset\" exception!"); } catch (sql::SQLException &) { } res.reset(s2->executeQuery("select i from test.ccpp_expired_pwd")); ASSERT(res->next()); ASSERT_EQUALS(2, res->getInt(1)); c2->close(); stmt->executeUpdate("DROP TABLE test.ccpp_expired_pwd"); stmt->executeUpdate("DROP USER ccpp_expired_pwd"); } /* Bug#16970753/69492 * Cannot Connect error when using legacy authentication */ void bugs::legacy_auth() { logMsg("bugs::legacy_auth"); try { stmt->executeUpdate("DROP USER ccpp_legacy_auth"); } catch (sql::SQLException &) { // Catching exception if user did not exist } res.reset(stmt->executeQuery("SELECT @@secure_auth")); res->next(); /* We need to know if we need to set it back*/ int secure_auth= res->getInt(1); if (secure_auth) { try { stmt->executeUpdate("SET GLOBAL secure_auth= OFF"); } catch(sql::SQLException &) { SKIP("For this test user should be able to set global variables."); } } try { stmt->executeUpdate("CREATE USER ccpp_legacy_auth@'%' IDENTIFIED BY 'foo'"); stmt->executeUpdate("GRANT ALL ON test to ccpp_legacy_auth@'%'"); } catch(sql::SQLException &) { SKIP("For this test user should have GRANT privelege"); } /* Simplest way to create user identified with old password on all server versions */ stmt->executeUpdate("UPDATE mysql.user SET Password=old_password('foo')\ WHERE User='ccpp_legacy_auth' AND Host='%'"); try { stmt->executeUpdate("UPDATE mysql.user SET Plugin=''\ WHERE User='ccpp_legacy_auth' AND Host='%'"); } catch(sql::SQLException &) { /* Doing nothing - catching for case of old server that does not have Plugin field */ } stmt->executeUpdate("FLUSH PRIVILEGES"); testsuite::Connection c2; sql::ConnectOptionsMap opts; opts["useLegacyAuth"]= false; opts["userName"]= sql::SQLString("ccpp_legacy_auth"); opts["password"]= sql::SQLString("foo"); opts["schema"]= sql::SQLString("test"); /* First verifying that we can't connect without the option */ try { c2.reset(getConnection(&opts)); } catch (sql::SQLException &e) { ASSERT_EQUALS(2049, e.getErrorCode() /*CR_SECURE_AUTH*/); } opts["useLegacyAuth"]= true; c2.reset(getConnection(&opts)); /* If this passed - we are fine */ c2->close(); /* Returning secure_auth if needed */ if (secure_auth) { stmt->executeUpdate("SET GLOBAL secure_auth= ON"); } stmt->executeUpdate("DROP USER ccpp_legacy_auth"); } /* Bug #18193771/71605 - The driver does not recognize utf8mb4 charset */ void bugs::bug71606() { logMsg("bugs::bug71606"); if (getMySQLVersion(con) < 56000) { SKIP("The server does not support tested functionality(utf8mb4 charset)"); } /* We only loop thru default collations - thus the testcase does not cover all possible cases */ res.reset(stmt->executeQuery("SHOW CHARSET")); /* Connection is reset after the testcase finishes - thus we can safely "set names" here */ Statement stmt2(con->createStatement()); pstmt.reset(con->prepareStatement("SELECT 'a'")); ResultSet res2; ResultSetMetaData *rsmd2; while (res->next()) { String csname(res->getString(1)); String query("SET NAMES "); query.append(res->getString(1)); try { stmt2->executeUpdate(query); } catch(sql::SQLException &) { /* Assuming this particular charset charset cannot be set as client charset, like atm we can't do that with utf16/32 */ continue; } res2.reset(pstmt->executeQuery()); rsmd2= res2->getMetaData(); rsmd2->isCaseSensitive(1); } } void bugs::bug72700() { logMsg("bugs::bug72700"); ASSERT(stmt->execute("select astext(geomfromtext('point(10 10)'))")); try { res.reset(stmt->getResultSet()); checkResultSetScrolling(res); ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS(meta->getColumnType(1), 15); ASSERT_EQUALS(meta->getColumnTypeName(1), "LONGTEXT"); } catch (::sql::SQLException & /*e*/) { return; /* Everything is fine */ } stmt->execute("DROP TABLE IF EXISTS bug72700"); stmt->execute("CREATE TABLE bug72700(valtext longtext)"); ASSERT(stmt->execute("SELECT valtext FROM bug72700")); try { res.reset(stmt->getResultSet()); checkResultSetScrolling(res); ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS(meta->getColumnType(1), 15); ASSERT_EQUALS(meta->getColumnTypeName(1), "TEXT"); } catch (::sql::SQLException & /*e*/) { return; /* Everything is fine */ } stmt->execute("DROP TABLE IF EXISTS bug72700"); } void bugs::bug66871() { sql::Connection *con; sql::Statement *stmt; sql::ResultSet *res; logMsg("bugs::bug66871"); try { con = getConnection(NULL); stmt = con->createStatement(); ASSERT(stmt->execute("select 1")); res= stmt->getResultSet(); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(1), 1); con->close(); delete con; ASSERT(stmt->execute("select 2")); res= stmt->getResultSet(); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(1), 2); } catch (::sql::SQLException & /*e*/) { delete res; delete stmt; return; /* Everything is fine */ } delete res; delete stmt; FAIL("Exception wasn't thrown by execute"); } /* Segementation fault in row retrieval when defaultstatementresulttype= forward_only and row position is after last row */ void bugs::bug20085944() { logMsg("bugs::bug20085944"); try { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; connection_properties["defaultStatementResultType"]=sql::ResultSet::TYPE_FORWARD_ONLY; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS bug20085944"); stmt->execute("CREATE TABLE bug20085944(id INT)"); stmt->execute("INSERT INTO bug20085944 VALUES(1),(2),(3)"); res.reset(stmt->executeQuery("SELECT * FROM bug20085944")); for (int i=1; i <= 3; ++i) { ASSERT(res->next()); ASSERT_EQUALS(i, res->getInt(1)); } ASSERT(!res->next()); res->getInt(1); } catch (::sql::SQLException & /*e*/) { return; /* Everything is fine */ } FAIL("Exception wasn't thrown by getInt() in bug20085944()"); } void bugs::bug19938873_pstmt() { logMsg("bugs::bug19938873_pstmt"); try { pstmt.reset(con->prepareStatement("SELECT NULL")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); res->wasNull(); } catch (sql::SQLException & /*e*/) { return; /* Everything is fine */ } FAIL("Exception wasn't thrown by wasNull()"); } void bugs::bug19938873_stmt() { logMsg("bugs::bug19938873_stmt"); try { stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT NULL")); ASSERT(res->next()); res->wasNull(); } catch (sql::SQLException & /*e*/) { return; /* Everything is fine */ } FAIL("Exception wasn't thrown by wasNull()"); } void bugs::bug68523() { try { stmt->execute("DROP TABLE IF EXISTS bug68523"); stmt->execute("CREATE TABLE bug68523(ts TIMESTAMP(6))"); stmt->execute("INSERT INTO bug68523(ts) values('2015-01-20 16:14:36.709649')"); pstmt.reset(con->prepareStatement("SELECT ts, TIME(ts) from bug68523")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(res->getString(1), "2015-01-20 16:14:36.709649"); ASSERT_EQUALS(res->getString(2), "16:14:36.709649"); stmt->execute("DROP TABLE IF EXISTS bug68523"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void bugs::bug66235() { logMsg("bug::bug66235"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id BIT(3))"); stmt->execute("INSERT INTO test(id) VALUES(0b1), (0b10), (0b1), (0b1), (0b10), (0b111);"); res.reset(stmt->executeQuery("SELECT MAX(id), MIN(id) FROM test")); while (res->next()) { ASSERT_EQUALS(res->getString(1), "7"); ASSERT_EQUALS(res->getInt(1), 7); ASSERT_EQUALS(res->getString(2), "1"); ASSERT_EQUALS(res->getInt(2), 1); } res.reset(stmt->executeQuery("SELECT id FROM test limit 1")); while (res->next()) { ASSERT_EQUALS(res->getString(1), "1"); ASSERT_EQUALS(res->getInt(1), 1); } stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void bugs::bug21066575() { logMsg("bug::bug21066575"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS bug21066575"); stmt->execute("CREATE TABLE bug21066575(txt text)"); stmt->execute("INSERT INTO bug21066575(txt) VALUES('abc')"); pstmt.reset(con->prepareStatement("select * from bug21066575")); res.reset(); for (int i = 0; i < 10; ++i) { res.reset(pstmt->executeQuery()); res->next(); ASSERT_EQUALS("abc", res->getString(1)); } stmt->execute("DROP TABLE IF EXISTS bug21066575_2"); stmt->execute("CREATE TABLE `bug21066575_2` (\ `f1` longtext,\ `id` int(11) NOT NULL AUTO_INCREMENT,\ PRIMARY KEY (`id`)\ ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1"); stmt->execute("insert into bug21066575_2(f1) values(repeat('f',1024000))," "(repeat('f',1024000))," "(repeat('f',1024000))," "(repeat('f',1024000))"); for(int i= 0; i < 100; i++) { pstmt.reset(con->prepareStatement("select id, f1 from bug21066575_2")); //pstmt->setInt(1, i); res.reset(pstmt->executeQuery()); while (res->next()) { std::stringstream ss; ss << "id = " << res->getInt(1); ss << std::endl; ss << "f1 = " << res->getString(2); logMsg(ss.str().c_str()); } //Detect if process frees ResultSet resources. res.reset(); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void bugs::bug14520822() { logMsg("bug::bug14520822"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS bug14520822"); stmt->execute("CREATE TABLE bug14520822(b BIT NOT NULL DEFAULT 0)"); stmt->execute("INSERT INTO bug14520822(b) VALUES(0b0), (0b1)"); res.reset(stmt->executeQuery("select min(b) ,max(b) from bug14520822")); res->next(); ASSERT_EQUALS("0", res->getString(1)); ASSERT_EQUALS("1", res->getString(2)); ASSERT_EQUALS(false, res->getBoolean(1)); ASSERT_EQUALS(true, res->getBoolean(2)); ASSERT_EQUALS((int64_t)0, res->getInt64(1)); ASSERT_EQUALS((int64_t)1, res->getInt64(2)); pstmt.reset(con->prepareStatement("select min(b) ,max(b) from bug14520822")); res.reset(pstmt->executeQuery()); res->next(); ASSERT_EQUALS("0", res->getString(1)); ASSERT_EQUALS("1", res->getString(2)); ASSERT_EQUALS(false, res->getBoolean(1)); ASSERT_EQUALS(true, res->getBoolean(2)); ASSERT_EQUALS((int64_t)0, res->getInt64(1)); ASSERT_EQUALS((int64_t)1, res->getInt64(2)); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void bugs::bug21053335() { logMsg("bugs::bug21053335"); try { stmt->execute("DROP TABLE IF EXISTS bug21053335"); stmt->execute("CREATE TABLE bug21053335(c char(10))"); stmt->execute("INSERT INTO bug21053335 values(NULL), (1)"); res.reset(stmt->executeQuery("select c from bug21053335")); res->next(); std::stringstream log; log << "Data :" <getString(1); log<<"\nrs->wasNull(1) : "<wasNull()<wasNull()); res->next(); try{ ASSERT(res->wasNull()); FAIL("Exception was not thrown by wasNull()"); } catch (sql::SQLException & e) { // Everything is ok } log.flush(); log << "Data :" <getString(1); log<<"\nrs->wasNull(1) : "<wasNull()<wasNull()); } catch (sql::SQLException &e) { FAIL("Exception thrown by wasNull()"); throw; } } void bugs::bug17218692() { logMsg("bugs::bug17218692"); try { stmt->execute("DROP TABLE IF EXISTS bug17218692"); stmt->execute("CREATE TABLE bug17218692(c1 time(6))"); stmt->execute("INSERT INTO bug17218692 VALUES('-838:59:58.987657')"); res.reset(stmt->executeQuery("select * from bug17218692")); res->next(); std::stringstream log; log<<"["<getString(1)<<"]"; ASSERT_EQUALS(log.str(), "[-838:59:58.987657]"); pstmt.reset(con->prepareStatement("select * from bug17218692 ")); res.reset(pstmt->executeQuery()); res->next(); std::stringstream log2; log2 << "["<getString(1)<<"]"; ASSERT_EQUALS(log.str(), log2.str()); } catch (sql::SQLException & e) { FAIL("Exception thrown"); throw; } } void bugs::bug21067193() { logMsg("bugs::bug21067193"); try { stmt->execute("DROP TABLE IF EXISTS bug21067193"); stmt->execute("create table bug21067193(id int)"); stmt->execute("insert into bug21067193 values(1),(2),(3)"); res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_SCROLL_SENSITIVE)->executeQuery("select * from bug21067193"))); ASSERT_EQUALS(true, res->absolute(2)); ASSERT_EQUALS(2, res->getInt(1)); ASSERT_EQUALS(true, res->absolute(-1)); ASSERT_EQUALS(3, res->getInt(1)); ASSERT_EQUALS(false, res->absolute(std::numeric_limits::min())); //Invalid position, Returns FALSE } catch (sql::SQLException & e) { // Error.... throw; } } void bugs::bug21152054() { stmt->execute("DROP TABLE IF EXISTS bug21152054"); stmt->execute("create table bug21152054(c1 int);" ); stmt->execute("insert into bug21152054 values(1), (2), (3), (4);" ); pstmt.reset( con->prepareStatement("select c1 from bug21152054;") ); res.reset( pstmt->executeQuery() ); ASSERT_EQUALS(true, res->absolute(4)); ASSERT_EQUALS(4, res->getInt(1)); int line = 4; ASSERT_EQUALS(true, res->relative(-1)); do { --line; ASSERT_EQUALS(line, res->getInt(1)); } while(res->relative(-1)); } void bugs::bug22292073() { stmt->execute("DROP TABLE IF EXISTS bug22292073"); stmt->execute("create table bug22292073 (jdoc JSON);" ); stmt->execute("insert into bug22292073 values('{ \"name\": \"abc\", \"age\": 1 , \"misc\":\ 1.2}'), ('{ \"name\": \"abcdef\", \"age\": 31 , \"misc\": 1.237843}');" ); pstmt.reset( con->prepareStatement("select JSON_EXTRACT(jdoc, '$.age') from bug22292073;") ); res.reset( pstmt->executeQuery() ); res->next(); ASSERT_EQUALS(true, res->getBoolean(1)); ASSERT_EQUALS(1, res->getInt(1)); ASSERT_EQUALS((int64_t)1L, res->getInt64(1)); ASSERT_EQUALS(1, res->getUInt(1)); ASSERT_EQUALS(1UL, res->getUInt64(1)); ASSERT_EQUALS(1.0, res->getDouble(1)); res->next(); ASSERT_EQUALS(true, res->getBoolean(1)); ASSERT_EQUALS(31, res->getInt(1)); ASSERT_EQUALS((int64_t)31L, res->getInt64(1)); ASSERT_EQUALS(31, res->getUInt(1)); ASSERT_EQUALS(31UL, res->getUInt64(1)); ASSERT_EQUALS(31.0, res->getDouble(1)); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("select JSON_EXTRACT(jdoc, '$.age') from bug22292073;")); res->next(); ASSERT_EQUALS(true, res->getBoolean(1)); ASSERT_EQUALS(1, res->getInt(1)); ASSERT_EQUALS((int64_t)1L, res->getInt64(1)); ASSERT_EQUALS(1, res->getUInt(1)); ASSERT_EQUALS(1UL, res->getUInt64(1)); ASSERT_EQUALS(1.0, res->getDouble(1)); res->next(); ASSERT_EQUALS(true, res->getBoolean(1)); ASSERT_EQUALS(31, res->getInt(1)); ASSERT_EQUALS((int64_t)31L, res->getInt64(1)); ASSERT_EQUALS(31, res->getUInt(1)); ASSERT_EQUALS(31UL, res->getUInt64(1)); ASSERT_EQUALS(31.0, res->getDouble(1)); } } /* namespace regression */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/bugs/bugs.h000644 015771 000012 00000005715 12645244437 022003 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __BUGS_H_ #define __BUGS_H_ #include "../unit_fixture.h" /** * Test cases for unsorted bugs (expecting that later bugs in different units * will be sorted to separate test suites) */ namespace testsuite { namespace regression { class bugs : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(bugs) { TEST_CASE(net_write_timeout39878); TEST_CASE(store_result_error_51562); TEST_CASE(getResultSet_54840); TEST_CASE(supportIssue_52319); TEST_CASE(expired_pwd); TEST_CASE(bug71606); TEST_CASE(bug72700); TEST_CASE(bug66871); TEST_CASE(bug20085944); TEST_CASE(bug19938873_pstmt); TEST_CASE(bug19938873_stmt); TEST_CASE(bug68523); TEST_CASE(bug66235); TEST_CASE(bug14520822); TEST_CASE(bug17218692); TEST_CASE(bug21053335); TEST_CASE(bug21067193); TEST_CASE(bug21066575); TEST_CASE(bug21152054); TEST_CASE(bug22292073); } /** * http://bugs.mysql.com/39878 * * bug report is against c/odbc, but problem is common for (almost?) all connectors * if we have pause between fetching rows lonher than net_write_timeout, * we won't receive all rows, and no error occures. */ void net_write_timeout39878(); /** * http://bugs.mysql.com/bug.php?id=51562 */ void store_result_error_51562(); void getResultSet_54840(); /** * MySQL customer suppoer issue #52319 */ void supportIssue_52319(); void expired_pwd(); void legacy_auth(); void bug71606(); void bug72700(); void bug66871(); void bug20085944(); void bug19938873_pstmt(); void bug19938873_stmt(); void bug68523(); void bug66235(); void bug14520822(); void bug21066575(); void bug17218692(); void bug21053335(); void bug21067193(); void bug21152054(); void bug22292073(); }; REGISTER_FIXTURE(bugs); } /* namespace regression */ } /* namespace testsuite */ #endif mysql-connector-c++-1.1.7/test/unit/classes/CMakeLists.txt000644 015771 000012 00000021355 12645244437 024125 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(test_common_sources ../unit_fixture.cpp ../main.cpp) IF(WIN32) SET(test_common_sources ${test_common_sources} ../unit_fixture.h) ENDIF(WIN32) SET(test_connection_sources ${test_common_sources} connection.cpp) IF(WIN32) SET(test_connection_sources ${test_connection_sources} connection.h) ENDIF(WIN32) ADD_EXECUTABLE(test_connection ${test_connection_sources}) SET_TARGET_PROPERTIES(test_connection PROPERTIES OUTPUT_NAME "connection" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_connection ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - connection") SET(test_databasemetadata_sources ../unit_fixture.cpp ../main.cpp connectionmetadata.cpp) IF(WIN32) SET(test_databasemetadata_sources ${test_databasemetadata_sources} ../unit_fixture.h connectionmetadata.h) ENDIF(WIN32) ADD_EXECUTABLE(test_databasemetadata ${test_databasemetadata_sources}) SET_TARGET_PROPERTIES(test_databasemetadata PROPERTIES OUTPUT_NAME "databasemetadata" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_databasemetadata ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - databasemetadata") SET(test_resultsetmetadata_sources ../unit_fixture.cpp ../main.cpp resultsetmetadata.cpp) IF(WIN32) SET(test_resultsetmetadata_sources ${test_resultsetmetadata_sources} ../unit_fixture.h resultsetmetadata.h) ENDIF(WIN32) ADD_EXECUTABLE(test_resultsetmetadata ${test_resultsetmetadata_sources}) SET_TARGET_PROPERTIES(test_resultsetmetadata PROPERTIES OUTPUT_NAME "resultsetmetadata" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_resultsetmetadata ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - resultsetmetadata") SET(test_resultset_sources ../unit_fixture.cpp ../main.cpp resultset.cpp) IF(WIN32) SET(test_resultset_sources ${test_resultset_sources} ../unit_fixture.h resultset.h) ENDIF(WIN32) ADD_EXECUTABLE(test_resultset ${test_resultset_sources}) SET_TARGET_PROPERTIES(test_resultset PROPERTIES OUTPUT_NAME "resultset" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_resultset ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - resultset") SET(test_savepoint_sources ../unit_fixture.cpp ../main.cpp savepoint.cpp) IF(WIN32) SET(test_savepoint_sources ${test_savepoint_sources} ../unit_fixture.h savepoint.h) ENDIF(WIN32) ADD_EXECUTABLE(test_savepoint ${test_savepoint_sources}) SET_TARGET_PROPERTIES(test_savepoint PROPERTIES OUTPUT_NAME "savepoint" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_savepoint ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - savepoint") SET(test_preparedstatement_sources ../unit_fixture.cpp ../main.cpp preparedstatement.cpp) IF(WIN32) SET(test_preparedstatement_sources ${test_preparedstatement_sources} ../unit_fixture.h preparedstatement.h) ENDIF(WIN32) ADD_EXECUTABLE(test_preparedstatement ${test_preparedstatement_sources}) SET_TARGET_PROPERTIES(test_preparedstatement PROPERTIES OUTPUT_NAME "preparedstatement" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_preparedstatement ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - preparedstatement") SET(test_parametermetadata_sources ../unit_fixture.cpp ../main.cpp parametermetadata.cpp) IF(WIN32) SET(test_parametermetadata_sources ${test_parametermetadata_sources} ../unit_fixture.h parametermetadata.h) ENDIF(WIN32) ADD_EXECUTABLE(test_parametermetadata ${test_parametermetadata_sources}) SET_TARGET_PROPERTIES(test_parametermetadata PROPERTIES OUTPUT_NAME "parametermetadata" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_parametermetadata ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - parametermetadata") SET(test_art_resultset_sources ../unit_fixture.cpp ../main.cpp art_resultset.cpp) IF(WIN32) SET(test_art_resultset_sources ${test_art_resultset_sources} ../unit_fixture.h art_resultset.h) ADD_DEFINITIONS("-DCPPCONN_PUBLIC_FUNC=") ENDIF(WIN32) ADD_EXECUTABLE(test_art_resultset ${test_art_resultset_sources}) SET_TARGET_PROPERTIES(test_art_resultset PROPERTIES OUTPUT_NAME "art_resultset" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") IF(WIN32) TARGET_LINK_LIBRARIES(test_art_resultset ${MY_TARGET_LINK_LIBRARIES_STATIC_CPPLIB} ${MY_GCOV_LINK_LIBRARIES}) # SET_TARGET_PROPERTIES(test_art_resultset PROPERTIES # LINK_FLAGS_DEBUG "/NODEFAULTLIB:LIBCMTD /NODEFAULTLIB:LIBCMT" # LINK_FLAGS_RELWITHDEBINFO "/NODEFAULTLIB:LIBCMT" # LINK_FLAGS_RELEASE "/NODEFAULTLIB:LIBCMT") ELSE(WIN32) TARGET_LINK_LIBRARIES(test_art_resultset ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) ENDIF(WIN32) MESSAGE(STATUS "Configuring unit tests - art_resultset") SET(test_statement_sources ../unit_fixture.cpp ../main.cpp statement.cpp) IF(WIN32) SET(test_statement_sources ${test_statement_sources} ../unit_fixture.h statement.h) ENDIF(WIN32) ADD_EXECUTABLE(test_statement ${test_statement_sources}) SET_TARGET_PROPERTIES(test_statement PROPERTIES OUTPUT_NAME "statement" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_statement ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - statement") SET(test_uri_sources ${test_common_sources} "${CMAKE_SOURCE_DIR}/driver/mysql_uri.cpp" "${CMAKE_SOURCE_DIR}/driver/mysql_util.cpp" uri.cpp) IF(WIN32) SET(test_uri_sources ${test_uri_sources} "${CMAKE_SOURCE_DIR}/driver/mysql_uri.h" uri.h) ENDIF(WIN32) ADD_EXECUTABLE(test_uri ${test_uri_sources}) SET_TARGET_PROPERTIES(test_uri PROPERTIES OUTPUT_NAME "uri" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_uri ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - uri") SET(test_variant_sources ../unit_fixture.cpp ../main.cpp variant.cpp) IF(WIN32) SET(test_variant_sources ${test_variant_sources} ../unit_fixture.h variant.h) ENDIF(WIN32) ADD_EXECUTABLE(test_variant ${test_variant_sources}) SET_TARGET_PROPERTIES(test_variant PROPERTIES OUTPUT_NAME "variant" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(test_variant ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - variant") mysql-connector-c++-1.1.7/test/unit/classes/art_resultset.cpp000644 015771 000012 00000005137 12645244437 024771 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../../../driver/mysql_art_resultset.h" #include "art_resultset.h" namespace testsuite { namespace classes { void art_resultset::testMyVal() { sql::mysql::MyVal valInt1(static_cast (0x0000000100000000LL)); sql::mysql::MyVal valInt2(static_cast (0x0000000000000100LL)); sql::mysql::MyVal valInt3(static_cast (0x8000000000000100LL)); sql::mysql::MyVal valUInt1(static_cast (0xfffffffffffffffeULL)); sql::mysql::MyVal valDouble1(0.00001); sql::mysql::MyVal valDouble2(0.0); sql::mysql::MyVal valDouble3(2.49); sql::mysql::MyVal valBool1(true); sql::mysql::MyVal valBool2(false); sql::mysql::MyVal valStr1("131"); sql::mysql::MyVal valStr2("foobar"); sql::mysql::MyVal valStr3("true"); sql::mysql::MyVal valPtr1(static_cast (NULL)); sql::mysql::MyVal valPtr2(static_cast (&valInt1)); ASSERT_EQUALS(true, valInt1.getBool()); ASSERT_EQUALS("4294967296", valInt1.getString()); ASSERT_EQUALS(true, valInt2.getBool()); ASSERT_EQUALS_EPSILON(256., valInt2.getDouble(), 0.00001); ASSERT_EQUALS(9223372036854776064ULL, valInt3.getUInt64()); ASSERT_EQUALS(-2LL, valUInt1.getInt64()); ASSERT_EQUALS(true, valDouble1.getBool()); ASSERT_EQUALS(false, valDouble2.getBool()); ASSERT_EQUALS(2LL, valDouble3.getInt64()); ASSERT_EQUALS(131LL, valStr1.getInt64()); ASSERT_EQUALS(0LL, valStr2.getInt64()); ASSERT_EQUALS(false, valStr3.getBool()); ASSERT_EQUALS(false, valPtr1.getBool()); ASSERT_EQUALS(true, valPtr2.getBool()); } } /* namespace resultset */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/art_resultset.h000644 015771 000012 00000002765 12645244437 024442 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Test of mysql_art_resultset. * Actually so far - MyVal from there only */ namespace testsuite { namespace classes { class art_resultset : public unit_fixture { public: EXAMPLE_TEST_FIXTURE(art_resultset) { TEST_CASE(testMyVal); } /** * Test for MyVal interpretation methods * */ void testMyVal(); }; REGISTER_FIXTURE(art_resultset); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/connection.cpp000644 015771 000012 00000236034 12645244437 024232 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "connection.h" #include #include #include #include #include #include #include namespace testsuite { namespace classes { void connection::getClientInfo() { logMsg("connection::getClientInfo() - MySQL_Connection::getClientInfo()"); try { std::string ret; ret=con->getClientInfo(); if (ret != "cppconn") FAIL("Expecting 'cppconn' got '" + ret + "'."); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::getClientOption() { logMsg("connection::getClientOption() - MySQL_Connection::get|setClientOption()"); try { const std::string option("metadataUseInfoSchema"); { bool input_value=true; bool output_value=false; void * input; void * output; input=(static_cast (&input_value)); output=(static_cast (&output_value)); con->setClientOption("metadataUseInfoSchema", input); con->getClientOption("metadataUseInfoSchema", output); ASSERT_EQUALS(input_value, output_value); con->setClientOption("metadataUseInfoSchema", input); con->getClientOption("metadataUseInfoSchema", output); ASSERT_EQUALS(input_value, output_value); input_value=false; output_value=true; con->setClientOption("metadataUseInfoSchema", input); con->getClientOption("metadataUseInfoSchema", output); ASSERT_EQUALS(input_value, output_value); } { int input_value=sql::ResultSet::TYPE_SCROLL_INSENSITIVE; int output_value=sql::ResultSet::TYPE_FORWARD_ONLY; void * input; void * output; input=(static_cast (&input_value)); output=(static_cast (&output_value)); con->setClientOption("defaultStatementResultType", input); con->getClientOption("defaultStatementResultType", output); ASSERT_EQUALS(input_value, output_value); input_value=sql::ResultSet::TYPE_FORWARD_ONLY; output_value=sql::ResultSet::TYPE_SCROLL_INSENSITIVE; con->setClientOption("defaultStatementResultType", input); con->getClientOption("defaultStatementResultType", output); ASSERT_EQUALS(input_value, output_value); try { input_value=sql::ResultSet::TYPE_SCROLL_SENSITIVE; con->setClientOption("defaultStatementResultType", input); FAIL("API Change or bug, please check"); } catch (sql::InvalidArgumentException &) { /* expected */ } try { input_value=sql::ResultSet::TYPE_SCROLL_SENSITIVE + sql::ResultSet::TYPE_SCROLL_INSENSITIVE + sql::ResultSet::TYPE_FORWARD_ONLY; con->setClientOption("defaultStatementResultType", input); FAIL("API Change or bug, please check"); } catch (sql::InvalidArgumentException &) { /* expected */ } } try { bool input_value=true; bool output_value=false; void * input; void * output; input=(static_cast (&input_value)); output=(static_cast (&output_value)); con->setClientOption("defaultPreparedStatementResultType", input); con->getClientOption("defaultPreparedStatementResultType", output); ASSERT_EQUALS(input_value, output_value); input_value=false; output_value=true; con->setClientOption("defaultPreparedStatementResultType", input); con->getClientOption("defaultPreparedStatementResultType", output); ASSERT_EQUALS(input_value, output_value); } catch (sql::MethodNotImplementedException &) { /* compiled without -DWE_SUPPORT_USE_RESULT_WITH_PS */ } try { sql::SQLString input_value("latin1"); sql::SQLString output_value; con->setClientOption("characterSetResults", input_value); output_value=con->getClientOption("characterSetResults"); ASSERT_EQUALS(input_value, output_value); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } int serverVersion=getMySQLVersion(con); if ( serverVersion >= 57003) { try { sql::ConnectOptionsMap opts; int input_value=111; int output_value=2367; void * output; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["OPT_READ_TIMEOUT"]=111; created_objects.clear(); con.reset(driver->connect(opts)); output=(static_cast (&output_value)); con->getClientOption("OPT_READ_TIMEOUT", output); ASSERT_EQUALS(input_value, output_value); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { sql::ConnectOptionsMap opts; bool input_value=true; bool output_value=false; void * output; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["OPT_RECONNECT"]=input_value; created_objects.clear(); con.reset(driver->connect(opts)); output=(static_cast (&output_value)); con->getClientOption("OPT_RECONNECT", output); ASSERT_EQUALS(input_value, output_value); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { sql::ConnectOptionsMap opts; sql::SQLString input_value("../lib/plugin/"); const char *output_value="../lib/plugin/"; void * output; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["pluginDir"]=input_value; created_objects.clear(); con.reset(driver->connect(opts)); output=(static_cast (&output_value)); con->getClientOption("pluginDir", output); ASSERT_EQUALS(input_value, output_value); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } try { sql::SQLString tmp=con->getClientOption("characterSetDirectory"); tmp=con->getClientOption("readDefaultFile"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::getSessionVariable() { logMsg("connection::getSessionVariable() - MySQL_Connection::get|setSessionVariable()"); try { std::string value(""); boost::scoped_ptr< sql::mysql::MySQL_Connection > my_con(dynamic_cast (driver->connect(url, user, passwd))); value=my_con->getSessionVariable("sql_mode"); my_con->setSessionVariable("sql_mode", "ANSI"); // The server will translate ANSI into something that is version dependent - // ASSERT_EQUALS(my_con->getSessionVariable("sql_mode"), ""); my_con->setSessionVariable("sql_mode", value); ASSERT_EQUALS(value, my_con->getSessionVariable("sql_mode")); value=my_con->getSessionVariable("sql_warnings"); std::string on("ON"); std::string off("OFF"); try { my_con->setSessionVariable("sql_warnings", "0"); on="1"; off="0"; } catch (sql::SQLException &) { } try { my_con->setSessionVariable("sql_warnings", on); ASSERT_EQUALS(on, my_con->getSessionVariable("sql_warnings")); my_con->setSessionVariable("sql_warnings", off); ASSERT_EQUALS(off, my_con->getSessionVariable("sql_warnings")); } catch (sql::SQLException &) { } my_con->setSessionVariable("sql_warnings", value); ASSERT_EQUALS(value, my_con->getSessionVariable("sql_warnings")); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::getNoWarningsOnNewLine() { logMsg("connection::getNoWarningsOnNewLine() - MySQL_Connection::getWarnings()"); try { const sql::SQLWarning* warning; warning=con->getWarnings(); if (warning != NULL) FAIL("There should be no warnings on the default connection"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::invalidCredentials() { logMsg("connection::invalidCredentials() - MySQL_Connection connect"); std::string myurl("tcp://"); std::string myuser(""); std::string mypasswd(""); try { try { con.reset(driver->connect(myurl, user, passwd)); logMsg("... using invalid URL should have failed, but we can't be sure that is it an issue, because we do not know for sure what defaults a test system is using,"); con.reset(driver->connect(url, user, passwd)); } catch (sql::SQLException &/*e*/) { logMsg("... using wrong URL caused expected failure"); con.reset(driver->connect(url, user, passwd)); } if (!url.empty()) { try { con.reset(driver->connect("", user, passwd)); logMsg("... using empty URL should have failed, but we can't be sure that is it an issue, because we do not know for sure what defaults a test system is using,"); con.reset(driver->connect(url, user, passwd)); } catch (sql::SQLException &) { logMsg("... using empty URL caused expected failure"); con.reset(driver->connect(url, user, passwd)); try { con.reset(driver->connect("", user, passwd)); FAIL("Should have caused exception"); } catch (sql::SQLException &) { } } } if (user.empty()) { myuser.append("H17ba76inosuchuser"); try { con.reset(driver->connect(url, myuser, passwd)); FAIL("... using invalid user should cause failure"); } catch (sql::SQLException &) { logMsg("... using wrong URL caused expected failure"); con.reset(driver->connect(url, user, passwd)); try { con.reset(driver->connect(url, myuser, passwd)); FAIL("Should have caused exception"); } catch (sql::SQLException &) { } } } else { /* Its a guess, but usually such a user won't exist... */ myuser.append(user); myuser.append(user); try { con.reset(driver->connect(url, myuser, myuser)); FAIL("... using invalid user should have failed"); } catch (sql::SQLException &) { logMsg("... using wrong user caused expected failure"); con.reset(driver->connect(url, user, passwd)); try { con.reset(driver->connect(url, myuser, myuser)); FAIL("Should have caused exception"); } catch (sql::SQLException &) { } } } if (passwd.empty()) { mypasswd.append("27jahjk327ahime27879xas"); try { con.reset(driver->connect(url, user, mypasswd)); FAIL("... using invalid password should cause failure"); } catch (sql::SQLException &) { logMsg("... using wrong password caused expected failure"); con.reset(driver->connect(url, user, passwd)); try { con.reset(driver->connect(url, user, mypasswd)); FAIL("Should have caused exception"); } catch (sql::SQLException &) { } } } else { mypasswd.append(passwd); mypasswd.append(passwd); try { con.reset(driver->connect(url, user, mypasswd)); FAIL("... using invalid password should have failed"); } catch (sql::SQLException &) { logMsg("... using wrong password caused expected failure"); con.reset(driver->connect(url, user, passwd)); try { con.reset(driver->connect(url, user, mypasswd)); FAIL("Should have caused exception"); } catch (sql::SQLException &) { } } } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::getNoWarningsAfterClear() { logMsg("connection::getNoWarningsAfterClear() - MySQL_Connection::getWarnings()"); try { const sql::SQLWarning* warning; /* TODO: pointless test as there is no warning before running clearWarnings() */ con->clearWarnings(); warning=con->getWarnings(); if (warning != NULL) FAIL("There should be no warnings on the default connection"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::checkClosed() { logMsg("connection::checkClosed - MySQL_Connection::close, isClosed() and internal check_closed()"); try { if (con->isClosed()) FAIL("Connection should not be reported as closed"); con->close(); if (!con->isClosed()) FAIL("Connection should be closed"); try { con->rollback(); } catch (sql::SQLException &e) { std::string reason(exceptionIsOK(e, "HY000", 0)); if (!reason.empty()) fail(reason.c_str(), __FILE__, __LINE__); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::connectUsingMapWrongTypes() { logMsg("connection::connectUsingMapWrongTypes - using map to pass connection parameters but parameter of wrong type"); try { sql::ConnectOptionsMap connection_properties; bool boolval=true; std::string strval(""); try { connection_properties["hostName"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception I"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("hostName"); connection_properties["hostName"]=url; try { connection_properties["userName"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception II"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("userName"); connection_properties["userName"]=user; try { connection_properties["password"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception III"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("password"); connection_properties["password"]=passwd; try { connection_properties["port"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception IV"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("port"); try { connection_properties["socket"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception V"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("socket"); try { connection_properties["pipe"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception VI"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("pipe"); try { connection_properties["schema"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception VII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("schema"); try { connection_properties["characterSetResults"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception VIII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("characterSetResults"); try { connection_properties["sslKey"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception IX"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslKey"); try { connection_properties["sslCert"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception X"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslCert"); try { connection_properties["sslCA"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XI"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslCA"); try { connection_properties["sslCAPath"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslCAPath"); try { connection_properties["sslCipher"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XIII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslCipher"); /* TODO -- will be moved into driver class. try { connection_properties["clientlib"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XIV"); } catch (sql::InvalidArgumentException) { expected } connection_properties.erase("clientlib"); */ try { connection_properties["defaultStatementResultType"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XV"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("defaultStatementResultType"); try { connection_properties["metadataUseInfoSchema"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XVI"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("metadataUseInfoSchema"); try { connection_properties["CLIENT_COMPRESS"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XVII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_COMPRESS"); try { connection_properties["CLIENT_FOUND_ROWS"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XVIII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_FOUND_ROWS"); try { connection_properties["CLIENT_IGNORE_SIGPIPE"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XIX"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_IGNORE_SIGPIPE"); try { connection_properties["CLIENT_IGNORE_SPACE"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XX"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_IGNORE_SPACE"); try { connection_properties["CLIENT_INTERACTIVE"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXI"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_INTERACTIVE"); try { connection_properties["CLIENT_LOCAL_FILES"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_LOCAL_FILES"); try { connection_properties["CLIENT_MULTI_STATEMENTS"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXIII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_MULTI_STATEMENTS"); try { connection_properties["CLIENT_NO_SCHEMA"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXIV"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("CLIENT_NO_SCHEMA"); try { connection_properties["OPT_CONNECT_TIMEOUT"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXV"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("OPT_CONNECT_TIMEOUT"); try { connection_properties["OPT_READ_TIMEOUT"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXVI"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("OPT_READ_TIMEOUT"); try { connection_properties["OPT_WRITE_TIMEOUT"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXVII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("OPT_WRITE_TIMEOUT"); try { connection_properties["OPT_RECONNECT"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXVIII"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("OPT_RECONNECT"); try { connection_properties["OPT_CHARSET_NAME"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXIX"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("OPT_CHARSET_NAME"); try { connection_properties["OPT_REPORT_DATA_TRUNCATION"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXX"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("OPT_REPORT_DATA_TRUNCATION"); try { connection_properties["sslVerify"]=(strval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXXI - sslVerify"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslVerify"); try { connection_properties["sslCRL"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXXII - sslCRL"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslCRL"); try { connection_properties["sslCRLPath"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXXIII - sslCRLPath"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("sslCRLPath"); try { connection_properties["rsaKey"]=(boolval); created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("No exception XXXIII - rsaKey"); } catch (sql::InvalidArgumentException) { /* expected */ } connection_properties.erase("rsaKey"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::connectUsingMap() { logMsg("connection::connectUsingMap - using map to pass connection parameters"); try { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; bool bval= !TestsRunner::getStartOptions()->getBool("dont-use-is"); connection_properties["metadataUseInfoSchema"]=(bval); created_objects.clear(); con.reset(driver->connect(connection_properties)); /* The property map now contains the minimum required entries and it works. Lets play with so-to-say optional entries. */ /* 1) Port */ connection_properties.erase("port"); { int port= -1; if (url.compare(0, sizeof ("tcp://") - 1, "tcp://") == 0) { size_t port_pos; port_pos=url.find_last_of(":", std::string::npos); if (port_pos != std::string::npos) port=atoi(url.substr(port_pos + 1, std::string::npos).c_str()); if (port == -1) { /* The user is using TCP/IP and default port 3306 */ connection_properties["password"]=(port); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); FAIL("Connect works with invalid port of -1"); } catch (sql::SQLException &e) { std::string reason(exceptionIsOK(e, "HY000", 2003)); logErr(reason); } } else { /* The user is using TCP/IP and has specified the port. A port setting shall NOT overrule the setting from the URL */ port= -1; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { FAIL("URL shall overrule port setting"); } } } else { /* We must be using a socket connection - all port settings shall be ignored */ connection_properties["port"]=(port); /* Must not throw an exception */ try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { FAIL("Port setting should be ignored, using Unix socket!"); } } } connection_properties.erase("port"); /* 2) Socket */ connection_properties.erase("socket"); { std::string socket(""); #ifndef CPPWIN_WIN32 if (url.compare(0, sizeof ("unix://") - 1, "unix://") == 0) { // Unix socket connection socket="I hope this is invalid"; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { FAIL("Socket setting should be ignored, socket is part of the URL"); } } else #endif if (url.compare(0, sizeof ("tcp://") - 1, "tcp://") == 0) { // TCP/IP connection, socket shall be ignored socket="I hope this is invalid"; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { FAIL("Socket setting should be ignored because its a TCP/IP connection"); } } } connection_properties.erase("socket"); /* 2) Schema */ connection_properties.erase("schema"); { std::string schema(""); std::string myschema("mysql"); std::string retschema(""); if (url.compare(0, sizeof ("tcp://") - 1, "tcp://") == 0) { // TCP/IP connection - schema cannot be set when using unix socket syntax size_t schema_pos; std::string host(url.substr(sizeof ("tcp://") - 1, std::string::npos)); schema_pos=host.find("/"); if (schema_pos != std::string::npos) { schema_pos++; schema=host.substr(schema_pos, host.size() - schema_pos); } } if (schema.empty()) { logMsg("... schema not set through the URL"); connection_properties[std::string("schema")]=schema; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); schema=con->getSchema(); if (!schema.empty()) FAIL("Empty schama specified but certain schema selected upon connect"); } catch (sql::SQLException &) { FAIL("Connect should have worked although schema property set to empty string"); } logMsg("... trying to connect to mysql schema, may or may not work"); connection_properties.erase("schema"); connection_properties["schema"]=(myschema); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); Connection mycon(driver->connect(connection_properties)); retschema=mycon->getSchema(); if (retschema != myschema) { logErr(retschema); logErr(myschema); logErr(mycon->getCatalog()); logErr(mycon->getSchema()); FAIL("Connected to schema mysql but getSchema() reports different schema"); } } catch (sql::SQLException &) { logMsg("... cannot connect to mysql schema but that is OK, might be insufficient grants"); } } else { /* schema is set in the TCP/IP url */ logMsg("... schema is set in the URL and property shall be ignored"); /* no property set */ try { created_objects.clear(); con.reset(driver->connect(connection_properties)); retschema=con->getSchema(); if (retschema != schema) { logErr(retschema); logErr(schema); FAIL("Connected to a certain schema but getSchema() reports different schema"); } } catch (sql::SQLException &) { FAIL("Connect should not fail"); } /* property set */ connection_properties["schema"]=(myschema); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); retschema=con->getSchema(); if (retschema != schema) { logErr(retschema); logErr(schema); FAIL("Connected to a certain schema but getSchema() reports different schema"); } } catch (sql::SQLException &) { FAIL("Connect should not fail"); } } } connection_properties.erase("schema"); /* 3) ssl* */ connection_properties.erase("sslKey"); connection_properties.erase("sslCert"); connection_properties.erase("sslCA"); connection_properties.erase("sslCAPath"); connection_properties.erase("sslCipher"); { logMsg("... setting bogus SSL properties"); std::string sql("ramdom bogus value"); connection_properties["sslKey"]=(sql); connection_properties["sslCert"]=(sql); connection_properties["sslCA"]=(sql); connection_properties["sslCAPath"]=(sql); connection_properties["sslCipher"]=(sql); /* mysql_ssl_set is silly: This function always returns 0. If SSL setup is incorrect, mysql_real_connect() returns an error when you attempt to connect. */ try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("sslKey"); connection_properties.erase("sslCert"); connection_properties.erase("sslCA"); connection_properties.erase("sslCAPath"); connection_properties.erase("sslCipher"); /* All the CLIENT* are pointless. There is no way (yet) to verify the settings */ /* 4) CLIENT_COMPRESS */ connection_properties.erase("CLIENT_COMPRESS"); { logMsg("... testing CLIENT_COMPRESS"); connection_properties["CLIENT_COMPRESS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_COMPRESS"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_COMPRESS"); /* 5) CLIENT_FOUND_ROWS */ connection_properties.erase("CLIENT_FOUND_ROWS"); { logMsg("... testing CLIENT_FOUND_ROWS"); connection_properties["CLIENT_FOUND_ROWS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_FOUND_ROWS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_FOUND_ROWS"); connection_properties["CLIENT_FOUND_ROWS"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_FOUND_ROWS"); /* 6) CLIENT_IGNORE_SIGPIPE */ connection_properties.erase("CLIENT_IGNORE_SIGPIPE"); { logMsg("... testing CLIENT_IGNORE_SIGPIPE"); connection_properties["CLIENT_IGNORE_SIGPIPE"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_IGNORE_SIGPIPE"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_IGNORE_SIGPIPE"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_IGNORE_SIGPIPE"); /* 7) CLIENT_IGNORE_SPACE */ connection_properties.erase("CLIENT_IGNORE_SPACE"); { logMsg("... testing CLIENT_IGNORE_SPACE"); connection_properties["CLIENT_IGNORE_SPACE"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_IGNORE_SPACE"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_IGNORE_SPACE"); connection_properties["CLIENT_IGNORE_SPACE"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_IGNORE_SPACE"); /* 8) CLIENT_INTERACTIVE */ connection_properties.erase("CLIENT_INTERACTIVE"); { logMsg("... testing CLIENT_INTERACTIVE"); connection_properties["CLIENT_INTERACTIVE"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_INTERACTIVE"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_INTERACTIVE"); connection_properties["CLIENT_INTERACTIVE"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_INTERACTIVE"); /* 9) CLIENT_LOCAL_FILES */ /* TODO - add proper test */ connection_properties.erase("CLIENT_LOCAL_FILES"); { logMsg("... testing CLIENT_LOCAL_FILES"); connection_properties["CLIENT_LOCAL_FILES"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_LOCAL_FILES"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_LOCAL_FILES"); connection_properties["CLIENT_LOCAL_FILES"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_LOCAL_FILES"); /* 10) CLIENT_MULTI_RESULTS */ /* TODO - add proper test */ connection_properties.erase("CLIENT_MULTI_RESULTS"); { logMsg("... testing CLIENT_MULTI_RESULTS"); connection_properties["CLIENT_MULTI_RESULTS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_MULTI_RESULTS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_MULTI_RESULTS"); connection_properties["CLIENT_MULTI_RESULTS"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_MULTI_RESULTS"); /* 11) CLIENT_MULTI_STATEMENTS */ /* TODO: add proper test */ connection_properties.erase("CLIENT_MULTI_STATEMENTS"); { logMsg("... testing CLIENT_MULTI_STATEMENTS"); connection_properties["CLIENT_MULTI_STATEMENTS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_MULTI_STATEMENTS"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_MULTI_STATEMENTS"); connection_properties["CLIENT_MULTI_STATEMENTS"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_MULTI_STATEMENTS"); /* 12) CLIENT_NO_SCHEMA */ connection_properties.erase("CLIENT_NO_SCHEMA"); { logMsg("... testing CLIENT_NO_SCHEMA"); connection_properties["CLIENT_NO_SCHEMA"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties["CLIENT_NO_SCHEMA"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } connection_properties.erase("CLIENT_NO_SCHEMA"); connection_properties["CLIENT_NO_SCHEMA"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &) { } } connection_properties.erase("CLIENT_NO_SCHEMA"); /* 13) MYSQL_OPT_CONNECT_TIMEOUT */ connection_properties.erase("OPT_CONNECT_TIMEOUT"); { logMsg("... testing OPT_CONNECT_TIMEOUT"); /* C-API does not care about the actual value, its passed down to the OS, The OS may or may not detect bogus values such as negative values. */ connection_properties["OPT_CONNECT_TIMEOUT"]=1; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_CONNECT_TIMEOUT"); /* 14) MYSQL_OPT_READ_TIMEOUT */ connection_properties.erase("OPT_READ_TIMEOUT"); { logMsg("... testing OPT_READ_TIMEOUT"); /* C-API does not care about the actual value, its passed down to the OS, The OS may or may not detect bogus values such as negative values. */ connection_properties["OPT_READ_TIMEOUT"]=1; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_READ_TIMEOUT"); /* 15) MYSQL_OPT_WRITE_TIMEOUT */ connection_properties.erase("OPT_WRITE_TIMEOUT"); { logMsg("... testing OPT_WRITE_TIMEOUT"); /* C-API does not care about the actual value */ connection_properties["OPT_WRITE_TIMEOUT"]=1; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_WRITE_TIMEOUT"); /* 16) MYSQL_OPT_RECONNECT */ connection_properties.erase("OPT_RECONNECT"); { logMsg("... testing OPT_RECONNECT"); /* C-API does not care about the actual value */ connection_properties["OPT_RECONNECT"]=true; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_RECONNECT"); /* 17) MYSQL_OPT_SET_CHARSET_NAME */ connection_properties.erase("OPT_SET_CHARSET_NAME"); { logMsg("... testing OPT_SET_CHARSET_NAME"); std::string charset("utf8"); /* C-API does not care about the actual value */ connection_properties["OPT_SET_CHARSET_NAME"]=(charset); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_SET_CHARSET_NAME"); /* 18) MYSQL_REPORT_DATA_TRUNCATION */ connection_properties.erase("REPORT_DATA_TRUNCATION"); { logMsg("... testing REPORT_DATA_TRUNCATION"); std::string charset("1"); /* C-API does not care about the actual value */ connection_properties["REPORT_DATA_TRUNCATION"]=(charset); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("REPORT_DATA_TRUNCATION"); /* 19) metadataUseInfoSchema */ connection_properties.erase("metadataUseInfoSchema"); { logMsg("... testing metadataUseInfoSchema"); connection_properties["metadataUseInfoSchema"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("metadataUseInfoSchema"); connection_properties["metadataUseInfoSchema"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("metadataUseInfoSchema"); /* 20) defaultStatementResultType */ connection_properties.erase("defaultStatementResultType"); { logMsg("... testing defaultStatementResultType"); connection_properties["defaultStatementResultType"]=(sql::ResultSet::TYPE_FORWARD_ONLY); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("defaultStatementResultType"); connection_properties["defaultStatementResultType"]=(sql::ResultSet::TYPE_SCROLL_INSENSITIVE); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("defaultStatementResultType"); connection_properties["defaultStatementResultType"]=(sql::ResultSet::TYPE_SCROLL_SENSITIVE); try { created_objects.clear(); try { con.reset(driver->connect(connection_properties)); FAIL("Bug or API change - TYPE_SCROLL_SENSITIVE is unsupported"); } catch (sql::SQLException &e) { logMsg("... expected exception because TYPE_SCROLL_SENSITIVE is unsupported!"); logMsg(e.what()); } } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("defaultStatementResultType"); #ifdef CPPWIN_WIN32 /* 21) OPT_NAMED_PIPE - handled but ignored! */ connection_properties.erase("OPT_NAMED_PIPE"); { logMsg("... testing OPT_NAMED_PIPE"); std::string pipe("IGNORED"); connection_properties["OPT_NAMED_PIPE"]=(pipe); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_NAMED_PIPE"); #endif /* 22) OPT_CHARSET_NAME = MYSQL_SET_CHARSET_NAME */ connection_properties.erase("OPT_CHARSET_NAME"); { logMsg("... testing OPT_CHARSET_NAME"); std::string charset("utf8"); connection_properties["OPT_CHARSET_NAME"]=(charset); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_CHARSET_NAME"); /* 23) OPT_REPORT_DATA_TRUNCATION */ connection_properties.erase("OPT_REPORT_DATA_TRUNCATION"); { logMsg("... testing OPT_REPORT_DATA_TRUNCATION"); connection_properties["OPT_REPORT_DATA_TRUNCATION"]=(true); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("OPT_REPORT_DATA_TRUNCATION"); connection_properties["OPT_REPORT_DATA_TRUNCATION"]=(false); try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("OPT_REPORT_DATA_TRUNCATION"); /* 24) defaultPreparedStatementResultType */ connection_properties.erase("defaultPreparedStatementResultType"); { logMsg("... testing defaultPreparedStatementResultType"); connection_properties["defaultPreparedStatementResultType"]=sql::ResultSet::TYPE_FORWARD_ONLY; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &/*e*/) { /* may not be compiled in - ignore */ } } connection_properties.erase("defaultPreparedStatementResultType"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::connectOptReconnect() { logMsg("connection::connectOptReconnect - OPT_RECONNECT"); std::stringstream msg; try { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; bool bval= !TestsRunner::getStartOptions()->getBool("dont-use-is"); connection_properties["metadataUseInfoSchema"]=(bval); logMsg("... OPT_RECONNECT disabled"); connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=false; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); con->close(); ASSERT(con->isClosed()); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); FAIL("Can create statement although connection has been closed"); } catch (sql::SQLException &/*e*/) { /* expected */ } connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=false; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); ASSERT_EQUALS(false, con->isClosed()); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } logMsg("... OPT_RECONNECT enabled"); connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=true; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); con->close(); ASSERT(con->isClosed()); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); FAIL("Can create statement although connection has been closed"); } catch (sql::SQLException &/*e*/) { /* expected */ } connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=true; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); ASSERT_EQUALS(false, con->isClosed()); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } logMsg("... OPT_RECONNECT disabled and KILL"); connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=false; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT CONNECTION_ID() as _pid")); ASSERT(res->next()); msg.str(""); msg << "KILL " << res->getInt("_pid"); try { Connection my_con(getConnection()); my_con->setSchema(db); Statement my_stmt(my_con->createStatement()); my_stmt->execute(msg.str()); logMsg("... we seem to be lucky, we have killed a connection"); logMsg(msg.str()); try { msg.str(""); msg << "USE " << db; stmt->execute(msg.str()); stmt->execute("DROP TABLE IF EXISTS test"); FAIL("Statement object is still usable"); } catch (sql::SQLException &e) { // Any error message is fine, connection should have been killed logMsg(e.what()); } } catch (sql::SQLException &/*e*/) { // KILL has failed - that is OK, we may not have permissions } connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=false; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT CONNECTION_ID() as _pid")); ASSERT(res->next()); msg.str(""); msg << "KILL " << res->getInt("_pid"); try { Connection my_con(getConnection()); my_con->setSchema(db); Statement my_stmt(my_con->createStatement()); my_stmt->execute(msg.str()); logMsg("... we seem to be lucky, we have killed a connection"); logMsg(msg.str()); try { stmt.reset(con->createStatement()); logMsg("... we got a new statement object"); stmt->execute("DROP TABLE IF EXISTS test"); FAIL("Statement object is still usable"); } catch (sql::SQLException &e) { /* Any error message is fine, connection should have been killed */ logMsg(e.what()); } } catch (sql::SQLException &/*e*/) { /* KILL has failed - that is OK, we may not have permissions */ } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::setTransactionIsolation() { logMsg("connection::setTransactionIsolation() - MySQL_Connection::setTransactionIsolation()"); bool have_innodb=false; int cant_be_changed_error= -1; int server_dependent_insert= -1; stmt.reset(con->createStatement()); try { con->setTransactionIsolation(sql::TRANSACTION_READ_COMMITTED); ASSERT_EQUALS(sql::TRANSACTION_READ_COMMITTED, con->getTransactionIsolation()); res.reset(stmt->executeQuery("SHOW VARIABLES LIKE 'tx_isolation'")); checkResultSetScrolling(res); res->next(); ASSERT_EQUALS("READ-COMMITTED", res->getString("Value")); con->setTransactionIsolation(sql::TRANSACTION_READ_UNCOMMITTED); ASSERT_EQUALS(sql::TRANSACTION_READ_UNCOMMITTED, con->getTransactionIsolation()); res.reset(stmt->executeQuery("SHOW VARIABLES LIKE 'tx_isolation'")); res->next(); ASSERT_EQUALS("READ-UNCOMMITTED", res->getString("Value")); con->setTransactionIsolation(sql::TRANSACTION_REPEATABLE_READ); ASSERT_EQUALS(sql::TRANSACTION_REPEATABLE_READ, con->getTransactionIsolation()); res.reset(stmt->executeQuery("SHOW VARIABLES LIKE 'tx_isolation'")); res->next(); ASSERT_EQUALS("REPEATABLE-READ", res->getString("Value")); con->setTransactionIsolation(sql::TRANSACTION_SERIALIZABLE); ASSERT_EQUALS(sql::TRANSACTION_SERIALIZABLE, con->getTransactionIsolation()); res.reset(stmt->executeQuery("SHOW VARIABLES LIKE 'tx_isolation'")); res->next(); ASSERT_EQUALS("SERIALIZABLE", res->getString("Value")); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { con.reset(getConnection()); stmt.reset(con->createStatement()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { con->setAutoCommit(true); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT) ENGINE = InnoDB"); have_innodb=true; } catch (sql::SQLException &) { have_innodb=false; } if (have_innodb) { try { con->setAutoCommit(false); stmt->execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"); stmt->execute("INSERT INTO test(id) VALUES (1)"); /* JDBC documentation: If this method is called while in the middle of a transaction, any changes up to that point will be committed.*/ stmt->execute("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"); // con->setTransactionIsolation(sql::TRANSACTION_REPEATABLE_READ); /* According to the JDBC docs the INSERT has been comitted and this ROLLBACK must have no impat */ con->rollback(); res.reset(stmt->executeQuery("SELECT COUNT(*) AS _num FROM test")); res->next(); server_dependent_insert=res->getInt("_num"); } catch (sql::SQLException &e) { logMsg("... EXPECTED behaviour - Transaction isolation level can't be changed while a transaction is in progress."); logMsg(e.what()); logMsg("SQLState: " + std::string(e.getSQLState())); cant_be_changed_error=e.getErrorCode(); } try { con.reset(getConnection()); stmt.reset(con->createStatement()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { con->setAutoCommit(true); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT) ENGINE = InnoDB"); con->setAutoCommit(false); con->setTransactionIsolation(sql::TRANSACTION_SERIALIZABLE); stmt->execute("INSERT INTO test(id) VALUES (1)"); /* JDBC documentation: If this method is called while in the middle of a transaction, any changes up to that point will be committed.*/ con->setTransactionIsolation(sql::TRANSACTION_REPEATABLE_READ); if (-1 != cant_be_changed_error) { FAIL("Changing the transaction level manually has caused an exception. Changing it through API has not!"); } /* According to the JDBC docs the INSERT has been comitted and this ROLLBACK must have no impat */ con->rollback(); res.reset(stmt->executeQuery("SELECT COUNT(*) AS _num FROM test")); res->next(); ASSERT_EQUALS(server_dependent_insert, res->getInt("_num")); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { if (e.getErrorCode() != cant_be_changed_error) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } else { logMsg("... EXPECTED behaviour - Transaction isolation level can't be changed while a transaction is in progress."); logMsg(e.what()); logMsg("SQLState: " + std::string(e.getSQLState())); } } } con->close(); try { con->setTransactionIsolation(sql::TRANSACTION_READ_COMMITTED); FAIL("Closed connection not detected"); } catch (sql::SQLException &) { } } void connection::rollback() { try { con->setAutoCommit(false); try { try { con->setAutoCommit(true); con->rollback(con->setSavepoint("foo")); FAIL("autoCommit mode not detected"); } catch (sql::InvalidArgumentException &e) { ASSERT_EQUALS(e.what(), "The connection is in autoCommit mode"); } } catch (sql::SQLException &) { /* no support for savepoints, bad luck... */ } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } /* Exploiting bug that different wrapper is currently created if requested for "" * and default lib name. just to test that nothing bad happens. * Test itself shouldn't fail. */ #ifndef MYSQLCLIENT_STATIC_BINDING void connection::loadSameLibraryTwice() { #if defined(_WIN32) const sql::SQLString baseName("libmysql.dll"); #elif defined(__APPLE__) const sql::SQLString baseName("libmysqlclient_r.dylib"); #elif defined(__hpux) && defined(__hppa) const sql::SQLString baseName("libmysqlclient_r.sl"); #else const sql::SQLString baseName("libmysqlclient_r.so"); #endif sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; connection_properties["clientlib"]=baseName; con.reset(driver->connect(connection_properties)); } #endif /* Test of the OPT_ENABLE_CLEARTEXT_PLUGIN connection of the text The test idea - we try to create fake PAM authorized user and try to connect using that user first without, and then with the new option selected. In first case the error has to be that cleartext plugin could not be loaded, and in second case the error has to be different */ void connection::enableClearTextAuth() { int serverVersion=getMySQLVersion(con); if ( ((serverVersion < 55027) || (serverVersion > 56000)) && (serverVersion < 56007)) { SKIP("The server does not support tested functionality(cleartext plugin enabling)"); } try { stmt->executeUpdate("DROP USER 't_ct_user'@'%'"); } catch (sql::SQLException &) { // Catching exception if user did not exist } try { stmt->executeUpdate("GRANT ALL ON 't_ct_plugin' TO 't_ct_user' IDENTIFIED WITH " "'authentication_pam'"); } catch (sql::SQLException &) { SKIP("The authentication_pam plugin not loaded"); } sql::ConnectOptionsMap opts; testsuite::Connection c2; opts["userName"]=sql::SQLString("t_ct_user"); opts["password"]=sql::SQLString("foo"); /* Expecting error CR_AUTH_PLUGIN_CANNOT_LOAD_ERROR without option ENABLE_CLEARTEXT_PLUGIN */ try { c2.reset(getConnection(&opts)); } catch (sql::SQLException &e) { /* We should have dropped the created user here if assertion fails - TODO: Add sort of dropSchemaObject for created users in tearDown */ ASSERT_EQUALS(2059, e.getErrorCode()/*CR_AUTH_PLUGIN_CANNOT_LOAD_ERROR*/); } /* Expecting error other then CR_AUTH_PLUGIN_CANNOT_LOAD_ERROR as option ENABLE_CLEARTEXT_PLUGIN is used */ opts["OPT_ENABLE_CLEARTEXT_PLUGIN"]=true; try { c2.reset(getConnection(&opts)); } catch (sql::SQLException &e) { ASSERT(e.getErrorCode() != 2059); } stmt->executeUpdate("DROP USER 't_ct_user'@'%'"); } void connection::connectAttrAdd() { logMsg("connection::connectAttr - MYSQL_OPT_CONNECT_ATTR_ADD|MYSQL_OPT_CONNECT_ATTR_DELETE"); int serverVersion=getMySQLVersion(con); if ( serverVersion < 56006) { SKIP("The server does not support tested functionality(cleartext plugin enabling)"); } try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; std::map< sql::SQLString, sql::SQLString > connectAttrMap; std::list< std::string > connectAttrList; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; connectAttrMap["keyc1"]="value1"; connectAttrMap["keyc2"]="value2"; connectAttrMap["keyc3"]="value3"; connectAttrMap["keyc4"]="value4"; connectAttrMap["keyc5"]="value5"; connectAttrList.push_back(std::string("keyc2")); connectAttrList.push_back(std::string("keyc5")); opts.erase("OPT_CONNECT_ATTR_ADD"); opts.erase("OPT_CONNECT_ATTR_DELETE"); opts["OPT_CONNECT_ATTR_ADD"]=connectAttrMap; opts["OPT_CONNECT_ATTR_DELETE"]=connectAttrList; created_objects.clear(); conn1.reset(driver->connect(opts)); stmt.reset(conn1->createStatement()); res.reset(stmt->executeQuery("SELECT ATTR_NAME, ATTR_VALUE FROM " "performance_schema.session_account_connect_attrs WHERE " "ATTR_NAME LIKE '%keyc%' ORDER BY ATTR_NAME ASC;")); ASSERT(res->next()); ASSERT_EQUALS(res->getString("ATTR_NAME"), "keyc1"); ASSERT_EQUALS(res->getString("ATTR_VALUE"), "value1"); ASSERT(res->next()); ASSERT_EQUALS(res->getString("ATTR_NAME"), "keyc3"); ASSERT_EQUALS(res->getString("ATTR_VALUE"), "value3"); ASSERT(res->next()); ASSERT_EQUALS(res->getString("ATTR_NAME"), "keyc4"); ASSERT_EQUALS(res->getString("ATTR_VALUE"), "value4"); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } /* Check for empty OPT_CONNECT_ATTR_ADD map should not result in errors */ try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; std::map< sql::SQLString, sql::SQLString > connectAttrMap; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts.erase("OPT_CONNECT_ATTR_ADD"); opts["OPT_CONNECT_ATTR_ADD"]=connectAttrMap; created_objects.clear(); conn1.reset(driver->connect(opts)); stmt.reset(conn1->createStatement()); res.reset(stmt->executeQuery("SELECT 1")); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(1), 1); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } /* Check for empty OPT_CONNECT_ATTR_DELETE list */ try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; std::map< sql::SQLString, sql::SQLString > connectAttrMap; std::list< std::string > connectAttrList; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; connectAttrMap["keya1"]="value1"; connectAttrMap["keya2"]="value2"; opts.erase("OPT_CONNECT_ATTR_ADD"); opts.erase("OPT_CONNECT_ATTR_DELETE"); opts["OPT_CONNECT_ATTR_ADD"]=connectAttrMap; opts["OPT_CONNECT_ATTR_DELETE"]=connectAttrList; created_objects.clear(); conn1.reset(driver->connect(opts)); stmt.reset(conn1->createStatement()); res.reset(stmt->executeQuery("SELECT ATTR_NAME, ATTR_VALUE FROM " "performance_schema.session_account_connect_attrs WHERE " "ATTR_NAME LIKE '%keya%' ORDER BY ATTR_NAME ASC;")); ASSERT(res->next()); ASSERT_EQUALS(res->getString("ATTR_NAME"), "keya1"); ASSERT_EQUALS(res->getString("ATTR_VALUE"), "value1"); ASSERT(res->next()); ASSERT_EQUALS(res->getString("ATTR_NAME"), "keya2"); ASSERT_EQUALS(res->getString("ATTR_VALUE"), "value2"); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } /* Check with inserting max allowed key-value pair i.e. lesser then size of performance_schema_session_connect_attrs_size */ try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; int max_count; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; created_objects.clear(); conn1.reset(driver->connect(opts)); stmt.reset(conn1->createStatement()); res.reset(stmt->executeQuery("SHOW VARIABLES LIKE " "'performance_schema_session_connect_attrs_size';")); ASSERT(res->next()); ASSERT_EQUALS(res->getString("Variable_name"), "performance_schema_session_connect_attrs_size"); int perf_conn_attr_size= res->getInt("Value"); if (perf_conn_attr_size < 512) { SKIP("The performance_schema_session_connect_attrs_size is less then 512"); } else if (perf_conn_attr_size >= 512 && perf_conn_attr_size < 1024) { max_count= 32; } else if (perf_conn_attr_size >= 1024 && perf_conn_attr_size < 2048) { max_count= 64; } else if (perf_conn_attr_size >= 2048) { max_count= 128; } try { testsuite::Connection conn2; std::map< sql::SQLString, sql::SQLString > connectAttrMap; std::list< std::string > connectAttrList; std::stringstream skey; int i; for (i=1; i <= max_count; ++i) { skey.str(""); skey << "keymu" << i; connectAttrMap[skey.str()] = "value"; } opts.erase("OPT_CONNECT_ATTR_ADD"); opts.erase("OPT_CONNECT_ATTR_DELETE"); opts["OPT_CONNECT_ATTR_ADD"]= connectAttrMap; created_objects.clear(); conn2.reset(driver->connect(opts)); stmt.reset(conn2->createStatement()); res.reset(stmt->executeQuery("SELECT ATTR_NAME, ATTR_VALUE FROM " "performance_schema.session_account_connect_attrs WHERE " "ATTR_NAME LIKE '%keymu%' ORDER BY SUBSTRING(ATTR_NAME, 6)+0 ASC;")); i=0; while (res->next()) { skey.str(""); skey << "keymu" << ++i; ASSERT_EQUALS(res->getString("ATTR_NAME"), skey.str()); ASSERT_EQUALS(res->getString("ATTR_VALUE"), "value"); } ASSERT(max_count == i); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::connectAttrReset() { logMsg("connection::connectAttr - MYSQL_OPT_CONNECT_ATTR_RESET"); int serverVersion= getMySQLVersion(con); if ( serverVersion < 50606) { SKIP("The server does not support tested functionality(cleartext plugin enabling)"); } try { testsuite::Connection conn2; sql::ConnectOptionsMap opts; std::map< sql::SQLString, sql::SQLString > connectAttrMap; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; connectAttrMap["keyd1"]="value1"; connectAttrMap["keyd2"]="value2"; connectAttrMap["keyd3"]="value3"; opts.erase("OPT_CONNECT_ATTR_ADD"); opts["OPT_CONNECT_ATTR_ADD"]=connectAttrMap; opts["OPT_CONNECT_ATTR_RESET"]=0; created_objects.clear(); conn2.reset(driver->connect(opts)); stmt.reset(conn2->createStatement()); res.reset(stmt->executeQuery("SELECT ATTR_NAME, ATTR_VALUE FROM " "performance_schema.session_account_connect_attrs WHERE " "ATTR_NAME LIKE '%keyd%' ORDER BY ATTR_NAME ASC;")); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::connectCharsetDir() { try { sql::ConnectOptionsMap opts; sql::SQLString charDir("/tmp/"); opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["charsetDir"]=charDir; created_objects.clear(); con.reset(driver->connect(opts)); sql::SQLString outDir=con->getClientOption("characterSetDirectory"); ASSERT_EQUALS(charDir, outDir); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::connectSSLEnforce() { try { sql::ConnectOptionsMap opts; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["sslEnforce"]=true; created_objects.clear(); con.reset(driver->connect(opts)); } catch (sql::SQLException &e) { ASSERT_EQUALS(2026, e.getErrorCode() /*CR_SSL_CONNECTION_ERROR*/); } } void connection::setAuthDir() { logMsg("connection::setAuthDir - MYSQL_PLUGIN_DIR"); int serverVersion=getMySQLVersion(con); if ( serverVersion >= 50703 ) { SKIP("Server version >= 5.7.3 needed to run this test"); } try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; sql::SQLString in_plugin_dir; opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; #ifdef _WIN32 in_plugin_dir=sql::SQLString("C:\test_plugin"); #else in_plugin_dir=sql::SQLString("\tmp\test_plugin"); #endif //_WIN32 opts["pluginDir"]=in_plugin_dir; created_objects.clear(); conn1.reset(driver->connect(opts)); sql::SQLString out_plugin_dir=conn1->getClientOption(sql::SQLString("pluginDir")); ASSERT_EQUALS(in_plugin_dir, out_plugin_dir); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::setDefaultAuth() { logMsg("connection::setDefaultAuth - MYSQL_DEFAULT_AUTH"); int serverVersion=getMySQLVersion(con); if ( serverVersion < 50703 ) { SKIP("Server version >= 5.7.3 needed to run this test"); } try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; sql::SQLString in_plugin_dir; sql::SQLString def_auth("test_set_default_password"); opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["defaultAuth"]=def_auth; created_objects.clear(); try { conn1.reset(driver->connect(opts)); } catch (sql::SQLException &e) { /* Error expected as trying to load unknown authentication plugin */ ASSERT_EQUALS(2059, e.getErrorCode()/*CR_AUTH_PLUGIN_CANNOT_LOAD_ERROR*/); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::localInfile() { logMsg("connection::setDefaultAuth - MYSQL_OPT_LOCAL_INFILE"); #ifdef _UNIX_ try { testsuite::Connection conn1; sql::ConnectOptionsMap opts; sql::SQLString in_plugin_dir; sql::SQLString schema("test"); std::ofstream infile; infile.open("test_infile.txt"); infile << "1,\"val1\"\n"; infile << "2,\"val2\"\n"; infile.close(); opts["hostName"]=url; opts["userName"]=user; opts["password"]=passwd; opts["schema"]=schema; opts["OPT_LOCAL_INFILE"]=1; created_objects.clear(); conn1.reset(driver->connect(opts)); stmt.reset(conn1->createStatement()); stmt->execute("DROP TABLE IF EXISTS test_local_infile"); stmt->execute("CREATE TABLE test_local_infile(id INT, value VARCHAR(20))"); stmt->execute("LOAD DATA LOCAL INFILE 'test_infile.txt' " "INTO TABLE test_local_infile FIELDS TERMINATED BY ',' OPTIONALLY " "ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); res.reset(stmt->executeQuery("SELECT * FROM test_local_infile ORDER BY id ASC;")); ASSERT(res->next()); ASSERT_EQUALS("1", res->getInt(1)); ASSERT_EQUALS("val1", res->getString(2)); ASSERT(res->next()); ASSERT_EQUALS("2", res->getInt(1)); ASSERT_EQUALS("val2", res->getString(2)); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } #endif //_UNIX_ } void connection::isValid() { logMsg("connection::isValid"); try { if (!con->isValid()) { FAIL("Connection is not active"); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connection::reconnect() { logMsg("connection::connectOptReconnect - OPT_RECONNECT"); logMsg("OPT_RECONNECT disabled"); try { try { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; connection_properties["OPT_READ_TIMEOUT"]=1; connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=false; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT sleep(10);")); FAIL("Connection didn't timed out"); } catch (sql::SQLException /*&e*/) { ASSERT(con->reconnect()); res.reset(stmt->executeQuery("SELECT 1;")); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(1), 1); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } logMsg("OPT_RECONNECT enabled"); try { try { sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; connection_properties["OPT_READ_TIMEOUT"]=1; connection_properties.erase("OPT_RECONNECT"); connection_properties["OPT_RECONNECT"]=true; created_objects.clear(); con.reset(driver->connect(connection_properties)); con->setSchema(db); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT sleep(10);")); FAIL("Connection didn't timed out"); } catch (sql::SQLException /*&e*/) { ASSERT(con->reconnect()); res.reset(stmt->executeQuery("SELECT 1;")); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(1), 1); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } } /* namespace connection */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/connection.h000644 015771 000012 00000013362 12645244437 023674 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class connection : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(connection) { TEST_CASE(getClientInfo); TEST_CASE(getClientOption); TEST_CASE(getSessionVariable); TEST_CASE(getNoWarningsOnNewLine); TEST_CASE(getNoWarningsAfterClear); TEST_CASE(checkClosed); TEST_CASE(connectUsingMap); TEST_CASE(connectUsingMapWrongTypes); TEST_CASE(connectOptReconnect); TEST_CASE(invalidCredentials); TEST_CASE(setTransactionIsolation); TEST_CASE(rollback); /* TODO: do we want to add this to sql::Connection? TEST_CASE(setSessionVariable); */ // Test doesn't make sense for static binding. #ifndef MYSQLCLIENT_STATIC_BINDING TEST_CASE(loadSameLibraryTwice); #endif TEST_CASE(enableClearTextAuth); TEST_CASE(connectAttrAdd); TEST_CASE(connectAttrReset); TEST_CASE(connectCharsetDir); TEST_CASE(connectSSLEnforce); TEST_CASE(setAuthDir); TEST_CASE(setDefaultAuth); TEST_CASE(localInfile); TEST_CASE(isValid); TEST_CASE(reconnect); } /** * Test const std::string& MySQL_Connection::getClientInfo(const std::string&) * * Not part of the JDBC specs? Always returns "cppconn". */ void getClientInfo(); /** * Test getClientOption, setClientOption * * Not part of the JDBC specs? Only supports metadataUseInfoSchema */ void getClientOption(); /** * Test getSessionVariable, setSessionVariable * * Not part of the JDBC specs? */ void getSessionVariable(); /** * Ensure that tests get a connection without any warnings * * Call the function on a clean line, it should return NULL. */ void getNoWarningsOnNewLine(); /** * Check if MySQL_Connection::clearWarnings() really cleans warnings reported by MySQL_Connection::getWarnings() * * TODO: THe test method should cause a warning to be able to verify that * clearWarnings() really clears the warnings... */ void getNoWarningsAfterClear(); /* * Check if MySQL_Connection::rollback() recognizes a closed connection * * NOTE: This is a little hack to reach the internal * MySQL_Connection::checkClosed() method. */ void checkClosed(); /* * Use a map to establish a connection but passing wrong types * * Pretty similar to connectUsingMap but just consistenly wrong types */ void connectUsingMapWrongTypes(); /* * Use a map to establish a connection * * This one does not check if the connection settings passed do anything * meaningful. It here to ensure that one can pass a certain setting. The * impact of a setting shall be tested by other dedicated test methods. */ void connectUsingMap(); /* * OPT_RECONNECT * * Check if it does what it is supposed to do */ void connectOptReconnect(); /* * Test of MySQL_Connection::setSessionVariable() * * TODO: do we want to add this to sql::Connection? * Focus on code coverage * void setSessionVariable(); */ /** * Establish a connection with invalid credentials * * */ void invalidCredentials(); /* * Test of MySQL_Connection::setTransactionIsolation() * */ void setTransactionIsolation(); /* * Test of rollback to savepoint with autocommit turned on */ void rollback(); #ifndef MYSQLCLIENT_STATIC_BINDING /* * Tries to load same library twice - 1 time just by the name, 2nd time - by full path * (need to know which lib file is picked by name) * nothing should happen in the test. But crash is possible at the end of work of the program */ void loadSameLibraryTwice(); #endif void enableClearTextAuth(); /* * Test for Connection attributes options MYSQL_OPT_CONNECT_ATTR_ADD * | MYSQL_OPT_CONNECT_ATTR_DELETE */ void connectAttrAdd(); /* * Test for Connection attributes options MYSQL_OPT_CONNECT_ATTR_RESET */ void connectAttrReset(); /* * Test for Connection attributes options MYSQL_SET_CHARSET_DIR */ void connectCharsetDir(); /* * Test for Connection attributes options MYSQL_OPT_SSL_ENFORCE */ void connectSSLEnforce(); /* * Test for Connection attributes options MYSQL_PLUGIN_DIR */ void setAuthDir(); /* * Test for Connection attributes options MYSQL_DEFAULT_AUTH */ void setDefaultAuth(); /* * Test for Connection attributes options MYSQL_OPT_LOCAL_INFILE */ void localInfile(); /* * Test of MySQL_Connection::isValid() * */ void isValid(); /* * Test of MySQL_Connection::reconnect() * */ void reconnect(); }; REGISTER_FIXTURE(connection); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/connectionmetadata.cpp000644 015771 000012 00000256126 12645244437 025737 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "connectionmetadata.h" #include #include #include #include #include #include namespace testsuite { namespace classes { void connectionmetadata::getSchemata() { logMsg("connectionmetadata::getSchemata() - MySQL_ConnectionMetaData::getSchemata"); bool schema_found=false; std::stringstream msg; try { DatabaseMetaData * dbmeta=con->getMetaData(); ResultSet resdbm1(dbmeta->getSchemata()); checkResultSetScrolling(resdbm1); ResultSet resdbm2(dbmeta->getSchemaObjects(con->getCatalog(), "", "schema")); logMsg("... checking if getSchemata() and getSchemaObjects() report the same schematas"); resdbm1->beforeFirst(); while (resdbm1->next()) { schema_found=false; resdbm2->beforeFirst(); while (resdbm2->next()) if (resdbm2->getString("SCHEMA") == resdbm1->getString(1)) { schema_found=true; break; } if (!schema_found) FAIL("Schemata lists differ"); msg.str(""); msg << "... OK " << resdbm1->getString(1) << " = " << resdbm2->getString("SCHEMA"); logMsg(msg.str()); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSchemaObjects() { logMsg("connectionmetadata::getSchemaObject() - MySQL_ConnectionMetaData::getSchemaObjects"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ResultSet resdbm1(dbmeta->getSchemaObjects()); checkResultSetScrolling(resdbm1); ResultSet resdbm2; while (resdbm1->next()) { resdbm2.reset(dbmeta->getSchemaObjects(con->getCatalog(), "", resdbm1->getString(1))); checkResultSetScrolling(resdbm2); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getAttributes() { logMsg("connectionmetadata::getAttributes() - MySQL_ConnectionMetaData::getAttributes"); unsigned int i; std::vector::iterator it; std::stringstream msg; try { DatabaseMetaData * dbmeta=con->getMetaData(); res.reset(dbmeta->getAttributes(con->getCatalog(), con->getSchema(), "", "")); checkResultSetScrolling(res); ResultSetMetaData * resmeta=res->getMetaData(); it=attributes.begin(); for (i=1; i <= resmeta->getColumnCount(); i++) { if (it == attributes.end()) FAIL("There are more columns than expected"); ASSERT_EQUALS(it->name, resmeta->getColumnName(i)); msg.str(""); msg << "... OK found column " << it->name; logMsg(msg.str()); it++; } if (it != attributes.end()) FAIL("There are less columns than expected"); res.reset(dbmeta->getAttributes("ABC", "DEF", "GHI", "JKL")); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getBestRowIdentifier() { logMsg("connectionmetadata::getBestRowIdentifier() - MySQL_ConnectionMetaData::getBestRowIdentifier"); std::vector::iterator it; std::stringstream msg; bool got_warning=false; try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); logMsg("... looping over all kinds of column types"); for (it=columns.begin(); it != columns.end(); it++) { stmt->execute("DROP TABLE IF EXISTS test"); msg.str(""); msg << "CREATE TABLE test(id " << it->sqldef << ", PRIMARY KEY(id))"; try { stmt->execute(msg.str()); } catch (sql::SQLException &) { msg.str(""); msg << "... skipping " << it->sqldef; logMsg(msg.str()); continue; } res.reset(dbmeta->getBestRowIdentifier(con->getCatalog(), con->getSchema(), "test", 0, false)); checkResultSetScrolling(res); ASSERT_EQUALS(true, res->next()); ASSERT_EQUALS(DatabaseMetaData::bestRowSession, res->getInt(1)); ASSERT_EQUALS(res->getInt(1), res->getInt("SCOPE")); ASSERT_EQUALS("id", res->getString(2)); ASSERT_EQUALS(res->getInt(2), res->getInt("COLUMN_NAME")); if (it->ctype != res->getInt(3)) { msg.str(""); msg << "... \t\tWARNING - check DATA_TYPE for " << it->sqldef; msg << " - expecting type " << it->ctype << " got " << res->getInt(3); logMsg(msg.str()); ResultSet cres(stmt->executeQuery("SHOW CREATE TABLE test")); cres->next(); logMsg(cres->getString(2).c_str()); got_warning=true; } // TODO - ASSERT_EQUALS(it->ctype, res->getInt(3)); ASSERT_EQUALS(res->getInt(3), res->getInt("DATA_TYPE")); if (it->name != res->getString(4)) { msg.str(""); msg << "... \t\tWARNING - check DATA_TYPE for " << it->sqldef; msg << " - expecting type name " << it->name << " got " << res->getString(4); logMsg(msg.str()); got_warning=true; } // TODO - ASSERT_EQUALS(it->name, res->getString(4)); ASSERT_EQUALS(res->getString(4), res->getString("TYPE_NAME")); if (it->precision != res->getUInt64(5)) { msg.str(""); msg << "... \t\tWARNING - check COLUMN_SIZE for " << it->sqldef; msg << " - expecting pecision " << it->precision << " got " << res->getInt(5); logMsg(msg.str()); got_warning=true; } // TODO - ASSERT_EQUALS(it->precision, res->getInt(5)); ASSERT_EQUALS(res->getInt(5), res->getInt("COLUMN_SIZE")); ASSERT_EQUALS(0, res->getInt(6)); ASSERT_EQUALS(res->getInt(6), res->getInt("BUFFER_LENGTH")); if (it->decimal_digits != res->getInt(7)) { msg.str(""); msg << "... \t\tWARNING - check DECIMAL_DIGITS for " << it->sqldef; msg << " - expecting decimal digits = " << it->decimal_digits << " got " << res->getInt(7); logMsg(msg.str()); got_warning=true; } ASSERT_EQUALS(res->getInt(7), res->getInt("DECIMAL_DIGITS")); ASSERT_EQUALS(DatabaseMetaData::bestRowNotPseudo, res->getInt(8)); ASSERT_EQUALS(res->getInt(8), res->getInt("PSEUDO_COLUMN")); stmt->execute("DROP TABLE IF EXISTS test"); } if (got_warning) { FAIL("See Warnings!"); } stmt->execute("DROP TABLE IF EXISTS test"); // TODO - stmt->execute("CREATE TABLE test(col1 INT NOT NULL, col2 INT NOT NULL, PRIMARY KEY(col1, col2))"); res.reset(dbmeta->getBestRowIdentifier(con->getCatalog(), con->getSchema(), "test", 0, false)); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getColumnPrivileges() { logMsg("connectionmetadata::getColumnPrivileges() - MySQL_ConnectionMetaData::getColumnPrivileges"); int rows=0; bool got_warning=false; std::stringstream msg; try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col1 INT, col2 INT)"); DatabaseMetaData * dbmeta=con->getMetaData(); res.reset(dbmeta->getColumnPrivileges(con->getCatalog(), con->getSchema(), "test", "id")); ASSERT_EQUALS(false, res->next()); res.reset(dbmeta->getColumnPrivileges(con->getCatalog(), con->getSchema(), "test", "col%")); checkResultSetScrolling(res); rows=0; while (res->next()) { rows++; if (con->getCatalog() != "" && res->getString(1) != "" && con->getCatalog() != res->getString(1)) { got_warning=true; msg.str(""); msg << "... TABLE_CAT: expecting '" << con->getCatalog() << "' got "; msg << "'" << res->getString(1) << "'"; logMsg(msg.str()); } ASSERT_EQUALS(res->getString(1), res->getString("TABLE_CAT")); ASSERT_EQUALS(con->getSchema(), res->getString(2)); ASSERT_EQUALS(res->getString(2), res->getString("TABLE_SCHEM")); ASSERT_EQUALS("test", res->getString(3)); ASSERT_EQUALS(res->getString(3), res->getString("TABLE_NAME")); ASSERT_EQUALS(res->getString(4), res->getString("COLUMN_NAME")); ASSERT_EQUALS("", res->getString(5)); ASSERT_EQUALS(res->getString(5), res->getString("GRANTOR")); ASSERT_EQUALS(res->getString(6), res->getString("GRANTEE")); ASSERT_EQUALS(res->getString(7), res->getString("PRIVILEGE")); ASSERT_EQUALS(res->getString(8), res->getString("IS_GRANTABLE")); if (("NO" != res->getString(8)) && ("YES" != res->getString(8)) && ("" != res->getString(8))) { // Let's be optimistic that the column does not hold this exact value... ASSERT_EQUALS("Any of 'YES', 'NO' and empty string ''", res->getString(8)); } } ASSERT_GT(2, rows); if (got_warning) { TODO("See --verbose warnings"); } res.reset(dbmeta->getColumnPrivileges(con->getCatalog(), con->getSchema(), "test", "col2")); ASSERT_EQUALS(true, res->next()); ASSERT_EQUALS("col2", res->getString("COLUMN_NAME")); ASSERT_EQUALS(res->getString(4), res->getString("COLUMN_NAME")); stmt->execute("DROP TABLE IF EXISTS test"); res.reset(dbmeta->getColumnPrivileges(con->getCatalog(), con->getSchema(), "test", "col2")); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } if (got_warning) { FAIL("TODO - See --verbose warnings"); } } void connectionmetadata::getColumns() { logMsg("connectionmetadata::getColumn() - MySQL_ConnectionMetaData::getColumns"); std::vector::iterator it; std::stringstream msg; bool got_warning=false; bool got_todo_warning=false; try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); bool isVer6=dbmeta->getDatabaseMajorVersion() == 6; logMsg("... looping over all kinds of column types"); for (it=columns.begin(); it != columns.end(); it++) { stmt->execute("DROP TABLE IF EXISTS test"); msg.str(""); msg << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(msg.str()); msg.str(""); msg << "... testing " << it->sqldef; logMsg(msg.str()); } catch (sql::SQLException &) { msg.str(""); msg << "... skipping " << it->sqldef; logMsg(msg.str()); continue; } res.reset(dbmeta->getColumns(con->getCatalog(), con->getSchema(), "test", "id")); checkResultSetScrolling(res); ASSERT_EQUALS(true, res->next()); if (con->getCatalog() != "" && res->getString(1) != "" && con->getCatalog() != res->getString("TABLE_CAT")) { got_todo_warning=true; msg.str(); msg << "...\t\tWARNING - expecting TABLE_CAT = '" << con->getCatalog() << "'"; msg << " got '" << res->getString("TABLE_CAT") << "'"; logMsg(msg.str()); } ASSERT_EQUALS(res->getString(1), res->getString("TABLE_CAT")); ASSERT_EQUALS(con->getSchema(), res->getString("TABLE_SCHEM")); ASSERT_EQUALS(res->getString(2), res->getString("TABLE_SCHEM")); ASSERT_EQUALS("test", res->getString("TABLE_NAME")); ASSERT_EQUALS(res->getString(3), res->getString("TABLE_NAME")); ASSERT_EQUALS("id", res->getString("COLUMN_NAME")); ASSERT_EQUALS(res->getString(4), res->getString("COLUMN_NAME")); if (it->ctype != res->getInt("DATA_TYPE")) { msg.str(""); msg << "... \t\tWARNING - check DATA_TYPE for " << it->sqldef; msg << " - expecting type " << it->ctype << " got " << res->getInt("DATA_TYPE"); logMsg(msg.str()); got_warning=true; } // ASSERT_EQUALS(it->ctype, res->getInt("DATA_TYPE")); ASSERT_EQUALS(res->getInt(5), res->getInt("DATA_TYPE")); if (it->name != res->getString("TYPE_NAME")) { msg.str(""); msg << "... \t\tWARNING - check TYPE_NAME for " << it->sqldef; msg << " - expecting type " << it->name << " got " << res->getString("TYPE_NAME"); logMsg(msg.str()); got_warning=true; } // ASSERT_EQUALS(it->name, res->getString("TYPE_NAME")); ASSERT_EQUALS(res->getString(6), res->getString("TYPE_NAME")); if (it->precision != res->getUInt64(7)) { msg.str(""); msg << "... \t\tWARNING - check COLUMN_SIZE for " << it->sqldef; msg << " - expecting pecision " << it->precision << " got " << res->getUInt64(7); logMsg(msg.str()); got_warning=true; } ASSERT_EQUALS(res->getInt(7), res->getInt("COLUMN_SIZE")); ASSERT_EQUALS(0, res->getInt(8)); ASSERT_EQUALS(res->getInt(8), res->getInt("BUFFER_LENGTH")); ASSERT_EQUALS(it->decimal_digits, res->getInt(9)); ASSERT_EQUALS(res->getInt(9), res->getInt("DECIMAL_DIGITS")); ASSERT_EQUALS(it->num_prec_radix, res->getInt(10)); ASSERT_EQUALS(res->getInt(10), res->getInt("NUM_PREC_RADIX")); if (it->nullable != res->getInt(11)) { msg.str(""); msg << "... \t\tWARNING - check NULLABLE for " << it->sqldef; msg << " - expecting nullable = " << it->nullable << " got " << res->getInt(11); msg << " columnNoNull = " << DatabaseMetaData::columnNoNulls << ", "; msg << " columnNullable = " << DatabaseMetaData::columnNullable << ", "; msg << " columnNullableUnknown = " << DatabaseMetaData::columnNullableUnknown; logMsg(msg.str()); got_warning=true; } ASSERT_EQUALS(it->nullable, res->getInt(11)); ASSERT_EQUALS(res->getInt(11), res->getInt("NULLABLE")); ASSERT_EQUALS(it->remarks, res->getString(12)); ASSERT_EQUALS(res->getString(12), res->getString("REMARKS")); ASSERT_EQUALS(it->column_def, res->getString(13)); ASSERT_EQUALS(res->getString(13), res->getString("COLUMN_DEF")); ASSERT_EQUALS(res->getInt(14), res->getInt("SQL_DATA_TYPE")); ASSERT_EQUALS(res->getInt(15), res->getInt("SQL_DATETIME_SUB")); if (it->char_octet_length != 0 && (it->ctype == sql::DataType::CHAR || it->ctype == sql::DataType::VARCHAR)) { size_t expected_len=it->char_octet_length; if ((it->ctype == sql::DataType::CHAR || it->ctype == sql::DataType::VARCHAR) && isVer6 && it->sqldef.find("TINYTEXT") == std::string::npos && (it->sqldef.find("utf8") != std::string::npos || it->sqldef.find("NATIONAL") != std::string::npos)) { expected_len=(expected_len / 3)*4; } if (res->getUInt64(16) != expected_len) { msg.str(""); msg << "... \t\tWARNING - check CHAR_OCTET_LENGTH for " << it->sqldef; msg << " - expecting char_octet_length " << it->char_octet_length << " got " << res->getUInt64(16); logMsg(msg.str()); got_warning=true; } } ASSERT_EQUALS(res->getUInt64(16), res->getUInt64("CHAR_OCTET_LENGTH")); ASSERT_EQUALS(2, res->getInt(17)); ASSERT_EQUALS(res->getInt(17), res->getInt("ORDINAL_POSITION")); if (((it->nullable == DatabaseMetaData::columnNoNulls) && (res->getString(18) != "NO")) || ((it->nullable == DatabaseMetaData::columnNullable) && (res->getString(18) != "YES")) || ((it->nullable == DatabaseMetaData::columnNullableUnknown) && (res->getString(18) != ""))) { msg.str(""); msg << "... \t\tWARNING - check IS_NULLABLE for " << it->sqldef; msg << " - expecting nullable = " << it->nullable << " got is_nullable = '" << res->getInt(18) << "'"; logMsg(msg.str()); got_warning=true; } ASSERT_EQUALS(res->getString(18), res->getString("IS_NULLABLE")); ASSERT_EQUALS("", res->getString(19)); ASSERT_EQUALS(res->getString(19), res->getString("SCOPE_CATALOG")); ASSERT_EQUALS("", res->getString(20)); ASSERT_EQUALS(res->getString(20), res->getString("SCOPE_SCHEMA")); ASSERT_EQUALS("", res->getString(21)); ASSERT_EQUALS(res->getString(21), res->getString("SCOPE_TABLE")); ASSERT_EQUALS("", res->getString(22)); ASSERT_EQUALS(res->getString(22), res->getString("SOURCE_DATA_TYPE")); ASSERT_EQUALS(it->is_autoincrement, res->getString(23)); ASSERT_EQUALS(res->getString(23), res->getString("IS_AUTOINCREMENT")); stmt->execute("DROP TABLE IF EXISTS test"); } if (got_warning) FAIL("See --verbose warnings!"); if (got_todo_warning) { TODO("See --verbose warnings!"); FAIL("TODO - see --verbose warnings"); } try { bool input_value=true; bool output_value=false; void * input; void * output; stmt->execute("CREATE TABLE test(id INT,val VARCHAR(20))"); input=(static_cast (&input_value)); output=(static_cast (&output_value)); con->setClientOption("metadataUseInfoSchema", input); con->getClientOption("metadataUseInfoSchema", output); ASSERT_EQUALS(input_value, output_value); dbmeta=con->getMetaData(); res.reset(dbmeta->getColumns(con->getCatalog(), "", "test", "%")); ASSERT(res->rowsCount() == 2); input_value=false; output_value=true; con->setClientOption("metadataUseInfoSchema", input); con->getClientOption("metadataUseInfoSchema", output); ASSERT_EQUALS(input_value, output_value); dbmeta=con->getMetaData(); res.reset(dbmeta->getColumns(con->getCatalog(), "", "test", "%")); ASSERT(res->rowsCount() == 2); } catch (sql::SQLException &) { FAIL("getColumns() does not work properly for metadataUseInfoSchema"); } stmt->execute("DROP TABLE IF EXISTS test"); res.reset(dbmeta->getColumns(con->getCatalog(), con->getSchema(), "test", "id")); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getConnection() { logMsg("connectionmetadata::getConnection() - MySQL_ConnectionMetaData::getConnection"); sql::Connection *same_con; try { stmt.reset(con->createStatement()); stmt->execute("SET @this_is_my_connection_id=101"); DatabaseMetaData * dbmeta=con->getMetaData(); same_con= dbmeta->getConnection(); stmt.reset(same_con->createStatement()); res.reset(stmt->executeQuery("SELECT @this_is_my_connection_id AS _connection_id")); ASSERT(res->next()); ASSERT_EQUALS(101, res->getInt("_connection_id")); ASSERT_EQUALS(res->getInt(1), res->getInt("_connection_id")); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getDatabaseVersions() { logMsg("connectionmetadata::getDatabaseVersions() - MySQL_ConnectionMetaData::getDatabase[Minor|Major|Patch]Version()"); std::stringstream prodversion; try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_GT(2, dbmeta->getDatabaseMajorVersion()); ASSERT_LT(7, dbmeta->getDatabaseMajorVersion()); ASSERT_LT(100, dbmeta->getDatabaseMinorVersion()); ASSERT_LT(100, dbmeta->getDatabasePatchVersion()); ASSERT_EQUALS("MySQL", dbmeta->getDatabaseProductName()); prodversion.str(""); prodversion << dbmeta->getDatabaseMajorVersion() << "." << dbmeta->getDatabaseMinorVersion(); prodversion << "." << dbmeta->getDatabasePatchVersion(); if (prodversion.str().length() < dbmeta->getDatabaseProductVersion().length()) { // Check only left prefix, database could have "-alpha" or something in its product versin ASSERT_EQUALS(prodversion.str(), dbmeta->getDatabaseProductVersion().substr(0, prodversion.str().length())); } else { ASSERT_EQUALS(prodversion.str(), dbmeta->getDatabaseProductVersion()); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getDriverVersions() { logMsg("connectionmetadata::getDriverVersions() - MySQL_ConnectionMetaData::getDriver[Minor|Major|Patch]Version()"); std::stringstream prodversion; try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_GT(0, dbmeta->getDriverMajorVersion()); ASSERT_LT(2, dbmeta->getDriverMajorVersion()); if (dbmeta->getDriverMinorVersion() < 0) FAIL("getDriverMinorVersion() returns negative value."); ASSERT_LT(100, dbmeta->getDriverMinorVersion()); if (dbmeta->getDriverPatchVersion() < 0) FAIL("getDriverPatchVersion() returns negative value."); ASSERT_LT(100, dbmeta->getDriverPatchVersion()); ASSERT_EQUALS("MySQL Connector/C++", dbmeta->getDriverName()); prodversion.str(""); prodversion << dbmeta->getDriverMajorVersion() << "." << dbmeta->getDriverMinorVersion(); prodversion << "." << dbmeta->getDriverPatchVersion(); if (prodversion.str().length() < dbmeta->getDriverVersion().length()) { // Check only left prefix, Driver could have "-alpha" or something in its product versin ASSERT_EQUALS(prodversion.str(), dbmeta->getDriverVersion().substr(0, prodversion.str().length())); } else { ASSERT_EQUALS(prodversion.str(), dbmeta->getDriverVersion()); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getDefaultTransactionIsolation() { logMsg("connectionmetadata::getDefaultTransactionIsolation() - MySQL_ConnectionMetaData::getDefaultTransactionIsolation()"); int server_version; try { DatabaseMetaData * dbmeta=con->getMetaData(); server_version=(10000 * dbmeta->getDatabaseMajorVersion()) + (100 * dbmeta->getDriverMinorVersion()) + dbmeta->getDriverPatchVersion(); if (server_version < 32336) FAIL("Sorry guys - we do not support MySQL <5.1. This test will not handle this case."); ASSERT_EQUALS(sql::TRANSACTION_READ_COMMITTED, dbmeta->getDefaultTransactionIsolation()); ASSERT(sql::TRANSACTION_NONE != dbmeta->getDefaultTransactionIsolation()); ASSERT(sql::TRANSACTION_READ_UNCOMMITTED != dbmeta->getDefaultTransactionIsolation()); ASSERT(sql::TRANSACTION_REPEATABLE_READ != dbmeta->getDefaultTransactionIsolation()); ASSERT(sql::TRANSACTION_SERIALIZABLE != dbmeta->getDefaultTransactionIsolation()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getExtraNameCharacters() { logMsg("connectionmetadata::getExtraNameCharacters() - MySQL_ConnectionMetaData::getExtraNameCharacters()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS("#@", dbmeta->getExtraNameCharacters()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getIdentifierQuoteString() { logMsg("connectionmetadata::getIdentifierQuoteString() - MySQL_ConnectionMetaData::getIdentifierQuoteString()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); try { stmt->execute("SET @@sql_mode = ''"); res.reset(stmt->executeQuery("SELECT @@sql_mode AS _sql_mode")); ASSERT(res->next()); ASSERT_EQUALS("", res->getString("_sql_mode")); } catch (sql::SQLException &) { SKIP("Cannot set SQL_MODE, skipping test"); } ASSERT_EQUALS("`", dbmeta->getIdentifierQuoteString()); stmt->execute("SET @@sql_mode = 'ANSI_QUOTES,ALLOW_INVALID_DATES'"); res.reset(stmt->executeQuery("SELECT @@sql_mode AS _sql_mode")); ASSERT(res->next()); ASSERT_EQUALS("ANSI_QUOTES,ALLOW_INVALID_DATES", res->getString("_sql_mode")); ASSERT_EQUALS("\"", dbmeta->getIdentifierQuoteString()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getImportedKeys() { logMsg("connectionmetadata::getImportedKeys() - MySQL_ConnectionMetaData::getImportedKeys()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); try { stmt->execute("CREATE TABLE parent(pid INT NOT NULL, PRIMARY KEY(pid)) ENGINE=INNODB;"); stmt->execute("CREATE TABLE child(cid INT NOT NULL, cpid INT, " "INDEX idx_parent_id(cpid), FOREIGN KEY idx_parent_id(cpid) " "REFERENCES parent(pid) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(cid)) ENGINE=INNODB;"); } catch (sql::SQLException &) { SKIP("Cannot create necessary FK tables"); } int num_res=0; res.reset(dbmeta->getImportedKeys(con->getCatalog(), con->getSchema(), "parent")); ASSERT(!res->next()); res.reset(dbmeta->getImportedKeys(con->getCatalog(), con->getSchema(), "child")); checkResultSetScrolling(res); ASSERT(res->next()); logMsg("... calling checkForeignKey for child"); checkForeignKey(con, res); ASSERT(!res->next()); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); stmt->execute("CREATE TABLE parent(pid1 INT NOT NULL, pid2 INT NOT NULL, PRIMARY KEY(pid1, pid2)) ENGINE=INNODB;"); stmt->execute("CREATE TABLE child(cid INT NOT NULL, cpid2 INT, cpid1 INT, " "INDEX idx_parent_id(cpid1, cpid2), FOREIGN KEY idx_parent_id(cpid1, cpid2) " "REFERENCES parent(pid1, pid2) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(cid)) ENGINE=INNODB;"); res.reset(dbmeta->getImportedKeys(con->getCatalog(), con->getSchema(), "child")); num_res=0; while (res->next()) { num_res++; switch (num_res) { case 1: ASSERT_EQUALS("cpid1", res->getString("FKCOLUMN_NAME")); break; case 2: ASSERT_EQUALS("cpid2", res->getString("FKCOLUMN_NAME")); break; default: FAIL("Expecting only two rows"); break; } } ASSERT_EQUALS(2, num_res); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); res.reset(dbmeta->getImportedKeys(con->getCatalog(), con->getSchema(), "child")); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getExportedKeys() { logMsg("connectionmetadata::getExportedKeys() - MySQL_ConnectionMetaData::getExportedKeys()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); try { stmt->execute("CREATE TABLE parent(pid INT NOT NULL, PRIMARY KEY(pid)) ENGINE=INNODB;"); stmt->execute("CREATE TABLE child(cid INT NOT NULL, cpid INT, " "INDEX idx_parent_id(cpid), FOREIGN KEY idx_parent_id(cpid) " "REFERENCES parent(pid) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(cid)) ENGINE=INNODB;"); } catch (sql::SQLException &) { SKIP("Cannot create necessary FK tables"); } int num_res=0; res.reset(dbmeta->getExportedKeys(con->getCatalog(), con->getSchema(), "child")); ASSERT(!res->next()); res.reset(dbmeta->getExportedKeys(con->getCatalog(), con->getSchema(), "parent")); ASSERT(res->next()); logMsg("... calling checkForeignKey for parent"); checkForeignKey(con, res); ASSERT(!res->next()); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); stmt->execute("CREATE TABLE parent(pid1 INT NOT NULL, pid2 INT NOT NULL, PRIMARY KEY(pid1, pid2)) ENGINE=INNODB;"); stmt->execute("CREATE TABLE child(cid INT NOT NULL, cpid2 INT, cpid1 INT, " "INDEX idx_parent_id(cpid1, cpid2), FOREIGN KEY idx_parent_id(cpid1, cpid2) " "REFERENCES parent(pid1, pid2) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(cid)) ENGINE=INNODB;"); res.reset(dbmeta->getExportedKeys(con->getCatalog(), con->getSchema(), "parent")); checkResultSetScrolling(res); num_res=0; while (res->next()) { num_res++; switch (num_res) { case 1: ASSERT_EQUALS("cpid1", res->getString("FKCOLUMN_NAME")); break; case 2: ASSERT_EQUALS("cpid2", res->getString("FKCOLUMN_NAME")); break; default: FAIL("Expecting only two rows"); break; } } ASSERT_EQUALS(2, num_res); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); res.reset(dbmeta->getExportedKeys(con->getCatalog(), con->getSchema(), "child")); ASSERT(!res->next()); } catch (sql::MethodNotImplementedException &e) { logMsg(e.what()); SKIP("MySQL is too old, MethodNotImplementedException!"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::checkForeignKey(Connection &mycon, ResultSet &myres) { bool got_warning=false; std::stringstream msg; if (mycon->getCatalog() != "" && mycon->getCatalog() != myres->getString(1)) { got_warning=true; msg.str(""); msg << "... WARNING expecting PKTABLE_CAT = '" << mycon->getCatalog() << "'"; msg << " got '" << myres->getString(1) << "'"; logMsg(msg.str()); } ASSERT_EQUALS(myres->getString(1), myres->getString("PKTABLE_CAT")); ASSERT_EQUALS(mycon->getSchema(), myres->getString(2)); ASSERT_EQUALS(myres->getString(2), myres->getString("PKTABLE_SCHEM")); ASSERT_EQUALS("parent", myres->getString(3)); ASSERT_EQUALS(myres->getString(3), myres->getString("PKTABLE_NAME")); ASSERT_EQUALS("pid", myres->getString(4)); ASSERT_EQUALS(myres->getString(4), myres->getString("PKCOLUMN_NAME")); if (mycon->getCatalog() != "" && mycon->getCatalog() != myres->getString(5)) { got_warning=true; msg.str(""); msg << "... WARNING expecting FKTABLE_CAT = '" << mycon->getCatalog() << "'"; msg << " got '" << myres->getString(1) << "'"; logMsg(msg.str()); } ASSERT_EQUALS(myres->getString(5), myres->getString("FKTABLE_CAT")); ASSERT_EQUALS(mycon->getSchema(), myres->getString(6)); ASSERT_EQUALS(myres->getString(6), myres->getString("FKTABLE_SCHEM")); ASSERT_EQUALS("child", myres->getString(7)); ASSERT_EQUALS(myres->getString(7), myres->getString("FKTABLE_NAME")); ASSERT_EQUALS("cpid", myres->getString(8)); ASSERT_EQUALS(myres->getString(8), myres->getString("FKCOLUMN_NAME")); ASSERT_EQUALS(1, myres->getInt(9)); ASSERT_EQUALS(myres->getInt(9), myres->getInt("KEY_SEQ")); ASSERT_EQUALS((int64_t) DatabaseMetaData::importedKeyCascade, myres->getInt64(10)); ASSERT_EQUALS(myres->getInt64(10), myres->getInt64("UPDATE_RULE")); ASSERT(DatabaseMetaData::importedKeyNoAction != myres->getInt64(10)); ASSERT(DatabaseMetaData::importedKeySetNull != myres->getInt64(10)); ASSERT(DatabaseMetaData::importedKeySetDefault != myres->getInt64(10)); ASSERT(DatabaseMetaData::importedKeyRestrict != myres->getInt64(10)); ASSERT_EQUALS((int64_t) DatabaseMetaData::importedKeyCascade, myres->getInt64(11)); ASSERT_EQUALS(myres->getInt64(11), myres->getInt64("DELETE_RULE")); ASSERT(DatabaseMetaData::importedKeyNoAction != myres->getInt64(11)); ASSERT(DatabaseMetaData::importedKeySetNull != myres->getInt64(11)); ASSERT(DatabaseMetaData::importedKeySetDefault != myres->getInt64(11)); ASSERT(DatabaseMetaData::importedKeyRestrict != myres->getInt64(11)); // InnoDB should give the FK a name ASSERT("" != myres->getString("FK_NAME")); ASSERT_EQUALS(myres->getString(12), myres->getString("FK_NAME")); // TODO - not sure what value to expect ASSERT_EQUALS("PRIMARY", myres->getString("PK_NAME")); ASSERT_EQUALS(myres->getString(13), myres->getString("PK_NAME")); ASSERT_EQUALS((int64_t) DatabaseMetaData::importedKeyNotDeferrable, myres->getInt64(14)); ASSERT(DatabaseMetaData::importedKeyInitiallyDeferred != myres->getInt64(10)); ASSERT(DatabaseMetaData::importedKeyInitiallyImmediate != myres->getInt64(10)); if (got_warning) { TODO("See --verbose warnings!"); FAIL("TODO - See --verbose warnings!"); } } void connectionmetadata::getIndexInfo() { logMsg("connectionmetadata::getIndexInfo() - MySQL_ConnectionMetaData::getIndexInfo()"); std::stringstream msg; bool got_warning=false; bool got_todo_warning=false; try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col1 INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL, col4 INT, col5 INT, PRIMARY KEY(col1))"); stmt->execute("INSERT INTO test(col1, col2, col3) VALUES (1, 1, 1)"); res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", false, false)); ASSERT(res->next()); if (con->getCatalog() != "" && res->getString(1) != "" && con->getCatalog() != res->getString(1)) { got_todo_warning=true; msg.str(""); msg << "...\t\tWARNING expecting TABLE_CAT = '" << con->getCatalog() << "'"; msg << " got '" << res->getString(1) << "'"; logMsg(msg.str()); } ASSERT_EQUALS(res->getString(1), res->getString("TABLE_CAT")); ASSERT_EQUALS(con->getSchema(), res->getString(2)); ASSERT_EQUALS(res->getString(2), res->getString("TABLE_SCHEM")); ASSERT_EQUALS("test", res->getString(3)); ASSERT_EQUALS(res->getString(3), res->getString("TABLE_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT_EQUALS(res->getBoolean(4), res->getBoolean("NON_UNIQUE")); ASSERT_EQUALS(res->getString("TABLE_SCHEM"), res->getString(5)); ASSERT_EQUALS(res->getString(5), res->getString("INDEX_QUALIFIER")); ASSERT_EQUALS("PRIMARY", res->getString(6)); ASSERT_EQUALS(res->getString(6), res->getString("INDEX_NAME")); ASSERT_EQUALS(DatabaseMetaData::tableIndexOther, res->getInt(7)); ASSERT_EQUALS(res->getInt(7), res->getInt("TYPE")); ASSERT(DatabaseMetaData::tableIndexStatistic != res->getInt(7)); ASSERT(DatabaseMetaData::tableIndexClustered != res->getInt(7)); ASSERT(DatabaseMetaData::tableIndexHashed != res->getInt(7)); ASSERT_EQUALS(1, res->getInt(8)); ASSERT_EQUALS(res->getInt(8), res->getInt("ORDINAL_POSITION")); ASSERT_EQUALS("col1", res->getString(9)); ASSERT_EQUALS(res->getString(9), res->getString("COLUMN_NAME")); ASSERT_EQUALS("A", res->getString(10)); ASSERT_EQUALS(res->getString(10), res->getString("ASC_OR_DESC")); if (res->getInt(11) != 1) { got_warning=true; msg.str(""); msg << "... \t\tWARNING: There is one row in the table and PK should have a "; msg << "cardinality of 1, got " << res->getInt(11); logMsg(msg.str()); } ASSERT_EQUALS(res->getInt(11), res->getInt("CARDINALITY")); ASSERT_EQUALS(0, res->getInt(12)); ASSERT_EQUALS(res->getInt(12), res->getInt("PAGES")); ASSERT_EQUALS("", res->getString(13)); ASSERT_EQUALS(res->getString(13), res->getString("FILTER_CONDITION")); ASSERT(!res->next()); // New unique index stmt->execute("CREATE UNIQUE INDEX an_idx_col3 ON test(col3 ASC)"); res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", false, false)); checkResultSetScrolling(res); ASSERT(res->next()); ASSERT_EQUALS("an_idx_col3", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT(res->next()); ASSERT_EQUALS("PRIMARY", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT(!res->next()); // Now we have three indexes, unique PK, unique an_idx_col3 and non-unique idx_col2 stmt->execute("CREATE INDEX idx_col2 ON test(col2 ASC)"); // Show only the unique ones... res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", true, false)); ASSERT(res->next()); ASSERT_EQUALS("an_idx_col3", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT(res->next()); ASSERT_EQUALS("PRIMARY", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); if (res->next()) { got_warning=true; msg.str(""); msg << "... \t\tWARNING: requesting only unique keys but got also non-unique key "; msg << "'" << res->getString("INDEX_NAME") << "', UNIQUE = " << std::boolalpha; msg << !res->getBoolean("NON_UNIQUE"); logMsg(msg.str()); } ASSERT(!res->next()); // Another index. Should appear in the sort order prior to the idx_col2 one... // Sort order is: NON_UNIQUE, TYPE, INDEX_NAME stmt->execute("CREATE INDEX an_a_idx_col4 ON test(col4 DESC)"); res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", false, false)); ASSERT(res->next()); ASSERT_EQUALS(DatabaseMetaData::tableIndexOther, res->getInt(7)); ASSERT_EQUALS("an_idx_col3", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT(res->next()); ASSERT_EQUALS("PRIMARY", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT_EQUALS(DatabaseMetaData::tableIndexOther, res->getInt(7)); ASSERT(res->next()); ASSERT_EQUALS("an_a_idx_col4", res->getString("INDEX_NAME")); ASSERT_EQUALS(true, res->getBoolean("NON_UNIQUE")); ASSERT_EQUALS(DatabaseMetaData::tableIndexOther, res->getInt(7)); ASSERT(res->next()); ASSERT_EQUALS("idx_col2", res->getString("INDEX_NAME")); ASSERT_EQUALS(true, res->getBoolean("NON_UNIQUE")); ASSERT_EQUALS(DatabaseMetaData::tableIndexOther, res->getInt(7)); ASSERT(!res->next()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col1 INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL, col4 INT, col5 INT, PRIMARY KEY(col1))"); stmt->execute("CREATE INDEX idx_col4_col5 ON test(col5 DESC, col4 ASC)"); res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", false, false)); ASSERT(res->next()); ASSERT_EQUALS("PRIMARY", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT(res->next()); ASSERT_EQUALS("idx_col4_col5", res->getString("INDEX_NAME")); ASSERT_EQUALS("A", res->getString("ASC_OR_DESC")); ASSERT_EQUALS("col5", res->getString("COLUMN_NAME")); ASSERT_EQUALS(true, res->getBoolean("NON_UNIQUE")); ASSERT(res->next()); ASSERT_EQUALS("idx_col4_col5", res->getString("INDEX_NAME")); ASSERT_EQUALS("A", res->getString("ASC_OR_DESC")); ASSERT_EQUALS("col4", res->getString("COLUMN_NAME")); ASSERT_EQUALS(true, res->getBoolean("NON_UNIQUE")); ASSERT(!res->next()); try { stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col1 INT NOT NULL, col2 INT NOT NULL, PRIMARY KEY(col1)) ENGINE=MEMORY"); stmt->execute("CREATE INDEX idx_col2 USING HASH ON test(col2 DESC)"); res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", false, false)); ASSERT(res->next()); ASSERT_EQUALS("PRIMARY", res->getString("INDEX_NAME")); ASSERT_EQUALS(false, res->getBoolean("NON_UNIQUE")); ASSERT(res->next()); ASSERT_EQUALS("idx_col2", res->getString("INDEX_NAME")); // There is no order when using HASH ASSERT_EQUALS("", res->getString("ASC_OR_DESC")); ASSERT_EQUALS("col2", res->getString("COLUMN_NAME")); ASSERT_EQUALS(DatabaseMetaData::tableIndexHashed, res->getInt("TYPE")); ASSERT_EQUALS(true, res->getBoolean("NON_UNIQUE")); ASSERT(!res->next()); } catch (sql::SQLException &) { } stmt->execute("DROP TABLE IF EXISTS test"); res.reset(dbmeta->getIndexInfo(con->getCatalog(), con->getSchema(), "test", false, false)); ASSERT(!res->next()); if (got_warning) { FAIL("See above warnings!"); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } if (got_todo_warning) { TODO("See --verbose warnings!"); FAIL("TODO - see --verbose warnings"); } } void connectionmetadata::getLimitsAndStuff() { logMsg("connectionmetadata::getLimitsAndStuff() - MySQL_ConnectionMetaData::getLimitsAndStuff()"); std::string funcs("ASCII,BIN,BIT_LENGTH,CHAR,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT,"\ "CONCAT_WS,CONV,ELT,EXPORT_SET,FIELD,FIND_IN_SET,HEX,INSERT,"\ "INSTR,LCASE,LEFT,LENGTH,LOAD_FILE,LOCATE,LOCATE,LOWER,LPAD,"\ "LTRIM,MAKE_SET,MATCH,MID,OCT,OCTET_LENGTH,ORD,POSITION,"\ "QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX,"\ "SPACE,STRCMP,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING_INDEX,TRIM,UCASE,UPPER"); std::string sys_funcs("DATABASE,USER,SYSTEM_USER,SESSION_USER,PASSWORD,ENCRYPT,LAST_INSERT_ID,VERSION"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS(3, dbmeta->getCDBCMajorVersion()); ASSERT_EQUALS(0, dbmeta->getCDBCMinorVersion()); ASSERT_EQUALS(16777208, dbmeta->getMaxBinaryLiteralLength()); ASSERT_EQUALS(32, dbmeta->getMaxCatalogNameLength()); ASSERT_EQUALS(16777208, dbmeta->getMaxCharLiteralLength()); ASSERT_EQUALS(64, dbmeta->getMaxColumnNameLength()); ASSERT_EQUALS(64, dbmeta->getMaxColumnsInGroupBy()); ASSERT_EQUALS(16, dbmeta->getMaxColumnsInIndex()); ASSERT_EQUALS(64, dbmeta->getMaxColumnsInOrderBy()); ASSERT_EQUALS(256, dbmeta->getMaxColumnsInSelect()); ASSERT_EQUALS(512, dbmeta->getMaxColumnsInTable()); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT @@max_connections AS _max")); ASSERT(res->next()); ASSERT_EQUALS(res->getInt("_max"), dbmeta->getMaxConnections()); ASSERT_EQUALS(64, dbmeta->getMaxCursorNameLength()); ASSERT_EQUALS(256, dbmeta->getMaxIndexLength()); ASSERT_EQUALS(64, dbmeta->getMaxProcedureNameLength()); ASSERT_EQUALS(2147483639, dbmeta->getMaxRowSize()); ASSERT_EQUALS(64, dbmeta->getMaxSchemaNameLength()); stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SHOW VARIABLES LIKE 'max_allowed_packet'")); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(2) - 4, dbmeta->getMaxStatementLength()); ASSERT_EQUALS(0, dbmeta->getMaxStatements()); ASSERT_EQUALS(64, dbmeta->getMaxTableNameLength()); ASSERT_EQUALS(256, dbmeta->getMaxTablesInSelect()); ASSERT_EQUALS(16, dbmeta->getMaxUserNameLength()); ASSERT_EQUALS("ABS,ACOS,ASIN,ATAN,ATAN2,BIT_COUNT,CEILING,COS," "COT,DEGREES,EXP,FLOOR,LOG,LOG10,MAX,MIN,MOD,PI,POW," "POWER,RADIANS,RAND,ROUND,SIN,SQRT,TAN,TRUNCATE" , dbmeta->getNumericFunctions()); ASSERT_EQUALS(false, dbmeta->allProceduresAreCallable()); ASSERT_EQUALS(false, dbmeta->allTablesAreSelectable()); ASSERT_EQUALS(true, dbmeta->dataDefinitionCausesTransactionCommit()); ASSERT_EQUALS(false, dbmeta->dataDefinitionIgnoredInTransactions()); ASSERT_EQUALS(false, dbmeta->deletesAreDetected(-1)); ASSERT_EQUALS(false, dbmeta->deletesAreDetected(0)); ASSERT_EQUALS(false, dbmeta->deletesAreDetected(1)); ASSERT_EQUALS(true, dbmeta->dataDefinitionCausesTransactionCommit()); ASSERT_EQUALS(true, dbmeta->doesMaxRowSizeIncludeBlobs()); ASSERT_EQUALS(DatabaseMetaData::sqlStateSQL99, dbmeta->getSQLStateType()); ASSERT(DatabaseMetaData::sqlStateXOpen != dbmeta->getSQLStateType()); ASSERT_EQUALS(funcs, dbmeta->getStringFunctions()); ASSERT_EQUALS(sys_funcs, dbmeta->getSystemFunctions()); ASSERT_EQUALS(false, dbmeta->insertsAreDetected(-1)); ASSERT_EQUALS(false, dbmeta->insertsAreDetected(0)); ASSERT_EQUALS(false, dbmeta->insertsAreDetected(1)); ASSERT_EQUALS(true, dbmeta->isCatalogAtStart()); ASSERT_EQUALS(false, dbmeta->isReadOnly()); ASSERT_EQUALS(true, dbmeta->nullPlusNonNullIsNull()); ASSERT_EQUALS(false, dbmeta->nullsAreSortedAtEnd()); ASSERT_EQUALS(false, dbmeta->nullsAreSortedAtStart()); // KLUDGE - the code takes care of some exotic MySQL 4.x, however, we don't support 4.x ASSERT_EQUALS(false, dbmeta->nullsAreSortedHigh()); ASSERT_EQUALS(!dbmeta->nullsAreSortedLow(), dbmeta->nullsAreSortedHigh()); ASSERT_EQUALS(false, dbmeta->othersDeletesAreVisible(-1)); ASSERT_EQUALS(false, dbmeta->othersDeletesAreVisible(0)); ASSERT_EQUALS(false, dbmeta->othersDeletesAreVisible(1)); ASSERT_EQUALS(false, dbmeta->othersInsertsAreVisible(-1)); ASSERT_EQUALS(false, dbmeta->othersInsertsAreVisible(0)); ASSERT_EQUALS(false, dbmeta->othersInsertsAreVisible(1)); ASSERT_EQUALS(false, dbmeta->othersUpdatesAreVisible(-1)); ASSERT_EQUALS(false, dbmeta->othersUpdatesAreVisible(0)); ASSERT_EQUALS(false, dbmeta->othersUpdatesAreVisible(1)); ASSERT_EQUALS(false, dbmeta->ownDeletesAreVisible(-1)); ASSERT_EQUALS(false, dbmeta->ownDeletesAreVisible(0)); ASSERT_EQUALS(false, dbmeta->ownDeletesAreVisible(1)); ASSERT_EQUALS(false, dbmeta->ownInsertsAreVisible(-1)); ASSERT_EQUALS(false, dbmeta->ownInsertsAreVisible(0)); ASSERT_EQUALS(false, dbmeta->ownInsertsAreVisible(1)); ASSERT_EQUALS(false, dbmeta->ownUpdatesAreVisible(-1)); ASSERT_EQUALS(false, dbmeta->ownUpdatesAreVisible(0)); ASSERT_EQUALS(false, dbmeta->ownUpdatesAreVisible(1)); ASSERT_EQUALS(false, dbmeta->storesUpperCaseIdentifiers()); ASSERT_EQUALS(true, dbmeta->storesUpperCaseQuotedIdentifiers()); ASSERT_EQUALS(true, dbmeta->supportsAlterTableWithAddColumn()); ASSERT_EQUALS(true, dbmeta->supportsAlterTableWithDropColumn()); ASSERT_EQUALS(true, dbmeta->supportsANSI92EntryLevelSQL()); ASSERT_EQUALS(false, dbmeta->supportsANSI92FullSQL()); ASSERT_EQUALS(false, dbmeta->supportsANSI92IntermediateSQL()); ASSERT_EQUALS(true, dbmeta->supportsBatchUpdates()); ASSERT_EQUALS(false, dbmeta->supportsCatalogsInDataManipulation()); ASSERT_EQUALS(false, dbmeta->supportsCatalogsInIndexDefinitions()); ASSERT_EQUALS(false, dbmeta->supportsCatalogsInPrivilegeDefinitions()); ASSERT_EQUALS(false, dbmeta->supportsCatalogsInProcedureCalls()); ASSERT_EQUALS(false, dbmeta->supportsCatalogsInTableDefinitions()); ASSERT_EQUALS(true, dbmeta->supportsColumnAliasing()); ASSERT_EQUALS(false, dbmeta->supportsConvert()); ASSERT_EQUALS(true, dbmeta->supportsCoreSQLGrammar()); /* We support MySQL 5.1+ . It must be true */ ASSERT_EQUALS(true, dbmeta->supportsCorrelatedSubqueries()); ASSERT_EQUALS(false, dbmeta->supportsDataDefinitionAndDataManipulationTransactions()); ASSERT_EQUALS(false, dbmeta->supportsDataManipulationTransactionsOnly()); ASSERT_EQUALS(true, dbmeta->supportsDifferentTableCorrelationNames()); ASSERT_EQUALS(true, dbmeta->supportsExpressionsInOrderBy()); ASSERT_EQUALS(false, dbmeta->supportsExtendedSQLGrammar()); ASSERT_EQUALS(false, dbmeta->supportsFullOuterJoins()); ASSERT_EQUALS(true, dbmeta->supportsGetGeneratedKeys()); ASSERT_EQUALS(true, dbmeta->supportsGroupBy()); ASSERT_EQUALS(true, dbmeta->supportsGroupByBeyondSelect()); ASSERT_EQUALS(true, dbmeta->supportsGroupByUnrelated()); ASSERT_EQUALS(true, dbmeta->supportsLikeEscapeClause()); ASSERT_EQUALS(true, dbmeta->supportsLimitedOuterJoins()); ASSERT_EQUALS(true, dbmeta->supportsMinimumSQLGrammar()); ASSERT_EQUALS(true, dbmeta->supportsMultipleOpenResults()); ASSERT_EQUALS(false, dbmeta->supportsMultipleResultSets()); ASSERT_EQUALS(true, dbmeta->supportsMultipleTransactions()); ASSERT_EQUALS(false, dbmeta->supportsNamedParameters()); ASSERT_EQUALS(true, dbmeta->supportsNonNullableColumns()); ASSERT_EQUALS(false, dbmeta->supportsOpenCursorsAcrossCommit()); ASSERT_EQUALS(false, dbmeta->supportsOpenCursorsAcrossRollback()); ASSERT_EQUALS(false, dbmeta->supportsOpenStatementsAcrossCommit()); ASSERT_EQUALS(false, dbmeta->supportsOpenStatementsAcrossRollback()); ASSERT_EQUALS(false, dbmeta->supportsOrderByUnrelated()); ASSERT_EQUALS(true, dbmeta->supportsOuterJoins()); ASSERT_EQUALS(false, dbmeta->supportsPositionedDelete()); ASSERT_EQUALS(false, dbmeta->supportsPositionedUpdate()); ASSERT_EQUALS(true, dbmeta->supportsResultSetHoldability(sql::ResultSet::HOLD_CURSORS_OVER_COMMIT)); ASSERT_EQUALS(false, dbmeta->supportsResultSetHoldability(sql::ResultSet::CLOSE_CURSORS_AT_COMMIT)); ASSERT_EQUALS(true, dbmeta->supportsResultSetType(sql::ResultSet::TYPE_SCROLL_INSENSITIVE)); ASSERT_EQUALS(false, dbmeta->supportsResultSetType(sql::ResultSet::TYPE_SCROLL_SENSITIVE)); ASSERT_EQUALS(false, dbmeta->supportsResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)); /* We support MySQL 5.1+ . It must be true */ ASSERT_EQUALS(true, dbmeta->supportsSavepoints()); ASSERT_EQUALS(true, dbmeta->supportsSchemasInDataManipulation()); ASSERT_EQUALS(true, dbmeta->supportsSchemasInDataManipulation()); ASSERT_EQUALS(true, dbmeta->supportsSchemasInIndexDefinitions()); ASSERT_EQUALS(true, dbmeta->supportsSchemasInPrivilegeDefinitions()); ASSERT_EQUALS(true, dbmeta->supportsSchemasInProcedureCalls()); ASSERT_EQUALS(true, dbmeta->supportsSchemasInTableDefinitions()); /* We support MySQL 5.1+ . It must be true */ ASSERT_EQUALS(true, dbmeta->supportsSelectForUpdate()); ASSERT_EQUALS(false, dbmeta->supportsStatementPooling()); ASSERT_EQUALS(true, dbmeta->supportsStoredProcedures()); ASSERT_EQUALS(true, dbmeta->supportsSubqueriesInComparisons()); ASSERT_EQUALS(true, dbmeta->supportsSubqueriesInExists()); ASSERT_EQUALS(true, dbmeta->supportsSubqueriesInIns()); ASSERT_EQUALS(true, dbmeta->supportsSubqueriesInQuantifieds()); ASSERT_EQUALS(true, dbmeta->supportsTableCorrelationNames()); /* We support MySQL 5.1+ . It must be true */ ASSERT_EQUALS(true, dbmeta->supportsTransactionIsolationLevel(sql::TRANSACTION_NONE)); ASSERT_EQUALS(true, dbmeta->supportsTransactionIsolationLevel(sql::TRANSACTION_READ_COMMITTED)); ASSERT_EQUALS(true, dbmeta->supportsTransactionIsolationLevel(sql::TRANSACTION_READ_UNCOMMITTED)); ASSERT_EQUALS(true, dbmeta->supportsTransactionIsolationLevel(sql::TRANSACTION_REPEATABLE_READ)); ASSERT_EQUALS(true, dbmeta->supportsTransactionIsolationLevel(sql::TRANSACTION_SERIALIZABLE)); ASSERT_EQUALS(true, dbmeta->supportsTransactions()); ASSERT_EQUALS(true, dbmeta->supportsTypeConversion()); /* We support MySQL 5.1+ . It must be true */ ASSERT_EQUALS(true, dbmeta->supportsUnion()); ASSERT_EQUALS(true, dbmeta->supportsUnionAll()); ASSERT_EQUALS(false, dbmeta->updatesAreDetected(sql::ResultSet::TYPE_FORWARD_ONLY)); ASSERT_EQUALS(false, dbmeta->updatesAreDetected(sql::ResultSet::TYPE_SCROLL_INSENSITIVE)); ASSERT_EQUALS(false, dbmeta->updatesAreDetected(sql::ResultSet::TYPE_SCROLL_SENSITIVE)); ASSERT_EQUALS(false, dbmeta->usesLocalFilePerTable()); ASSERT_EQUALS(false, dbmeta->usesLocalFiles()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getPrimaryKeys() { logMsg("connectionmetadata::getPrimaryKeys() - MySQL_ConnectionMetaData::getPrimaryKeys"); int row_num; std::string catalog; std::string schema; std::stringstream msg; bool got_warning=false; try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col2 INT NOT NULL, col1 INT NOT NULL, PRIMARY KEY(col2, col1))"); // The descriptions are ordered by the column COLUMN_NAME, will they? res.reset(dbmeta->getPrimaryKeys(con->getCatalog(), con->getSchema(), "test")); checkResultSetScrolling(res); row_num=0; while (res->next()) { row_num++; if (con->getCatalog() != "" && res->getString("TABLE_CAT") != "" && con->getCatalog() != res->getString("TABLE_CAT")) { got_warning=true; msg.str(""); msg << "...\t\tWARNING expecting TABLE_CAT = '" << con->getCatalog() << "'"; msg << " got '" << res->getString("TABLE_CAT") << "'"; logMsg(msg.str()); } ASSERT_EQUALS(con->getSchema(), res->getString("TABLE_SCHEM")); ASSERT_EQUALS("test", res->getString("TABLE_NAME")); switch (row_num) { case 1: // No, ordered by KEY_SEQ ASSERT_EQUALS("col2", res->getString("COLUMN_NAME")); ASSERT_EQUALS(row_num, res->getInt("KEY_SEQ")); break; case 2: ASSERT_EQUALS("col1", res->getString("COLUMN_NAME")); ASSERT_EQUALS(row_num, res->getInt("KEY_SEQ")); break; default: FAIL("Too many PK columns reported"); break; } ASSERT_EQUALS("PRIMARY", res->getString("PK_NAME")); } ASSERT_EQUALS(2, row_num); // catalog - a string ... "" retrieves pk from tables wo catalog, NULL = catalog should not be used to narrow the search res.reset(dbmeta->getPrimaryKeys(catalog, con->getSchema(), "test")); ASSERT_EQUALS(true, res->next()); ASSERT_EQUALS("test", res->getString("TABLE_NAME")); res.reset(dbmeta->getPrimaryKeys(catalog, schema, "test")); ASSERT(!res->next()); stmt->execute("DROP TABLE IF EXISTS test"); res.reset(dbmeta->getPrimaryKeys(con->getCatalog(), con->getSchema(), "test")); ASSERT_EQUALS(false, res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } if (got_warning) { TODO("See --verbose warnings!"); FAIL("TODO - see --verbose warnings!"); } } void connectionmetadata::getProcedures() { logMsg("connectionmetadata::getProcedures() - MySQL_ConnectionMetaData::getProcedures"); bool got_warning=false; std::stringstream msg; try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); try { stmt->execute("DROP PROCEDURE IF EXISTS p1"); stmt->execute("CREATE PROCEDURE p1(OUT param1 INT) BEGIN SELECT 1 INTO param1; END"); } catch (sql::SQLException &) { SKIP("Cannot create procedure"); } // Verify if the procedure creally has been created... stmt->execute("SET @myvar = -1"); stmt->execute("CALL p1(@myvar)"); res.reset(stmt->executeQuery("SELECT @myvar AS _myvar")); ASSERT(res->next()); ASSERT_EQUALS(1, res->getInt("_myvar")); logMsg("...who is the bad guy?"); res.reset(dbmeta->getProcedures(con->getCatalog(), con->getSchema(), "p1")); checkResultSetScrolling(res); logMsg("...is it you, getProcedures()?"); ASSERT(res->next()); if (con->getCatalog() != "" && res->getString("PROCEDURE_CAT") != "" && con->getCatalog() != res->getString("PROCEDURE_CAT")) { got_warning=true; msg.str(""); msg << "\t\tWARNING expecting PROCEDURE_CAT = '" << con->getCatalog() << "'"; msg << " got '" << res->getString("PROCEDURE_CAT") << "'"; logMsg(msg.str()); } ASSERT_EQUALS(res->getString(1), res->getString("PROCEDURE_CAT")); ASSERT_EQUALS(con->getSchema(), res->getString("PROCEDURE_SCHEM")); ASSERT_EQUALS(res->getString(2), res->getString("PROCEDURE_SCHEM")); ASSERT_EQUALS("p1", res->getString(3)); ASSERT_EQUALS(res->getString(3), res->getString("PROCEDURE_NAME")); ASSERT_EQUALS("", res->getString(4)); ASSERT_EQUALS("", res->getString(5)); ASSERT_EQUALS("", res->getString(6)); ASSERT_EQUALS("", res->getString(7)); ASSERT_EQUALS(res->getString("REMARKS"), res->getString(7)); ASSERT_EQUALS(DatabaseMetaData::procedureNoResult, res->getInt("PROCEDURE_TYPE")); ASSERT(DatabaseMetaData::procedureReturnsResult != res->getInt(8)); ASSERT(DatabaseMetaData::procedureResultUnknown != res->getInt(8)); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } if (got_warning) { TODO("See --verbose warnings!"); FAIL("TODO - see --verbose warnings!"); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS void connectionmetadata::getProcedureColumns() { logMsg("connectionmetadata::getProcedureColumns() - MySQL_ConnectionMetaData::getProcedureColumns()"); int server_version; SKIP("method not implemented"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); try { stmt->execute("DROP PROCEDURE IF EXISTS p1"); stmt->execute("CREATE PROCEDURE p1(OUT param1 INT) BEGIN SELECT 1 INTO param1; END"); } catch (sql::SQLException &) { SKIP("Cannot create procedure"); } // Verify if the procedure creally has been created... stmt->execute("SET @myvar = -1"); stmt->execute("CALL p1(@myvar)"); res.reset(stmt->executeQuery("SELECT @myvar AS _myvar")); checkResultSetScrolling(res); ASSERT(res->next()); ASSERT_EQUALS(1, res->getInt("_myvar")); res.reset(dbmeta->getProcedureColumns(con->getCatalog(), con->getSchema(), "p1", "%")); server_version=(10000 * dbmeta->getDatabaseMajorVersion()) + (100 * dbmeta->getDriverMinorVersion()) + dbmeta->getDriverPatchVersion(); if (server_version < 50206) ASSERT(!res->next()); else { ASSERT(res->next()); FAIL("Theres a new I_S table PARAMETERS. The test should use it"); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } #endif void connectionmetadata::getCatalogs() { logMsg("connectionmetadata::getCatalogs() - MySQL_ConnectionMetaData::getCatalogs()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); res.reset(dbmeta->getCatalogs()); ASSERT(res->next()); ASSERT(!res->next()); ResultSetMetaData * resmeta=res->getMetaData(); /* http://java.sun.com/j2se/1.4.2/docs/api/java/sql/DatabaseMetaData.html#getCatalogs() */ ASSERT_EQUALS((unsigned int) 1, resmeta->getColumnCount()); ASSERT_EQUALS("TABLE_CAT", resmeta->getColumnLabel(1)); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getCatalogSeparator() { logMsg("connectionmetadata::getCatalogSeparator() - MySQL_ConnectionMetaData::getCatalogSeparator()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS("", dbmeta->getCatalogSeparator()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getCatalogTerm() { logMsg("connectionmetadata::getCatalogTerm() - MySQL_ConnectionMetaData::getCatalogTerm()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS("n/a", dbmeta->getCatalogTerm()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getCrossReference() { logMsg("connectionmetadata::getCrossReference() - MySQL_ConnectionMetaData::getCrossReference()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); try { stmt->execute("CREATE TABLE parent(pid INT NOT NULL, PRIMARY KEY(pid)) ENGINE=INNODB;"); stmt->execute("CREATE TABLE child(cid INT NOT NULL, cpid INT, " "INDEX idx_parent_id(cpid), FOREIGN KEY idx_parent_id(cpid) " "REFERENCES parent(pid) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(cid)) ENGINE=INNODB;"); } catch (sql::SQLException &) { SKIP("Cannot create necessary FK tables"); } logMsg("... checking parent->child"); res.reset(dbmeta->getCrossReference(con->getCatalog(), con->getSchema(), "parent", con->getCatalog(), con->getSchema(), "child")); checkResultSetScrolling(res); ASSERT(res->next()); checkForeignKey(con, res); logMsg("... checking child->parent"); stmt->execute("DROP TABLE IF EXISTS child"); stmt->execute("DROP TABLE IF EXISTS parent"); res.reset(dbmeta->getCrossReference(con->getCatalog(), con->getSchema(), "child", con->getCatalog(), con->getSchema(), "parent")); ASSERT(!res->next()); } catch (sql::MethodNotImplementedException &e) { logMsg(e.what()); SKIP("MySQL is too old, MethodNotImplementedException!"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getProcedureTerm() { logMsg("connectionmetadata::getProcedureTerm() - MySQL_ConnectionMetaData::getProcedureTerm"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS("procedure", dbmeta->getProcedureTerm()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getResultSetHoldability() { logMsg("connectionmetadata::getResultSetHoldability() - MySQL_ConnectionMetaData::getResultSetHoldability()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS(sql::ResultSet::HOLD_CURSORS_OVER_COMMIT, dbmeta->getResultSetHoldability()); ASSERT(sql::ResultSet::CLOSE_CURSORS_AT_COMMIT != dbmeta->getResultSetHoldability()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSchemaTerm() { logMsg("connectionmetadata::getSchemaTerm() - MySQL_ConnectionMetaData::getSchemaTerm()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS("database", dbmeta->getSchemaTerm()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSearchStringEscape() { logMsg("connectionmetadata::getSearchStringEscape - MySQL_ConnectionMetaData::getSearchStringEscape()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS("\\", dbmeta->getSearchStringEscape()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSQLKeywords() { logMsg("connectionmetadata::getSQLKeywords - MySQL_ConnectionMetaData::getSQLKeywords()"); std::string keywords( "ACCESSIBLE, ADD, ALL,"\ "ALTER, ANALYZE, AND, AS, ASC, ASENSITIVE, BEFORE,"\ "BETWEEN, BIGINT, BINARY, BLOB, BOTH, BY, CALL,"\ "CASCADE, CASE, CHANGE, CHAR, CHARACTER, CHECK,"\ "COLLATE, COLUMN, CONDITION, CONNECTION, CONSTRAINT,"\ "CONTINUE, CONVERT, CREATE, CROSS, CURRENT_DATE,"\ "CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,"\ "DATABASE, DATABASES, DAY_HOUR, DAY_MICROSECOND,"\ "DAY_MINUTE, DAY_SECOND, DEC, DECIMAL, DECLARE,"\ "DEFAULT, DELAYED, DELETE, DESC, DESCRIBE,"\ "DETERMINISTIC, DISTINCT, DISTINCTROW, DIV, DOUBLE,"\ "DROP, DUAL, EACH, ELSE, ELSEIF, ENCLOSED,"\ "ESCAPED, EXISTS, EXIT, EXPLAIN, FALSE, FETCH,"\ "FLOAT, FLOAT4, FLOAT8, FOR, FORCE, FOREIGN, FROM,"\ "FULLTEXT, GRANT, GROUP, HAVING, HIGH_PRIORITY,"\ "HOUR_MICROSECOND, HOUR_MINUTE, HOUR_SECOND, IF,"\ "IGNORE, IN, INDEX, INFILE, INNER, INOUT,"\ "INSENSITIVE, INSERT, INT, INT1, INT2, INT3, INT4,"\ "INT8, INTEGER, INTERVAL, INTO, IS, ITERATE, JOIN,"\ "KEY, KEYS, KILL, LEADING, LEAVE, LEFT, LIKE,"\ "LOCALTIMESTAMP, LOCK, LONG, LONGBLOB, LONGTEXT,"\ "LOOP, LOW_PRIORITY, MATCH, MEDIUMBLOB, MEDIUMINT,"\ "MEDIUMTEXT, MIDDLEINT, MINUTE_MICROSECOND,"\ "MINUTE_SECOND, MOD, MODIFIES, NATURAL, NOT,"\ "NO_WRITE_TO_BINLOG, NULL, NUMERIC, ON, OPTIMIZE,"\ "OPTION, OPTIONALLY, OR, ORDER, OUT, OUTER,"\ "OUTFILE, PRECISION, PRIMARY, PROCEDURE, PURGE,"\ "RANGE, READ, READS, READ_ONLY, READ_WRITE, REAL,"\ "REFERENCES, REGEXP, RELEASE, RENAME, REPEAT,"\ "REPLACE, REQUIRE, RESTRICT, RETURN, REVOKE, RIGHT,"\ "RLIKE, SCHEMA, SCHEMAS, SECOND_MICROSECOND, SELECT,"\ "SENSITIVE, SEPARATOR, SET, SHOW, SMALLINT, SPATIAL,"\ "SPECIFIC, SQL, SQLEXCEPTION, SQLSTATE, SQLWARNING,"\ "SQL_BIG_RESULT, SQL_CALC_FOUND_ROWS, SQL_SMALL_RESULT,"\ "SSL, STARTING, STRAIGHT_JOIN, TABLE, TERMINATED,"\ "THEN, TINYBLOB, TINYINT, TINYTEXT, TO, TRAILING,"\ "TRIGGER, TRUE, UNDO, UNION, UNIQUE, UNLOCK,"\ "UNSIGNED, UPDATE, USAGE, USE, USING, UTC_DATE,"\ "UTC_TIME, UTC_TIMESTAMP, VALUES, VARBINARY, VARCHAR,"\ "VARCHARACTER, VARYING, WHEN, WHERE, WHILE, WITH,"\ "WRITE, X509, XOR, YEAR_MONTH, ZEROFILL" \ "GENERAL, IGNORE_SERVER_IDS, MASTER_HEARTBEAT_PERIOD," \ "MAXVALUE, RESIGNAL, SIGNAL, SLOW"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS(keywords, dbmeta->getSQLKeywords()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSuperTables() { logMsg("connectionmetadata::getSuperTables - MySQL_ConnectionMetaData::getSuperTables()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); res.reset(dbmeta->getSuperTables(con->getCatalog(), con->getSchema(), "test")); checkResultSetScrolling(res); ASSERT(!res->next()); ResultSetMetaData * resmeta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 4, resmeta->getColumnCount()); ASSERT_EQUALS("TABLE_CAT", resmeta->getColumnLabel(1)); ASSERT_EQUALS("TABLE_SCHEM", resmeta->getColumnLabel(2)); ASSERT_EQUALS("TABLE_NAME", resmeta->getColumnLabel(3)); ASSERT_EQUALS("SUPERTABLE_NAME", resmeta->getColumnLabel(4)); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSuperTypes() { logMsg("connectionmetadata::getSuperTypes - MySQL_ConnectionMetaData::getSuperTypes()"); try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); res.reset(dbmeta->getSuperTypes(con->getCatalog(), con->getSchema(), "test")); checkResultSetScrolling(res); ASSERT(!res->next()); ResultSetMetaData * resmeta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 6, resmeta->getColumnCount()); ASSERT_EQUALS("TYPE_CAT", resmeta->getColumnLabel(1)); ASSERT_EQUALS("TYPE_SCHEM", resmeta->getColumnLabel(2)); ASSERT_EQUALS("TYPE_NAME", resmeta->getColumnLabel(3)); ASSERT_EQUALS("SUPERTYPE_CAT", resmeta->getColumnLabel(4)); ASSERT_EQUALS("SUPERTYPE_SCHEM", resmeta->getColumnLabel(5)); ASSERT_EQUALS("SUPERTYPE_NAME", resmeta->getColumnLabel(6)); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::classAttributes() { logMsg("connectionmetadata::classAttributes - MySQL_ConnectionMetaData class attributes"); TODO("Check if JDBC compliance requires certain values"); try { DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT_EQUALS(0, dbmeta->attributeNoNulls); ASSERT_EQUALS(1, dbmeta->attributeNullable); ASSERT_EQUALS(2, dbmeta->attributeNullableUnknown); ASSERT_EQUALS(1, dbmeta->bestRowNotPseudo); // BUG - ASSERT_EQUALS(2, dbmeta->bestRowPseudo); ASSERT_EQUALS(2, dbmeta->bestRowSession); ASSERT_EQUALS(0, dbmeta->bestRowTemporary); ASSERT_EQUALS(1, dbmeta->bestRowTransaction); ASSERT_EQUALS(0, dbmeta->bestRowUnknown); ASSERT_EQUALS(0, dbmeta->columnNoNulls); ASSERT_EQUALS(1, dbmeta->columnNullable); ASSERT_EQUALS(2, dbmeta->columnNullableUnknown); ASSERT_EQUALS(0, dbmeta->importedKeyCascade); // BUG - got 1 - ASSERT_EQUALS(5, dbmeta->importedKeyInitiallyDeferred); // BUG - got 2 - ASSERT_EQUALS(6, dbmeta->importedKeyInitiallyImmediate); ASSERT_EQUALS(3, dbmeta->importedKeyNoAction); // BUG - got 4 - ASSERT_EQUALS(7, dbmeta->importedKeyNotDeferrable); // BUG - got 5 - ASSERT_EQUALS(1, dbmeta->importedKeyRestrict); // BUG - got 6 - ASSERT_EQUALS(4, dbmeta->importedKeySetDefault); // BUG - got 7 - ASSERT_EQUALS(2, dbmeta->importedKeySetNull); // BUG - got 0 - ASSERT_EQUALS(1, dbmeta->procedureColumnIn); // BUG - got 1 - ASSERT_EQUALS(2, dbmeta->procedureColumnInOut); // BUG - got 2 - ASSERT_EQUALS(4, dbmeta->procedureColumnOut); ASSERT_EQUALS(3, dbmeta->procedureColumnResult); // BUG - got 4 - ASSERT_EQUALS(5, dbmeta->procedureColumnReturn); // BUG - got 5 - ASSERT_EQUALS(1, dbmeta->importedKeyRestrict); // BUG - got 6 - ASSERT_EQUALS(4, dbmeta->importedKeySetDefault); // BUG - got 7 - ASSERT_EQUALS(2, dbmeta->importedKeySetNull); // BUG - got 0 - ASSERT_EQUALS(1, dbmeta->procedureColumnIn); ASSERT_EQUALS(1, dbmeta->procedureColumnInOut); // BUG - got 2 - ASSERT_EQUALS(4, dbmeta->procedureColumnOut); ASSERT_EQUALS(3, dbmeta->procedureColumnResult); // BUG - got 4 - ASSERT_EQUALS(5, dbmeta->procedureColumnReturn); // BUG - got 5 - ASSERT_EQUALS(0, dbmeta->procedureColumnUnknown); // BUG - got 6 - ASSERT_EQUALS(0, dbmeta->procedureNoNulls); // BUG - got 7 - ASSERT_EQUALS(1, dbmeta->procedureNoResult); // BUG - got 8 - ASSERT_EQUALS(1, dbmeta->procedureNullable); // BUG - got 9 - ASSERT_EQUALS(0, dbmeta->procedureNullableUnknown); // BUG - got 10 - ASSERT_EQUALS(2, dbmeta->procedureResultUnknown); // BUG - got 11 - ASSERT_EQUALS(2, dbmeta->procedureReturnsResult); // BUG - got 0 - ASSERT_EQUALS(2, dbmeta->sqlStateSQL99); ASSERT_EQUALS(1, dbmeta->sqlStateXOpen); // BUG - got 0 - ASSERT_EQUALS(1, dbmeta->tableIndexClustered); // BUG - got 1 - ASSERT_EQUALS(2, dbmeta->tableIndexHashed); // BUG - got 2 - ASSERT_EQUALS(3, dbmeta->tableIndexOther); // BUG - got 3 - ASSERT_EQUALS(0, dbmeta->tableIndexStatistic); ASSERT_EQUALS(0, dbmeta->typeNoNulls); ASSERT_EQUALS(1, dbmeta->typeNullable); ASSERT_EQUALS(2, dbmeta->typeNullableUnknown); ASSERT_EQUALS(2, dbmeta->typePredBasic); ASSERT_EQUALS(1, dbmeta->typePredChar); ASSERT_EQUALS(0, dbmeta->typePredNone); ASSERT_EQUALS(3, dbmeta->typeSearchable); ASSERT_EQUALS(1, dbmeta->versionColumnNotPseudo); ASSERT_EQUALS(2, dbmeta->versionColumnPseudo); ASSERT_EQUALS(0, dbmeta->versionColumnUnknown); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getColumnsTypeConversions() { logMsg("connectionmetadata::getColumnsTypeConversions() - MySQL_ConnectionMetaData::getColumns"); std::vector::iterator it; std::stringstream msg; int i; bool got_warning; try { DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); got_warning=false; logMsg("... looping over all kinds of column types"); for (it=columns.begin(), i=0; it != columns.end(); i++, it++) { stmt->execute("DROP TABLE IF EXISTS test"); msg.str(""); msg << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(msg.str()); msg.str(""); msg << "... testing " << it->sqldef; logMsg(msg.str()); } catch (sql::SQLException &) { msg.str(""); msg << "... skipping " << it->sqldef; logMsg(msg.str()); continue; } res.reset(dbmeta->getColumns(con->getCatalog(), con->getSchema(), "test", "id")); checkResultSetScrolling(res); ASSERT_EQUALS(true, res->next()); // string -> xyz ASSERT_EQUALS("test", res->getString("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getString(3), res->getString("TABLE_NAME")); ASSERT_EQUALS(false, res->getBoolean("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getBoolean(3), res->getBoolean("TABLE_NAME")); ASSERT_EQUALS((int64_t) 0, res->getInt64("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getInt64(3), res->getInt64("TABLE_NAME")); ASSERT_EQUALS((uint64_t) 0, res->getUInt64("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getUInt64(3), res->getUInt64("TABLE_NAME")); ASSERT_EQUALS((double) 0, res->getDouble("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getDouble(3), res->getDouble("TABLE_NAME")); ASSERT_EQUALS((int) 0, res->getInt("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getInt(3), res->getInt("TABLE_NAME")); ASSERT_EQUALS((unsigned int) 0, res->getUInt("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getUInt(3), res->getUInt("TABLE_NAME")); ASSERT_EQUALS(false, res->isNull("TABLE_NAME")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->isNull(3), res->isNull("TABLE_NAME")); // integer -> xyz if (it->decimal_digits != res->getInt("DECIMAL_DIGITS")) { msg.str(""); msg << "...\t\tWARNING: expecting DECIMAL_DIGITS = (int)'" << it->decimal_digits << "'"; msg << " got (int)'" << res->getString("DECIMAL_DIGITS") << "'"; logMsg(msg.str()); got_warning=true; } ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getInt(9), res->getInt("DECIMAL_DIGITS")); msg.str(""); if (0 == it->decimal_digits) { msg << "0"; } else { msg << it->decimal_digits; } if (msg.str() != res->getString("DECIMAL_DIGITS")) { msg.str(""); msg << "...\t\tWARNING: expecting DECIMAL_DIGITS = '" << it->decimal_digits << "'"; msg << " length() is '" << msg.str().length() << "'"; msg << " got '" << res->getString("DECIMAL_DIGITS") << "'"; msg << " length() is '" << res->getString("DECIMAL_DIGITS").length() << "'"; logMsg(msg.str()); got_warning=true; } else { // If string and int are broken, the rest is broken as well - you can bet! ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getString(9), res->getString("DECIMAL_DIGITS")); ASSERT_EQUALS(it->decimal_digits != 0, res->getBoolean("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getBoolean(9), res->getBoolean("DECIMAL_DIGITS")); ASSERT_EQUALS((int64_t) it->decimal_digits, res->getInt64("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getInt64(9), res->getInt64("DECIMAL_DIGITS")); ASSERT_EQUALS((uint64_t) it->decimal_digits, res->getUInt64("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getUInt64(9), res->getUInt64("DECIMAL_DIGITS")); ASSERT_EQUALS((double) it->decimal_digits, res->getDouble("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getDouble(9), res->getDouble("DECIMAL_DIGITS")); ASSERT_EQUALS((int32_t) it->decimal_digits, res->getInt("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getInt(9), res->getInt("DECIMAL_DIGITS")); ASSERT_EQUALS((uint32_t) it->decimal_digits, res->getUInt("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); ASSERT_EQUALS(res->getUInt(9), res->getUInt("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->isNull(9)); ASSERT_EQUALS(res->isNull(9), res->isNull("DECIMAL_DIGITS")); ASSERT_EQUALS(false, res->wasNull()); } try { res->isNull(0); FAIL("Invalid column index"); } catch (sql::SQLException &) { } try { res->isNull("invalid column index"); FAIL("Invalid column index"); } catch (sql::SQLException &) { } stmt->execute("DROP TABLE IF EXISTS test"); } stmt->execute("DROP TABLE IF EXISTS test"); res.reset(dbmeta->getColumns(con->getCatalog(), con->getSchema(), "test", "id")); ASSERT(!res->next()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { res->isNull(1); FAIL("Not on resultset, should fail"); } catch (sql::SQLException &) { } try { res->isNull("not on resultset and unknown column"); FAIL("Not on resultset, should fail"); } catch (sql::SQLException &) { } if (got_warning) FAIL("See --verbose warnings!"); } /* Simple testcase of getBestRowIdentifier returns columns making UNIQUE not Null filters in case of primary key is not present */ void connectionmetadata::bestIdUniqueNotNull() { createSchemaObject("TABLE", "bestIdUniqueNotNull", "(id int not null, value varchar(25)," "UNIQUE INDEX(id))"); createSchemaObject("TABLE", "bestIdUniqueNull", "(id int, value varchar(25)," "UNIQUE INDEX(id))"); DatabaseMetaData *dbmeta= con->getMetaData(); res.reset(dbmeta->getBestRowIdentifier(con->getCatalog(), con->getSchema(), "bestIdUniqueNotNull", 0, false)); ASSERT(res->next()); ASSERT_EQUALS("id", res->getString(2)); ASSERT(!res->next()); res.reset(dbmeta->getBestRowIdentifier(con->getCatalog(), con->getSchema(), "bestIdUniqueNull", 0, false)); ASSERT(!res->next()); } void connectionmetadata::getSchemaCollation() { logMsg("connectionmetadata::getSchemaCollation - MySQL_ConnectionMetaData::getSchemaCollation()"); try { ResultSetMetaData * resmeta; DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP DATABASE IF EXISTS collationTestDatabase"); stmt->execute("CREATE DATABASE collationTestDatabase CHARACTER SET utf8 COLLATE utf8_bin"); /* SchemaCollation */ res.reset(dbmeta->getSchemaCollation(con->getCatalog(), "collationTestDatabase")); ASSERT(res->next()); resmeta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 3, resmeta->getColumnCount()); ASSERT_EQUALS("SCHEMA_CAT", resmeta->getColumnLabel(1)); ASSERT_EQUALS("SCHEMA_NAME", resmeta->getColumnLabel(2)); ASSERT_EQUALS("SCHEMA_COLLATION", resmeta->getColumnLabel(3)); ASSERT(res->getString("SCHEMA_NAME").caseCompare("collationTestDatabase") == 0); ASSERT_EQUALS("utf8_bin", res->getString("SCHEMA_COLLATION")); stmt->execute("DROP DATABASE IF EXISTS collationTestDatabase"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getSchemaCharset() { logMsg("connectionmetadata::getSchemaCharset - MySQL_ConnectionMetaData::getSchemaCharset()"); try { ResultSetMetaData * resmeta; DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP DATABASE IF EXISTS charsetTestDatabase"); stmt->execute("CREATE DATABASE charsetTestDatabase CHARACTER SET utf8 COLLATE utf8_bin"); /* SchemaCharset */ res.reset(dbmeta->getSchemaCharset(con->getCatalog(), "charsetTestDatabase")); ASSERT(res->next()); resmeta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 3, resmeta->getColumnCount()); ASSERT_EQUALS("SCHEMA_CAT", resmeta->getColumnLabel(1)); ASSERT_EQUALS("SCHEMA_NAME", resmeta->getColumnLabel(2)); ASSERT_EQUALS("SCHEMA_CHARSET", resmeta->getColumnLabel(3)); ASSERT(res->getString("SCHEMA_NAME").caseCompare("charsetTestDatabase") == 0); ASSERT_EQUALS("utf8", res->getString("SCHEMA_CHARSET")); stmt->execute("DROP DATABASE IF EXISTS charsetTestDatabase"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getTableCollation() { logMsg("connectionmetadata::getTableCollation - MySQL_ConnectionMetaData::getTableCollation()"); try { ResultSetMetaData * resmeta; DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP DATABASE IF EXISTS collationTestDatabase"); stmt->execute("CREATE DATABASE collationTestDatabase CHARACTER SET utf8 COLLATE utf8_bin"); stmt->execute("DROP TABLE IF EXISTS collationTestDatabase.collationTestTable"); stmt->execute("CREATE TABLE collationTestDatabase.collationTestTable(id INT) CHARACTER SET latin1 COLLATE latin1_general_ci"); stmt->execute("DROP TABLE IF EXISTS collationTestDatabase.collationTestTableAnother"); stmt->execute("CREATE TABLE collationTestDatabase.collationTestTableAnother(id INT) CHARACTER SET utf8 COLLATE utf8_bin"); /* TableCollation */ res.reset(dbmeta->getTableCollation(con->getCatalog(), "collationTestDatabase", "%collationTestTable%")); ASSERT(res->next()); resmeta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 4, resmeta->getColumnCount()); ASSERT_EQUALS("TABLE_CAT", resmeta->getColumnLabel(1)); ASSERT_EQUALS("TABLE_SCHEMA", resmeta->getColumnLabel(2)); ASSERT_EQUALS("TABLE_NAME", resmeta->getColumnLabel(3)); ASSERT_EQUALS("TABLE_COLLATION", resmeta->getColumnLabel(4)); ASSERT(res->getString("TABLE_SCHEMA").caseCompare("collationTestDatabase") == 0); ASSERT(res->getString("TABLE_NAME").caseCompare("collationTestTable") == 0); ASSERT_EQUALS("latin1_general_ci", res->getString("TABLE_COLLATION")); ASSERT(res->next()); ASSERT(res->getString("TABLE_SCHEMA").caseCompare("collationTestDatabase") == 0); ASSERT(res->getString("TABLE_NAME").caseCompare("collationTestTableAnother") == 0); ASSERT_EQUALS("utf8_bin", res->getString("TABLE_COLLATION")); stmt->execute("DROP DATABASE IF EXISTS collationTestDatabase"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getTableCharset() { logMsg("connectionmetadata::getTableCharset - MySQL_ConnectionMetaData::getTableCharset()"); try { ResultSetMetaData * resmeta; DatabaseMetaData * dbmeta=con->getMetaData(); stmt.reset(con->createStatement()); stmt->execute("DROP DATABASE IF EXISTS charsetTestDatabase"); stmt->execute("CREATE DATABASE charsetTestDatabase CHARACTER SET utf8 COLLATE utf8_bin"); stmt->execute("DROP TABLE IF EXISTS charsetTestDatabase.charsetTestTable"); stmt->execute("CREATE TABLE charsetTestDatabase.charsetTestTable(id INT) CHARACTER SET latin1 COLLATE latin1_general_ci"); stmt->execute("DROP TABLE IF EXISTS charsetTestDatabase.charsetTestTableAnother"); stmt->execute("CREATE TABLE charsetTestDatabase.charsetTestTableAnother(id INT) CHARACTER SET utf8 COLLATE utf8_bin"); /* TableCharset */ res.reset(dbmeta->getTableCharset(con->getCatalog(), "charsetTestDatabase", "%charsetTestTable%")); ASSERT(res->next()); resmeta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 4, resmeta->getColumnCount()); ASSERT_EQUALS("TABLE_CAT", resmeta->getColumnLabel(1)); ASSERT_EQUALS("TABLE_SCHEMA", resmeta->getColumnLabel(2)); ASSERT_EQUALS("TABLE_NAME", resmeta->getColumnLabel(3)); ASSERT_EQUALS("TABLE_CHARSET", resmeta->getColumnLabel(4)); ASSERT(res->getString("TABLE_SCHEMA").caseCompare("charsetTestDatabase") == 0); ASSERT(res->getString("TABLE_NAME").caseCompare("charsetTestTable") == 0); ASSERT_EQUALS("latin1", res->getString("TABLE_CHARSET")); ASSERT(res->next()); ASSERT(res->getString("TABLE_SCHEMA").caseCompare("charsetTestDatabase") == 0); ASSERT(res->getString("TABLE_NAME").caseCompare("charsetTestTableAnother") == 0); ASSERT_EQUALS("utf8", res->getString("TABLE_CHARSET")); stmt->execute("DROP DATABASE IF EXISTS charsetTestDatabase"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void connectionmetadata::getTables() { logMsg("connectionmetadata::getTables - MySQL_ConnectionMetaData::getTables()"); try { ResultSetMetaData * resmeta; DatabaseMetaData * dbmeta=con->getMetaData(); std::list< sql::SQLString > tableTypes; stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS testTable1"); stmt->execute("CREATE TABLE testTable1(id INT)"); stmt->execute("DROP VIEW IF EXISTS testView1"); stmt->execute("CREATE VIEW testView1 AS SELECT * FROM testTable1"); /* for tableType = TABLE */ tableTypes.clear(); tableTypes.push_back(sql::SQLString("TABLE")); res.reset(dbmeta->getTables("", "%", "testTable%", tableTypes)); ASSERT(res->next()); ASSERT_EQUALS(res->getString(3), "testTable1"); ASSERT_EQUALS(res->getString(4), "TABLE"); /* for tableType = VIEW */ tableTypes.clear(); tableTypes.push_back(sql::SQLString("VIEW")); res.reset(dbmeta->getTables("", "%", "testView%", tableTypes)); ASSERT(res->next()); ASSERT_EQUALS(res->getString(3), "testView1"); ASSERT_EQUALS(res->getString(4), "VIEW"); stmt->execute("DROP TABLE IF EXISTS testTable1"); stmt->execute("DROP VIEW IF EXISTS testView1"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } } /* namespace connectionmetadata */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/connectionmetadata.h000644 015771 000012 00000025616 12645244437 025402 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" #include /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class connectionmetadata : public unit_fixture { private: typedef unit_fixture super; /** Helper function to check a FK definition * */ void checkForeignKey(Connection &con, ResultSet &res); protected: public: EXAMPLE_TEST_FIXTURE(connectionmetadata) { TEST_CASE(getSchemata); TEST_CASE(getSchemaObjects); TEST_CASE(getAttributes); TEST_CASE(getBestRowIdentifier); TEST_CASE(getCatalogs); TEST_CASE(getCatalogSeparator); TEST_CASE(getCatalogTerm); TEST_CASE(getCrossReference); TEST_CASE(getColumnPrivileges); TEST_CASE(getColumns); TEST_CASE(getConnection); TEST_CASE(getDatabaseVersions); TEST_CASE(getDriverVersions); TEST_CASE(getDefaultTransactionIsolation); TEST_CASE(getExtraNameCharacters); TEST_CASE(getExportedKeys); TEST_CASE(getIdentifierQuoteString); TEST_CASE(getImportedKeys); TEST_CASE(getIndexInfo); TEST_CASE(getLimitsAndStuff); TEST_CASE(getPrimaryKeys); TEST_CASE(getProcedures); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS TEST_CASE(getProcedureColumns); #endif TEST_CASE(getProcedureTerm); TEST_CASE(getResultSetHoldability); TEST_CASE(getSchemaTerm); TEST_CASE(getSearchStringEscape); TEST_CASE(getSQLKeywords); TEST_CASE(getSuperTables); TEST_CASE(getSuperTypes); /* TODO - we might in the future follow the JDBC standard word by word. However, at the moment we do not promise that our class attributes have certain values. Users shall not rely on certain values, for example those listed in the JDBC standard! TEST_CASE(classAttributes); */ TEST_CASE(getColumnsTypeConversions); TEST_CASE(bestIdUniqueNotNull); TEST_CASE(getSchemaCollation); TEST_CASE(getSchemaCharset); TEST_CASE(getTableCollation); TEST_CASE(getTableCharset); TEST_CASE(getTables); } /** * Test for DatabaseMetaData:getSchemata() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSchemata(); /** * Test for DatabaseMetaData:getSchemaObjects*() * * TODO - HACK _ FIXME - Focus on code coverage only! */ void getSchemaObjects(); /** * Test for DatabaseMetaData:getAttributes() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getAttributes(); /** * Test for DatabaseMetaData:getBestRowIdentifier() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getBestRowIdentifier(); /** * Test for DatabaseMetaData:getCatalogs() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getCatalogs(); /** * Test for DatabaseMetaData:getCatalogSeparator() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getCatalogSeparator(); /** * Test for DatabaseMetaData:getCatalogTerm() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getCatalogTerm(); /** * Test for DatabaseMetaData:getCrossReference() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getCrossReference(); /** * Test for DatabaseMetaData:getColumns() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumns(); /** * Test for DatabaseMetaData:getColumnPrivileges() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnPrivileges(); /** * Test for DatabaseMetaData:getConnection * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getConnection(); /** * Test for DatabaseMetaData:getDatabaseMajorVersion, *MinorVersion, *PatchVersion() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getDatabaseVersions(); /** * Test for DatabaseMetaData:getDriverMajorVersion, *MinorVersion, *PatchVersion() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getDriverVersions(); /** * Test for DatabaseMetaData:getDefaultTransactionIsolation() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getDefaultTransactionIsolation(); /** * Test for DatabaseMetaData:getExtraNameCharacters() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getExtraNameCharacters(); /** * Test for DatabaseMetaData:getExportedKeys() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getExportedKeys(); /** * Test for DatabaseMetaData:getIdentifierQuoteString() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getIdentifierQuoteString(); /** * Test for DatabaseMetaData:getImportedKeys() * * Create two tables parent and child and check if the method detects the FK properly. */ void getImportedKeys(); /** * Test for DatabaseMetaData:getIndexInfo() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getIndexInfo(); /** * Test for DatabaseMetaData:getLimitsAndStuff() * * Test for assorted get*Something() methods */ void getLimitsAndStuff(); /** * Test for DatabaseMetaData:getPrimaryKeys() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getPrimaryKeys(); /** * Test for DatabaseMetaData:getProcedures() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getProcedures(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /** * Test for DatabaseMetaData:getProcedureColumns() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getProcedureColumns(); #endif /** * Test for DatabaseMetaData:getProcedureTerm() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getProcedureTerm(); /** * Test for DatabaseMetaData:getResultSetHoldability() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getResultSetHoldability(); /** * Test for DatabaseMetaData::getSchemaTerm() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSchemaTerm(); /** * Test for DatabaseMetaData::getSearchStringEscape() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSearchStringEscape(); /** * Test for DatabaseMetaData::getSQLKeywords() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSQLKeywords(); /** * Test for DatabaseMetaData::getSuperTables() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSuperTables(); /** * Test for DatabaseMetaData::getSuperTypes() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSuperTypes(); /** * Test of DatabaseMetaData class attributes * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void classAttributes(); /** * Test of type conversions in MySQL_ArtResultSet * */ void getColumnsTypeConversions(); void bestIdUniqueNotNull(); /** * Test for DatabaseMetaData::getSchemaCollation() */ void getSchemaCollation(); /** * Test for DatabaseMetaData::getSchemaCharset() */ void getSchemaCharset(); /** * Test for DatabaseMetaData::getTableCollation() */ void getTableCollation(); /** * Test for DatabaseMetaData::getTableCharset() */ void getTableCharset(); /** * Test for DatabaseMetaData::getTables() */ void getTables(); }; REGISTER_FIXTURE(connectionmetadata); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/parametermetadata.cpp000644 015771 000012 00000007773 12645244437 025562 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "parametermetadata.h" #include namespace testsuite { namespace classes { void parametermetadata::getMeta() { logMsg("parametermetadata::InsertSelectAllTypes() - MySQL_ParameterMetaData::*"); ParameterMetaData * parameta; try { pstmt.reset(con->prepareStatement("SELECT 1")); parameta = pstmt->getParameterMetaData(); pstmt->close(); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { pstmt->getParameterMetaData(); FAIL("Closed connection not detected"); } catch (sql::InvalidInstanceException) { } } void parametermetadata::getParameterCount() { logMsg("parametermetadata::getParameterCount() - MySQL_ParameterMetaData::getParameterCount"); ParameterMetaData * parameta; try { pstmt.reset(con->prepareStatement("SELECT 1")); parameta = (pstmt->getParameterMetaData()); parameta->getParameterCount(); pstmt->close(); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { pstmt->getParameterMetaData(); FAIL("Closed connection not detected"); } catch (sql::InvalidInstanceException) { } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS void parametermetadata::notImplemented() { logMsg("parametermetadata::notImplemented() - MySQL_ParameterMetaData::*"); ParameterMetaData * parameta; try { pstmt.reset(con->prepareStatement("SELECT 1")); parameta = (pstmt->getParameterMetaData()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { parameta->getParameterClassName(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->getParameterMode(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->getParameterType(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->getParameterTypeName(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->getPrecision(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->getScale(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->isNullable(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } try { parameta->isSigned(1); FAIL("API change"); } catch (sql::MethodNotImplementedException) { } } #endif } /* namespace parametermetadata */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/parametermetadata.h000644 015771 000012 00000003616 12645244437 025217 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" #include /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class parametermetadata : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(parametermetadata) { TEST_CASE(getMeta); TEST_CASE(getParameterCount); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS TEST_CASE(notImplemented); #endif } /** * Fetch meta data from open/closed PS */ void getMeta(); /** * Test of ParameterMetaData::getParameterCount() */ void getParameterCount(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /** * Tests of all "not implemented" methods to track API changes */ void notImplemented(); #endif }; REGISTER_FIXTURE(parametermetadata); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/preparedstatement.cpp000644 015771 000012 00000116523 12645244437 025622 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "preparedstatement.h" #include #include #include namespace testsuite { namespace classes { void preparedstatement::InsertSelectAllTypes() { logMsg("preparedstatement::InsertSelectAllTypes() - MySQL_PreparedStatement::*"); std::stringstream sql; std::vector::iterator it; stmt.reset(con->createStatement()); bool got_warning=false; size_t len; try { for (it=columns.end(), it--; it != columns.begin(); it--) { stmt->execute("DROP TABLE IF EXISTS test"); sql.str(""); sql << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(sql.str()); sql.str(""); sql << "... testing '" << it->sqldef << "'"; logMsg(sql.str()); } catch (sql::SQLException &) { sql.str(""); sql << "... skipping '" << it->sqldef << "'"; logMsg(sql.str()); continue; } pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->setString(1, it->value); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt.reset(con->prepareStatement("SELECT id, NULL FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); ASSERT(res->next()); res.reset(); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); ASSERT(res->next()); if (it->check_as_string && (res->getString(1) != it->as_string)) { sql.str(""); sql << "... \t\tWARNING - SQL: '" << it->sqldef << "' - expecting '" << it->as_string << "'"; sql << " got '" << res->getString(1) << "'"; logMsg(sql.str()); got_warning=true; } ASSERT_EQUALS(res->getString("id"), res->getString(1)); try { res->getString(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getString(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getString(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getString(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getDouble("id"), res->getDouble(1)); try { res->getDouble(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getDouble(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getDouble(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getDouble(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getInt(1), res->getInt("id")); try { res->getInt(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getInt(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getUInt(1), res->getUInt("id")); try { res->getUInt(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getUInt(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getUInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getUInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getInt64("id"), res->getInt64(1)); try { res->getInt64(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getInt64(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getUInt64("id"), res->getUInt64(1)); try { res->getUInt64(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getUInt64(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getUInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getUInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getBoolean("id"), res->getBoolean(1)); try { res->getBoolean(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getBoolean(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getBoolean(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getBoolean(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); // TODO - make BLOB if (it->check_as_string) { { boost::scoped_ptr blob_output_stream(res->getBlob(1)); len=it->as_string.length(); boost::scoped_array blob_out(new char[len]); blob_output_stream->read(blob_out.get(), len); if (it->as_string.compare(0, blob_output_stream->gcount() , blob_out.get(), blob_output_stream->gcount())) { sql.str(""); sql << "... \t\tWARNING - SQL: '" << it->sqldef << "' - expecting '" << it->as_string << "'"; sql << " got '" << res->getString(1) << "'"; logMsg(sql.str()); got_warning=true; } } { boost::scoped_ptr blob_output_stream(res->getBlob("id")); len=it->as_string.length(); boost::scoped_array blob_out(new char[len]); blob_output_stream->read(blob_out.get(), len); if (it->as_string.compare(0, blob_output_stream->gcount() , blob_out.get(), blob_output_stream->gcount())) { sql.str(""); sql << "... \t\tWARNING - SQL: '" << it->sqldef << "' - expecting '" << it->as_string << "'"; sql << " got '" << res->getString(1) << "'"; logMsg(sql.str()); got_warning=true; } } } try { res->getBlob(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getBlob(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getBlob(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getBlob(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); } stmt->execute("DROP TABLE IF EXISTS test"); if (got_warning) FAIL("See warnings"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::assortedSetType() { logMsg("preparedstatement::assortedSetType() - MySQL_PreparedStatement::set*"); std::stringstream sql; std::vector::iterator it; stmt.reset(con->createStatement()); bool got_warning=false; try { for (it=columns.end(), it--; it != columns.begin(); it--) { stmt->execute("DROP TABLE IF EXISTS test"); sql.str(""); sql << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(sql.str()); sql.str(""); sql << "... testing '" << it->sqldef << "'"; logMsg(sql.str()); } catch (sql::SQLException &) { sql.str(""); sql << "... skipping '" << it->sqldef << "'"; logMsg(sql.str()); continue; } pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->setString(1, it->value); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setString(0, "overflow"); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setString(2, "invalid"); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setBigInt(1, it->value); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setBigInt(0, it->value); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setBigInt(2, it->value); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setBoolean(1, false); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setBoolean(0, false); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setBoolean(2, false); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setDateTime(1, it->value); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setDateTime(0, it->value); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setDateTime(2, it->value); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setDouble(1, (double) 1.23); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setDouble(0, (double) 1.23); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setDouble(2, (double) 1.23); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setInt(1, (int32_t) - 1); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setInt(0, (int32_t) - 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setInt(2, (int32_t) - 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setUInt(1, (uint32_t) 1); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setUInt(0, (uint32_t) 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setUInt(2, (uint32_t) 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setInt64(1, (int64_t) - 123); ASSERT_EQUALS(1, pstmt->executeUpdate()); if (it->is_nullable) { pstmt->clearParameters(); pstmt->setNull(1, it->ctype); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setNull(0, it->ctype); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setNull(2, it->ctype); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } } pstmt->clearParameters(); pstmt->setUInt(1, (uint32_t) 1); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setUInt(0, (uint32_t) - 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setUInt(2, (uint32_t) - 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); pstmt->setUInt64(1, (uint64_t) 123); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setUInt64(0, (uint64_t) - 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setUInt64(2, (uint64_t) - 1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); std::stringstream blob_input_stream; blob_input_stream.str(it->value); pstmt->setBlob(1, &blob_input_stream); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt->clearParameters(); try { pstmt->setBlob(0, &blob_input_stream); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt->clearParameters(); try { pstmt->setBlob(2, &blob_input_stream); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } pstmt.reset(con->prepareStatement("SELECT COUNT(IFNULL(id, 1)) AS _num FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); ASSERT(res->next()); if (res->getInt("_num") != (11 + (int) it->is_nullable)) { sql.str(""); sql << "....\t\tWARNING, SQL: " << it->sqldef << ", nullable " << std::boolalpha; sql << it->is_nullable << ", found " << res->getInt(1) << "columns but"; sql << " expecting " << (11 + (int) it->is_nullable); logMsg(sql.str()); got_warning=true; } } stmt->execute("DROP TABLE IF EXISTS test"); if (got_warning) FAIL("See warnings"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::setNull() { logMsg("preparedstatement::setNull() - MySQL_PreparedStatement::*"); std::stringstream sql; stmt.reset(con->createStatement()); try { stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->setNull(1, sql::DataType::INTEGER); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt.reset(con->prepareStatement("SELECT id FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); ASSERT(res->next()); ASSERT(res->isNull(1)); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL)"); pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->setNull(1, sql::DataType::INTEGER); pstmt->executeUpdate(); FAIL("Should fail"); } catch (sql::SQLException &) { } } void preparedstatement::checkClosed() { logMsg("preparedstatement::checkClosed() - MySQL_PreparedStatement::close()"); try { pstmt.reset(con->prepareStatement("SELECT 1")); pstmt->close(); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::getMetaData() { logMsg("preparedstatement::getMetaData() - MySQL_PreparedStatement::getMetaData()"); std::stringstream sql; std::vector::iterator it; stmt.reset(con->createStatement()); ResultSetMetaData * meta_ps; ResultSetMetaData * meta_st; ResultSet res_st; bool got_warning=false; unsigned int i; try { for (it=columns.end(), it--; it != columns.begin(); it--) { stmt->execute("DROP TABLE IF EXISTS test"); sql.str(""); sql << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(sql.str()); sql.str(""); sql << "... testing '" << it->sqldef << "'"; logMsg(sql.str()); } catch (sql::SQLException &) { sql.str(""); sql << "... skipping '" << it->sqldef << "'"; logMsg(sql.str()); continue; } pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->setString(1, it->value); ASSERT_EQUALS(1, pstmt->executeUpdate()); pstmt.reset(con->prepareStatement("SELECT id, dummy, NULL, -1.1234, 'Warum nicht...' FROM test")); res.reset(pstmt->executeQuery()); meta_ps=res->getMetaData(); res_st.reset(stmt->executeQuery("SELECT id, dummy, NULL, -1.1234, 'Warum nicht...' FROM test")); meta_st=res->getMetaData(); ASSERT_EQUALS(meta_ps->getColumnCount(), meta_st->getColumnCount()); for (i=1; i <= meta_ps->getColumnCount(); i++) { ASSERT_EQUALS(meta_ps->getCatalogName(i), meta_st->getCatalogName(i)); ASSERT_EQUALS(meta_ps->getColumnDisplaySize(i), meta_st->getColumnDisplaySize(i)); ASSERT_EQUALS(meta_ps->getColumnLabel(i), meta_st->getColumnLabel(i)); ASSERT_EQUALS(meta_ps->getColumnName(i), meta_st->getColumnName(i)); ASSERT_EQUALS(meta_ps->getColumnType(i), meta_st->getColumnType(i)); ASSERT_EQUALS(meta_ps->getColumnTypeName(i), meta_st->getColumnTypeName(i)); ASSERT_EQUALS(meta_ps->getPrecision(i), meta_st->getPrecision(i)); ASSERT_EQUALS(meta_ps->getScale(i), meta_st->getScale(i)); ASSERT_EQUALS(meta_ps->getSchemaName(i), meta_st->getSchemaName(i)); ASSERT_EQUALS(meta_ps->getTableName(i), meta_st->getTableName(i)); ASSERT_EQUALS(meta_ps->isAutoIncrement(i), meta_st->isAutoIncrement(i)); ASSERT_EQUALS(meta_ps->isCaseSensitive(i), meta_st->isCaseSensitive(i)); ASSERT_EQUALS(meta_ps->isCurrency(i), meta_st->isCurrency(i)); ASSERT_EQUALS(meta_ps->isDefinitelyWritable(i), meta_st->isDefinitelyWritable(i)); ASSERT_EQUALS(meta_ps->isNullable(i), meta_st->isNullable(i)); ASSERT_EQUALS(meta_ps->isReadOnly(i), meta_st->isReadOnly(i)); ASSERT_EQUALS(meta_ps->isSearchable(i), meta_st->isSearchable(i)); ASSERT_EQUALS(meta_ps->isSigned(i), meta_st->isSigned(i)); ASSERT_EQUALS(meta_ps->isWritable(i), meta_st->isWritable(i)); } try { meta_ps->getCatalogName(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException) { } } stmt->execute("DROP TABLE IF EXISTS test"); if (got_warning) FAIL("See warnings"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } bool preparedstatement::createSP(std::string sp_code) { try { stmt.reset(con->createStatement()); stmt->execute("DROP PROCEDURE IF EXISTS p"); } catch (sql::SQLException &e) { logMsg(e.what()); return false; } try { pstmt.reset(con->prepareStatement(sp_code)); ASSERT(!pstmt->execute()); logMsg("... using PS for everything"); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg; msg.str(""); msg << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg.str()); fail(e.what(), __FILE__, __LINE__); } stmt->execute(sp_code); } return true; } void preparedstatement::callSP() { logMsg("preparedstatement::callSP() - MySQL_PreparedStatement::*()"); std::string sp_code("CREATE PROCEDURE p(OUT ver_param VARCHAR(250)) BEGIN SELECT VERSION() INTO ver_param; END;"); try { if (!createSP(sp_code)) { logMsg("... skipping:"); return; } DatabaseMetaData * dbmeta=con->getMetaData(); try { pstmt.reset(con->prepareStatement("CALL p(@version)")); ASSERT(!pstmt->execute()); ASSERT(!pstmt->execute()); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg; msg.str(""); msg << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg.str()); fail(e.what(), __FILE__, __LINE__); } // PS protocol does not support CALL return; } pstmt.reset(con->prepareStatement("SELECT @version AS _version")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(dbmeta->getDatabaseProductVersion(), res->getString("_version")); pstmt.reset(con->prepareStatement("SET @version='no_version'")); ASSERT(!pstmt->execute()); pstmt.reset(con->prepareStatement("CALL p(@version)")); ASSERT(!pstmt->execute()); pstmt.reset(con->prepareStatement("SELECT @version AS _version")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(dbmeta->getDatabaseProductVersion(), res->getString("_version")); } catch (sql::SQLException &e) { logErr(e.what()); std::stringstream msg; msg.str(""); msg << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg.str()); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::callSPInOut() { logMsg("preparedstatement::callSPInOut() - MySQL_PreparedStatement::*()"); std::string sp_code("CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;"); try { if (!createSP(sp_code)) { logMsg("... skipping: cannot create SP"); return; } try { pstmt.reset(con->prepareStatement("CALL p('myver', @version)")); ASSERT(!pstmt->execute()); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg1; msg1.str(""); msg1 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg1.str()); fail(e.what(), __FILE__, __LINE__); } // PS protocol does not support CALL logMsg("... skipping: PS protocol does not support CALL"); return; } pstmt.reset(con->prepareStatement("SELECT @version AS _version")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS("myver", res->getString("_version")); } catch (sql::SQLException &e) { logErr(e.what()); std::stringstream msg2; msg2.str(""); msg2 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg2.str()); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::callSPWithPS() { logMsg("preparedstatement::callSPWithPS() - MySQL_PreparedStatement::*()"); try { int mysql_version=getMySQLVersion(con); if (mysql_version < 60000) SKIP("http://bugs.mysql.com/bug.php?id=44495 - Server crash"); std::string sp_code("CREATE PROCEDURE p(IN val VARCHAR(25)) BEGIN SET @sql = CONCAT('SELECT \"', val, '\"'); PREPARE stmt FROM @sql; EXECUTE stmt; DROP PREPARE stmt; END;"); if (!createSP(sp_code)) { logMsg("... skipping:"); return; } try { pstmt.reset(con->prepareStatement("CALL p('abc')")); res.reset(pstmt->executeQuery()); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg1; msg1.str(""); msg1 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg1.str()); fail(e.what(), __FILE__, __LINE__); } // PS interface cannot call this kind of statement return; } ASSERT(res->next()); ASSERT_EQUALS("abc", res->getString(1)); std::stringstream msg2; msg2.str(""); msg2 << "... val = '" << res->getString(1) << "'"; logMsg(msg2.str()); try { pstmt.reset(con->prepareStatement("CALL p(?)")); pstmt->setString(1, "123"); res.reset(pstmt->executeQuery()); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg3; msg3.str(""); msg3 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg3.str()); fail(e.what(), __FILE__, __LINE__); } // PS interface cannot call this kind of statement return; } res->close(); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg4; msg4.str(""); msg4 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg4.str()); fail(e.what(), __FILE__, __LINE__); } } } void preparedstatement::callSPMultiRes() { logMsg("preparedstatement::callSPMultiRes() - MySQL_PreparedStatement::*()"); try { std::string sp_code("CREATE PROCEDURE p() BEGIN SELECT 1; SELECT 2; SELECT 3; END;"); if (!createSP(sp_code)) { logMsg("... skipping:"); return; } try { pstmt.reset(con->prepareStatement("CALL p()")); ASSERT(pstmt->execute()); } catch (sql::SQLException &e) { if (e.getErrorCode() != 1295) { logErr(e.what()); std::stringstream msg1; msg1.str(""); msg1 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg1.str()); fail(e.what(), __FILE__, __LINE__); } // PS interface cannot call this kind of statement return; } // Should not work prior to MySQL 6.0 std::stringstream msg2; msg2.str(""); do { res.reset(pstmt->getResultSet()); while (res->next()) { msg2 << res->getString(1); } } while (pstmt->getMoreResults()); ASSERT_EQUALS("123", msg2.str()); } catch (sql::SQLException &e) { logErr(e.what()); std::stringstream msg3; msg3.str(""); msg3 << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg3.str()); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::anonymousSelect() { logMsg("preparedstatement::anonymousSelect() - MySQL_PreparedStatement::*, MYSQL_PS_Resultset::*"); try { pstmt.reset(con->prepareStatement("SELECT ' ', NULL")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(" ", res->getString(1)); std::string mynull(res->getString(2)); ASSERT(res->isNull(2)); ASSERT(res->wasNull()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::crash() { logMsg("preparedstatement::crash() - MySQL_PreparedStatement::*"); try { int mysql_version=getMySQLVersion(con); if ((mysql_version > 50000 && mysql_version < 50082) || (mysql_version > 51000 && mysql_version < 51035) || (mysql_version > 60000 && mysql_version < 60012)) SKIP("http://bugs.mysql.com/bug.php?id=43833 - Server crash"); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(dummy TIMESTAMP, id VARCHAR(1))"); pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->clearParameters(); pstmt->setDouble(1, (double) 1.23); ASSERT_EQUALS(1, pstmt->executeUpdate()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::getWarnings() { logMsg("preparedstatement::getWarnings() - MySQL_PreparedStatement::get|clearWarnings()"); std::stringstream msg; stmt.reset(con->createStatement()); try { stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT UNSIGNED)"); // Generating 2 warnings to make sure we get only the last 1 - won't hurt // Lets hope that this will always cause a 1264 or similar warning pstmt.reset(con->prepareStatement("INSERT INTO test(id) VALUES (?)")); pstmt->setInt(1, -2); pstmt->executeUpdate(); pstmt->setInt(1, -1); pstmt->executeUpdate(); int count= 0; for (const sql::SQLWarning* warn=pstmt->getWarnings(); warn; warn=warn->getNextWarning()) { msg.str(""); msg << "... ErrorCode = '" << warn->getErrorCode() << "', "; msg << "SQLState = '" << warn->getSQLState() << "', "; msg << "ErrorMessage = '" << warn->getMessage() << "'"; logMsg(msg.str()); ASSERT((0 != warn->getErrorCode())); if (1264 == warn->getErrorCode()) { ASSERT_EQUALS("22003", warn->getSQLState()); } else { ASSERT(("" != warn->getSQLState())); } ASSERT(("" != warn->getMessage())); ++count; } ASSERT_EQUALS(1, count); for (const sql::SQLWarning* warn=pstmt->getWarnings(); warn; warn=warn->getNextWarning()) { msg.str(""); msg << "... ErrorCode = '" << warn->getErrorCode() << "', "; msg << "SQLState = '" << warn->getSQLState() << "', "; msg << "ErrorMessage = '" << warn->getMessage() << "'"; logMsg(msg.str()); ASSERT((0 != warn->getErrorCode())); if (1264 == warn->getErrorCode()) { ASSERT_EQUALS("22003", warn->getSQLState()); } else { ASSERT(("" != warn->getSQLState())); } ASSERT(("" != warn->getMessage())); } pstmt->clearWarnings(); for (const sql::SQLWarning* warn=pstmt->getWarnings(); warn; warn=warn->getNextWarning()) { FAIL("There should be no more warnings!"); } pstmt->setInt(1, -3); pstmt->executeUpdate(); ASSERT(pstmt->getWarnings() != NULL); // Statement without tables access does not reset warnings. pstmt.reset(con->prepareStatement("SELECT 1")); res.reset(pstmt->executeQuery()); ASSERT(pstmt->getWarnings() == NULL); ASSERT(res->next()); // TODO - how to use getNextWarning() ? stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::blob() { logMsg("preparedstatement::blob() - MySQL_PreparedStatement::*"); char blob_input[512]; std::stringstream blob_input_stream; std::stringstream msg; char blob_output[512]; int id; int offset=0; try { pstmt.reset(con->prepareStatement("DROP TABLE IF EXISTS test")); pstmt->execute(); pstmt.reset(con->prepareStatement("CREATE TABLE test(id INT, col1 TINYBLOB, col2 TINYBLOB)")); pstmt->execute(); // Most basic INSERT/SELECT... pstmt.reset(con->prepareStatement("INSERT INTO test(id, col1) VALUES (?, ?)")); for (char ascii_code=CHAR_MIN; ascii_code < CHAR_MAX; ascii_code++) { blob_output[offset]='\0'; blob_input[offset++]=ascii_code; } blob_input[offset]='\0'; blob_output[offset]='\0'; for (char ascii_code=CHAR_MAX; ascii_code > CHAR_MIN; ascii_code--) { blob_output[offset]='\0'; blob_input[offset++]=ascii_code; } blob_input[offset]='\0'; blob_output[offset]='\0'; id=1; blob_input_stream << blob_input; pstmt->setInt(1, id); pstmt->setBlob(2, &blob_input_stream); try { pstmt->setBlob(3, &blob_input_stream); FAIL("Invalid index not detected"); } catch (sql::SQLException) { } pstmt->execute(); pstmt.reset(con->prepareStatement("SELECT id, col1 FROM test WHERE id = 1")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); msg.str(""); msg << "... simple INSERT/SELECT, '" << blob_input << "' =? '" << res->getString(2) << "'"; logMsg(msg.str()); ASSERT_EQUALS(res->getInt(1), id); ASSERT_EQUALS(res->getString(2), blob_input_stream.str()); ASSERT_EQUALS(res->getString(2), blob_input); ASSERT_EQUALS(res->getString("col1"), blob_input_stream.str()); ASSERT_EQUALS(res->getString("col1"), blob_input); boost::scoped_ptr< std::istream > blob_output_stream(res->getBlob(2)); blob_output_stream->seekg(std::ios::beg); blob_output_stream->get(blob_output, offset + 1); ASSERT_EQUALS(blob_input_stream.str(), blob_output); blob_output_stream.reset(res->getBlob("col1")); blob_output_stream->seekg(std::ios::beg); blob_output_stream->get(blob_output, offset + 1); ASSERT_EQUALS(blob_input, blob_output); msg.str(""); msg << "... second check, '" << blob_input << "' =? '" << blob_output << "'"; logMsg(msg.str()); ASSERT(!res->next()); res->close(); msg.str(""); // Data is too long to be stored in a TINYBLOB column msg << "... this is more than TINYBLOB can hold: "; msg << "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; pstmt.reset(con->prepareStatement("INSERT INTO test(id, col1) VALUES (?, ?)")); id=2; pstmt->setInt(1, id); pstmt->setBlob(2, &msg); pstmt->execute(); pstmt.reset(con->prepareStatement("SELECT id, col1 FROM test WHERE id = 2")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(res->getInt(1), id); ASSERT_GT((int) (res->getString(2).length()), (int) (msg.str().length())); ASSERT(!res->next()); res->close(); msg << "- what has happened to the stream?"; logMsg(msg.str()); pstmt.reset(con->prepareStatement("DROP TABLE IF EXISTS test")); pstmt->execute(); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void preparedstatement::executeQuery() { logMsg("preparedstatement::executeQuery() - MySQL_PreparedStatement::executeQuery"); try { const sql::SQLString option("defaultPreparedStatementResultType"); int value=sql::ResultSet::TYPE_FORWARD_ONLY; con->setClientOption(option, static_cast (&value)); } catch (sql::MethodNotImplementedException &/*e*/) { /* not available */ return; } try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT UNSIGNED)"); stmt->execute("INSERT INTO test(id) VALUES (1), (2), (3)"); pstmt.reset(con->prepareStatement("SELECT id FROM test ORDER BY id ASC")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(res->getInt("id"), 1); pstmt.reset(con->prepareStatement("DROP TABLE IF EXISTS test")); pstmt->execute(); } catch (sql::SQLException &e) { logErr(e.what()); std::stringstream msg; msg.str(""); msg << "SQLState: " << e.getSQLState() << ", MySQL error code: " << e.getErrorCode(); logErr(msg.str()); fail(e.what(), __FILE__, __LINE__); } } } /* namespace preparedstatement */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/preparedstatement.h000644 015771 000012 00000006125 12645244437 025263 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" #include #include /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class preparedstatement : public unit_fixture { private: typedef unit_fixture super; bool createSP(std::string sp_code); public: EXAMPLE_TEST_FIXTURE(preparedstatement) { TEST_CASE(crash); TEST_CASE(anonymousSelect); TEST_CASE(InsertSelectAllTypes); TEST_CASE(assortedSetType); TEST_CASE(setNull); TEST_CASE(checkClosed); TEST_CASE(getMetaData); TEST_CASE(callSP); TEST_CASE(callSPInOut); TEST_CASE(callSPWithPS); TEST_CASE(callSPMultiRes); TEST_CASE(getWarnings); TEST_CASE(blob); TEST_CASE(executeQuery); } /** * SELECT ' ', NULL as string */ void anonymousSelect(); /** * Loops over all kinds of column types and inserts/fetches a value */ void InsertSelectAllTypes(); /** * Loops over assorted column types and uses setXYZ to insert a value */ void assortedSetType(); /** * Loops over assorted column types and uses setXYZ to insert a value */ void setNull(); /** * Calling close() */ void checkClosed(); /** * Compare PS and Non-PS Metadata. */ void getMetaData(); /** * Calls a stored procedure */ void callSP(); /** * Calls a stored procedure with IN and OUT parameters */ void callSPInOut(); /** * Calls a stored procedure which contains a prepared statement */ void callSPWithPS(); /** * Calls a stored procedure which returns multiple result sets */ void callSPMultiRes(); /** * TODO - temporary to isolate a crash, remove after fix! */ void crash(); /** * Check get|clearWarnings() */ void getWarnings(); /** * Check BLOB/LOB handling */ void blob(); /** * Check executeQuery() and invalid fetch mode * * TODO - the test does focus on code coverage not functionality */ void executeQuery(); }; REGISTER_FIXTURE(preparedstatement); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/resultset.cpp000644 015771 000012 00000073275 12645244437 024133 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "resultset.h" #include #include #include #include #include namespace testsuite { namespace classes { void resultset::getInt() { bool on_off=true; con->setClientOption("clientTrace", &on_off); // Message for --verbose output logMsg("resultset::getInt - MySQL_ResultSet::getInt*"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(i integer, i_uns integer unsigned, b bigint, b_uns bigint unsigned)"); int64_t r1_c1=L64(2147483646), r1_c2=L64(2147483650), r1_c3=L64(9223372036854775806), r2_c1=L64(2147483647), r2_c2=L64(2147483649), r2_c3=L64(9223372036854775807); uint64_t r1_c4=UL64(9223372036854775810), r2_c4=UL64(18446744073709551615); pstmt.reset(con->prepareStatement("INSERT INTO test(i, i_uns, b, b_uns) VALUES(?,?,?,?)")); ASSERT(pstmt.get() != NULL); pstmt->clearParameters(); pstmt->setInt(1, static_cast (r1_c1)); pstmt->setInt64(2, r1_c2); pstmt->setInt64(3, r1_c3); pstmt->setUInt64(4, r1_c4); ASSERT_EQUALS(false, pstmt->execute()); pstmt->clearParameters(); pstmt->setInt(1, static_cast (r2_c1)); pstmt->setInt64(2, r2_c2); pstmt->setInt64(3, r2_c3); pstmt->setUInt64(4, r2_c4); ASSERT_EQUALS(false, pstmt->execute()); pstmt.reset(con->prepareStatement("SELECT i, i_uns, b, b_uns FROM test")); ASSERT(pstmt.get() != NULL); ASSERT(pstmt->execute()); res.reset(pstmt->getResultSet()); checkResultSetScrolling(res); ASSERT(res->next()); ASSERT_EQUALS(r1_c1, (int64_t) res->getInt("i")); ASSERT_EQUALS(r1_c1, (int64_t) res->getInt(1)); ASSERT_EQUALS(r1_c2, res->getInt64("i_uns")); ASSERT_EQUALS(r1_c2, res->getInt64(2)); ASSERT_EQUALS(r1_c3, res->getInt64("b")); ASSERT_EQUALS(r1_c3, res->getInt64(3)); ASSERT_EQUALS(r1_c4, res->getUInt64("b_uns")); ASSERT_EQUALS(r1_c4, res->getUInt64(4)); ASSERT(res->next()); ASSERT_EQUALS(r2_c1, (int64_t) res->getInt("i")); ASSERT_EQUALS(r2_c1, (int64_t) res->getInt(1)); ASSERT_EQUALS(r2_c2, res->getInt64("i_uns")); ASSERT_EQUALS(r2_c2, res->getInt64(2)); ASSERT_EQUALS(r2_c3, res->getInt64("b")); ASSERT_EQUALS(r2_c3, res->getInt64(3)); ASSERT_EQUALS(r2_c4, res->getUInt64("b_uns")); ASSERT_EQUALS(r2_c4, res->getUInt64(4)); ASSERT_EQUALS(res->next(), false); res.reset(stmt->executeQuery("SELECT i, i_uns, b, b_uns FROM test")); checkResultSetScrolling(res); ASSERT(res->next()); ASSERT_EQUALS(r1_c1, (int64_t) res->getInt("i")); ASSERT_EQUALS(r1_c1, (int64_t) res->getInt(1)); ASSERT_EQUALS(r1_c2, res->getInt64("i_uns")); ASSERT_EQUALS(r1_c2, res->getInt64(2)); ASSERT_EQUALS(r1_c3, res->getInt64("b")); ASSERT_EQUALS(r1_c3, res->getInt64(3)); ASSERT_EQUALS(r1_c4, res->getUInt64("b_uns")); ASSERT_EQUALS(r1_c4, res->getUInt64(4)); ASSERT(res->next()); ASSERT_EQUALS(r2_c1, (int64_t) res->getInt("i")); ASSERT_EQUALS(r2_c1, (int64_t) res->getInt(1)); ASSERT_EQUALS(r2_c2, res->getInt64("i_uns")); ASSERT_EQUALS(r2_c2, res->getInt64(2)); ASSERT_EQUALS(r2_c3, res->getInt64("b")); ASSERT_EQUALS(r2_c3, res->getInt64(3)); ASSERT_EQUALS(r2_c4, res->getUInt64("b_uns")); ASSERT_EQUALS(r2_c4, res->getUInt64(4)); ASSERT_EQUALS(res->next(), false); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } on_off=false; con->setClientOption("clientTrace", &on_off); } void resultset::getTypes() { logMsg("resultset::getTypes - MySQL_ResultSet::get*"); std::vector::iterator it; std::stringstream msg; bool got_warning=false; ResultSet pres; std::string ps_value; std::string::size_type len_st; std::string::size_type len_ps; try { stmt.reset(con->createStatement()); logMsg("... looping over all kinds of column types"); for (it=columns.begin(); it != columns.end(); it++) { stmt->execute("DROP TABLE IF EXISTS test"); msg.str(""); msg << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(msg.str()); msg.str(""); msg << "... testing " << it->sqldef << ", value = '" << it->value << "'"; logMsg(msg.str()); } catch (sql::SQLException &) { msg.str(""); msg << "... skipping " << it->sqldef; logMsg(msg.str()); continue; } msg.str(""); switch(it->ctype) { case sql::DataType::BIT: msg << "INSERT INTO test(id) VALUES (" << it->value << ")"; break; default: msg << "INSERT INTO test(id) VALUES (\"" << it->value << "\")"; } try { stmt->execute(msg.str()); ASSERT_EQUALS(1, (int)stmt->getUpdateCount()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); logErr("SqlDef: " + it->sqldef); fail(e.what(), __FILE__, __LINE__); } res.reset(stmt->executeQuery("SELECT id, NULL FROM test")); checkResultSetScrolling(res); ASSERT(res->next()); pstmt.reset(con->prepareStatement("SELECT id, NULL FROM test")); pstmt->clearParameters(); pres.reset(pstmt->executeQuery()); checkResultSetScrolling(pres); ASSERT(pres->next()); if (it->check_as_string) { logMsg("... checking string value"); if (it->as_string != res->getString("id")) { msg.str(""); msg << "... expecting '" << it->as_string << "', got '" << res->getString("id") << "'"; logMsg(msg.str()); got_warning=true; } } ASSERT_EQUALS(res->getString("id"), res->getString(1)); try { res->getString(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getString(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getString(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getString(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getDouble("id"), res->getDouble(1)); try { res->getDouble(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getDouble(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getDouble(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getDouble(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getInt(1), res->getInt("id")); try { res->getInt(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getInt(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getUInt(1), res->getUInt("id")); try { res->getUInt(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getUInt(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getUInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getUInt(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getInt64("id"), res->getInt64(1)); try { res->getInt64(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getInt64(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getUInt64("id"), res->getUInt64(1)); try { res->getUInt64(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getUInt64(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getUInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getUInt64(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); ASSERT_EQUALS(res->getBoolean("id"), res->getBoolean(1)); try { res->getBoolean(0); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } try { res->getBoolean(3); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->beforeFirst(); try { res->getBoolean(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->afterLast(); try { res->getBoolean(1); FAIL("Invalid argument not detected"); } catch (sql::InvalidArgumentException &) { } res->first(); // Comparing prepared statement resultset and statement resultset if (it->check_as_string && (pres->getString("id") != res->getString("id"))) { if (it->sqldef.find("ZEROFILL", 0) == std::string::npos) { ps_value=pres->getString("id"); len_st=res->getString("id").length(); len_ps=ps_value.length(); if (len_ps > len_st) { // Something like 1.01000 vs. 1.01 ? std::string::size_type i; for (i=len_st; i < len_ps; i++) { if (ps_value.at(i) != '0') break; } if (i < (len_ps - 1)) { got_warning=true; msg.str(""); msg << "... \t\tWARNING - getString(), PS: '" << pres->getString("id") << "'"; msg << ", Statement: '" << res->getString("id") << "'"; logMsg(msg.str()); } } } } // ASSERT_EQUALS(pres->getString("id"), res->getString("id")); if (!fuzzyEquals(pres->getDouble("id"), res->getDouble("id"), 0.001)) { msg.str(""); msg << "... \t\tWARNING - getDouble(), PS: '" << pres->getDouble("id") << "'"; msg << ", Statement: '" << res->getDouble("id") << "'"; msg << ", Difference: '" << (pres->getDouble("id") - res->getDouble("id")) << "'"; logMsg(msg.str()); got_warning=true; } //ASSERT_EQUALS(pres->getDouble("id"), res->getDouble("id")); if (pres->getInt("id") != res->getInt("id")) { msg.str(""); msg << "... \t\tWARNING - getInt(), PS: '" << pres->getInt("id") << "'"; msg << ", Statement: '" << res->getInt("id") << "'"; logMsg(msg.str()); got_warning=true; } // ASSERT_EQUALS(pres->getInt("id"), res->getInt("id")); if (!it->is_negative && (pres->getUInt("id") != res->getUInt("id"))) { msg.str(""); msg << "... \t\tWARNING - getUInt(), PS: '" << pres->getUInt("id") << "'"; msg << ", Statement: '" << res->getUInt("id") << "'"; logMsg(msg.str()); got_warning=true; } // ASSERT_EQUALS(pres->getUInt("id"), res->getUInt("id")); if (pres->getInt64("id") != res->getInt64("id")) { msg.str(""); msg << "... \t\tWARNING - getInt64(), PS: '" << pres->getInt64("id") << "'"; msg << ", Statement: '" << res->getInt64("id") << "'"; logMsg(msg.str()); got_warning=true; } // ASSERT_EQUALS(pres->getInt64("id"), res->getInt64("id")); if (!it->is_negative && (pres->getUInt64("id") != res->getUInt64("id"))) { msg.str(""); msg << "... \t\tWARNING - getUInt64(), PS: '" << pres->getUInt64("id") << "'"; msg << ", Statement: '" << res->getUInt64("id") << "'"; logMsg(msg.str()); got_warning=true; } // ASSERT_EQUALS(pres->getUInt64("id"), res->getUInt64("id")); ASSERT_EQUALS(pres->getBoolean("id"), res->getBoolean(1)); } if (got_warning) FAIL("See warnings!"); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultset::getTypesMinorIssues() { logMsg("resultset::getTypesMinorIssues - MySQL_ResultSet::get*"); std::vector::iterator it; std::stringstream msg; bool got_warning=false; bool got_minor_warning=false; ResultSet pres; std::string ps_value; std::string::size_type len_st; std::string::size_type len_ps; try { stmt.reset(con->createStatement()); logMsg("... looping over all kinds of column types"); for (it=columns.begin(); it != columns.end(); it++) { stmt->execute("DROP TABLE IF EXISTS test"); msg.str(""); msg << "CREATE TABLE test(dummy TIMESTAMP, id " << it->sqldef << ")"; try { stmt->execute(msg.str()); msg.str(""); msg << "... testing " << it->sqldef << ", value = '" << it->value << "'"; logMsg(msg.str()); } catch (sql::SQLException &) { msg.str(""); msg << "... skipping " << it->sqldef; logMsg(msg.str()); continue; } msg.str(""); switch(it->ctype) { case sql::DataType::BIT: msg << "INSERT INTO test(id) VALUES (" << it->value << ")"; break; default: msg << "INSERT INTO test(id) VALUES (\"" << it->value << "\")"; } try { stmt->execute(msg.str()); ASSERT_EQUALS(1, (int)stmt->getUpdateCount()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); logErr("SqlDef: " + it->sqldef); fail(e.what(), __FILE__, __LINE__); } res.reset(stmt->executeQuery("SELECT id, NULL FROM test")); checkResultSetScrolling(res); ASSERT(res->next()); pstmt.reset(con->prepareStatement("SELECT id, NULL FROM test")); pstmt->clearParameters(); pres.reset(pstmt->executeQuery()); checkResultSetScrolling(pres); ASSERT(pres->next()); if (it->check_as_string && (it->as_string != res->getString("id"))) { msg.str(""); msg << "... expecting '" << it->as_string << "', got '" << res->getString("id") << "'"; logMsg(msg.str()); got_warning=true; } // Comparing prepared statement resultset and statement resultset if (pres->getString("id") != res->getString("id")) { if (it->sqldef.find("ZEROFILL", 0) == std::string::npos) { bool is_minor=false; ps_value=pres->getString("id"); len_st=res->getString("id").length(); len_ps=ps_value.length(); if (len_ps > len_st) { // Something like 1.01000 vs. 1.01 ? std::string::size_type i; for (i=len_st; i < len_ps; i++) { if (ps_value.at(i) != '0') break; } if (i < (len_ps - 1)) { got_warning=true; } else { is_minor=true; got_minor_warning=true; } } if (!it->check_as_string) { is_minor=true; got_minor_warning=true; } else { got_warning=true; } msg.str(""); if (is_minor) { msg << "... \t\tMINOR WARNING - getString(), PS: '" << pres->getString("id") << "'"; } else { msg << "... \t\tWARNING - getString(), PS: '" << pres->getString("id") << "'"; } msg << ", Statement: '" << res->getString("id") << "'"; logMsg(msg.str()); } } } if (got_warning) FAIL("See --verbose warnings!"); /* * We decided to ignore the differences. It is * about number formatting only. Any application using C/C++ * will apply their own formatting style anyway. * No simple fix came to our mind. If we ever have an * idea we should fix it. Meanwhile: won't fix. */ if (got_minor_warning && false) { FAIL("TODO - see MINOR WARNING when using --verbose"); } stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS void resultset::notImplemented() { logMsg("resultset::notImplemented - MySQL_ResultSet::*"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); ASSERT_EQUALS(1, stmt->executeUpdate("INSERT INTO test(id) VALUES (1)")); res.reset(stmt->executeQuery("SELECT id FROM test")); doNotImplemented(); pstmt.reset(con->prepareStatement("SELECT id FROM test")); res.reset(pstmt->executeQuery()); doNotImplemented(); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultset::doNotImplemented() { try { res->getWarnings(); } catch (sql::MethodNotImplementedException) { } try { res->clearWarnings(); } catch (sql::MethodNotImplementedException) { } try { res->insertRow(); } catch (sql::MethodNotImplementedException) { } try { res->moveToCurrentRow(); } catch (sql::MethodNotImplementedException) { } try { res->moveToInsertRow(); } catch (sql::MethodNotImplementedException) { } try { res->refreshRow(); } catch (sql::MethodNotImplementedException) { } try { res->rowDeleted(); } catch (sql::MethodNotImplementedException) { } try { res->rowInserted(); } catch (sql::MethodNotImplementedException) { } try { res->rowUpdated(); } catch (sql::MethodNotImplementedException) { } } #endif void resultset::fetchBigint() { std::stringstream msg; logMsg("resultset::fetchBigint - MySQL_ResultSet::*"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id BIGINT UNSIGNED)"); stmt->execute("INSERT INTO test(id) VALUES (18446744073709551615)"); res.reset(stmt->executeQuery("SELECT id FROM test")); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS doNotImplemented(); #endif pstmt.reset(con->prepareStatement("SELECT id FROM test")); res.reset(pstmt->executeQuery()); res->next(); msg.str(); msg << "... PS: id = " << res->getDouble(1); logMsg(msg.str()); res.reset(stmt->executeQuery("SELECT id FROM test")); res->next(); msg.str(); msg << "... Statement: id = " << res->getDouble(1); logMsg(msg.str()); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultset::fetchBitAsInt() { std::stringstream msg; logMsg("resultset::fetchBitAsInt - MySQL_ResultSet::*"); try { logMsg("... BIT(0) - non-PS"); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id BIT(1))"); stmt->execute("INSERT INTO test(id) VALUES (0)"); stmt->execute("INSERT INTO test(id) VALUES (1)"); res.reset(stmt->executeQuery("SELECT id, CAST(id AS SIGNED) AS bit_as_signed FROM test ORDER BY id")); while (res->next()) { ASSERT_EQUALS(res->getInt("id"), res->getInt("bit_as_signed")); ASSERT_EQUALS(res->getInt("id"), res->getInt(1)); } logMsg("... BIT(0) - PS"); pstmt.reset(con->prepareStatement("SELECT id, CAST(id AS SIGNED) AS bit_as_signed FROM test ORDER BY id")); res.reset(pstmt->executeQuery()); while (res->next()) { ASSERT_EQUALS(res->getInt("id"), res->getInt("bit_as_signed")); ASSERT_EQUALS(res->getInt("id"), res->getInt(1)); } uint64_t c1=UL64(4294967295), c2=UL64(18446744073709551615); logMsg("... BIT(32), BIT(64) - non-PS"); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col1 BIT(32), col2 BIT(64))"); stmt->execute("INSERT INTO test(col1, col2) VALUES(b'11111111111111111111111111111111', b'1111111111111111111111111111111111111111111111111111111111111111')"); res.reset(stmt->executeQuery("SELECT col1, CAST(col1 AS UNSIGNED) AS col1_as_unsigned, col2, CAST(col2 AS UNSIGNED) AS col2_as_unsigned FROM test")); ASSERT(res->next()); ASSERT_EQUALS(c1, res->getUInt64(1)); ASSERT_EQUALS(res->getUInt64("col1_as_unsigned"), res->getUInt64(1)); ASSERT_EQUALS(c2, res->getUInt64("col2")); ASSERT_EQUALS(res->getUInt64("col2_as_unsigned"), res->getUInt64("col2")); logMsg("... BIT(32), BIT(64) - PS"); stmt->execute("DELETE FROM test"); pstmt.reset(con->prepareStatement("INSERT INTO test(col1, col2) VALUES(?,?)")); pstmt->clearParameters(); pstmt->setUInt64(1, c1); pstmt->setUInt64(2, c2); ASSERT_EQUALS(false, pstmt->execute()); pstmt.reset(con->prepareStatement("SELECT col1, CAST(col1 AS UNSIGNED) AS col1_as_unsigned, col2, CAST(col2 AS UNSIGNED) AS col2_as_unsigned FROM test")); res.reset(pstmt->executeQuery()); ASSERT(res->next()); ASSERT_EQUALS(c1, res->getUInt64(1)); ASSERT_EQUALS(res->getUInt64("col1_as_unsigned"), res->getUInt64(1)); ASSERT_EQUALS(c2, res->getUInt64("col2")); ASSERT_EQUALS(res->getUInt64("col2_as_unsigned"), res->getUInt64("col2")); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultset::getResultSetType() { sql::ConnectOptionsMap connection_properties; logMsg("resultset::getResultSetType - MySQL_ResultSet::*"); try { /* url comes from the unit testing framework */ connection_properties["hostName"]=url; /* user comes from the unit testing framework */ connection_properties["userName"]=user; connection_properties["password"]=passwd; connection_properties.erase("defaultStatementResultType"); { logMsg("... testing defaultStatementResultType"); connection_properties["defaultStatementResultType"]=sql::ResultSet::TYPE_FORWARD_ONLY; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } stmt.reset(con->createStatement()); ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_FORWARD_ONLY); pstmt.reset(con->prepareStatement("SELECT 1")); /* NOTE: no bug - PS supports TYPE_SCROLL_INSENSITIVE only and we are setting StatementResultType not PreparedStatementResultType */ res.reset(pstmt->executeQuery()); ASSERT_EQUALS(pstmt->getResultSetType(), sql::ResultSet::TYPE_SCROLL_INSENSITIVE); connection_properties.erase("defaultStatementResultType"); connection_properties["defaultStatementResultType"]=sql::ResultSet::TYPE_SCROLL_INSENSITIVE; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } stmt.reset(con->createStatement()); ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_SCROLL_INSENSITIVE); pstmt.reset(con->prepareStatement("SELECT 1")); res.reset(pstmt->executeQuery()); ASSERT_EQUALS(pstmt->getResultSetType(), sql::ResultSet::TYPE_SCROLL_INSENSITIVE); connection_properties.erase("defaultStatementResultType"); connection_properties["defaultStatementResultType"]=sql::ResultSet::TYPE_SCROLL_SENSITIVE; try { created_objects.clear(); try { con.reset(driver->connect(connection_properties)); FAIL("Bug or API change - TYPE_SCROLL_SENSITIVE is unsupported"); stmt.reset(con->createStatement()); ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_SCROLL_SENSITIVE); pstmt.reset(con->prepareStatement("SELECT 1")); res.reset(pstmt->executeQuery()); ASSERT_EQUALS(pstmt->getResultSetType(), sql::ResultSet::TYPE_SCROLL_INSENSITIVE); } catch (sql::SQLException &e) { logMsg("... expected exception because TYPE_SCROLL_SENSITIVE is unsupported!"); logMsg(e.what()); } } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } } connection_properties.erase("defaultStatementResultType"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultset::JSON_support() { std::stringstream msg; logMsg("resultset::JSON_support - MySQL_ResultSet::*"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, jval JSON)"); stmt->execute("INSERT INTO test(id, jval) VALUES(1, '[1]')"); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS doNotImplemented(); #endif pstmt.reset(con->prepareStatement("SELECT * FROM test")); res.reset(pstmt->executeQuery()); res->next(); msg.str(); ASSERT_EQUALS(1, res->getInt(1)); msg << "... PS: id = " << res->getInt(1); ASSERT_EQUALS("[1]", res->getString(2)); msg << "... PS: jval = " << res->getString(2); logMsg(msg.str()); res.reset(stmt->executeQuery("SELECT * FROM test")); res->next(); msg.str(); ASSERT_EQUALS(1, res->getInt(1)); msg << "... Statement: id = " << res->getInt(1); ASSERT_EQUALS("[1]", res->getString(2)); msg << "... Statement: jval = " << res->getString(2); logMsg(msg.str()); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } } /* namespace resultset */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/resultset.h000644 015771 000012 00000005456 12645244437 023574 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Test of the JDBC ResultSet class counterpart * */ namespace testsuite { namespace classes { class resultset : public unit_fixture { private: typedef unit_fixture super; protected: #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS void doNotImplemented(); #endif public: EXAMPLE_TEST_FIXTURE(resultset) { TEST_CASE(fetchBigint); TEST_CASE(fetchBitAsInt); TEST_CASE(getInt); TEST_CASE(getTypes); TEST_CASE(getResultSetType); TEST_CASE(getTypesMinorIssues); TEST_CASE(JSON_support); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS TEST_CASE(notImplemented); #endif } /** * Test for resultset::getInt*() * * Test of the assorted methods to fetch integers */ void getInt(); /** * Test for resultset::get*() * * Test of the assorted methods to fetch data */ void getTypes(); /** * Test for resultset::getResultSetType() * * Test of the assorted methods to fetch data */ void getResultSetType(); /** * Test for resultset::get*() * * TODO - hack to temporarily seperate test failures from TODO for beta by having more fine grained test */ void getTypesMinorIssues(); #ifdef INCLUDE_NOT_IMPLEMENTED_METHODS /** * Calling methods which throw "not implemented" to detect API changes */ void notImplemented(); #endif /** * Calling methods which throw "not implemented" to detect API changes */ void fetchBigint(); /** * Fetching BIT values as integers - edge cases */ void fetchBitAsInt(); /** * Test for resultset::getString() on JSON type columns * * Test of the assorted methods to fetch JSON strings */ void JSON_support(); }; REGISTER_FIXTURE(resultset); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/resultsetmetadata.cpp000644 015771 000012 00000115561 12645244437 025627 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "resultsetmetadata.h" #include #include #include #include #include #include #include namespace testsuite { namespace classes { void resultsetmetadata::getCatalogName() { logMsg("resultsetmetadata::getCatalogName() - MySQL_ResultSetMetaData::getCatalogName"); bool got_warning=false; try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doGetCatalogName(false, got_warning); logMsg("... PreparedStatement"); runStandardPSQuery(); doGetCatalogName(true, got_warning); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } if (got_warning) { TODO("See --verbose warnings"); FAIL("TODO - see --verbose warnings"); } } void resultsetmetadata::doGetCatalogName(bool is_ps, bool &got_warning) { std::stringstream msg; ResultSetMetaData * meta=res->getMetaData(); if (con->getCatalog() != "" && meta->getCatalogName(1) != "" && (con->getCatalog() != meta->getCatalogName(1))) { got_warning=true; msg.str(""); msg << "...\t\tWARNING expecting catalog = '" << con->getCatalog() << "'"; msg << " got '" << meta->getCatalogName(1) << "'"; logMsg(msg.str()); } if (meta->getCatalogName(1) != "" && meta->getCatalogName(1) != "def") { got_warning=true; msg.str(""); msg << "...\t\tWARNING expecting catalog = 'def'"; msg << " got '" << meta->getCatalogName(1) << "'"; logMsg(msg.str()); } try { meta->getCatalogName(0); FAIL("Column number starts at 1, invalid offset 0 not detected"); } catch (sql::InvalidArgumentException &) { } try { meta->getCatalogName(6); FAIL("Only five columns available but requesting number six, should bail"); } catch (sql::InvalidArgumentException &) { } if (!is_ps) { res->close(); try { meta->getCatalogName(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getColumnCount() { logMsg("resultsetmetadata::getColumnCount() - MySQL_ResultSetMetaData::getColumnCount"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doGetColumnCount(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doGetColumnCount(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetColumnCount(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 5, meta->getColumnCount()); if (!is_ps) { res->close(); try { meta->getCatalogName(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getColumnDisplaySize() { logMsg("resultsetmetadata::getColumnDisplaySize() - MySQL_ResultSetMetaData::getColumnDisplaySize()"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doGetColumnDisplaySize(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doGetColumnDisplaySize(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetColumnDisplaySize(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS((unsigned int) 5, meta->getColumnDisplaySize(1)); ASSERT_EQUALS((unsigned int) 1, meta->getColumnDisplaySize(2)); ASSERT_EQUALS((unsigned int) 5, meta->getColumnDisplaySize(3)); ASSERT_EQUALS((unsigned int) 1, meta->getColumnDisplaySize(4)); ASSERT_EQUALS((unsigned int) 3, meta->getColumnDisplaySize(5)); try { meta->getColumnDisplaySize(0); FAIL("Column number starts at 1, invalid offset 0 not detected"); } catch (sql::InvalidArgumentException &) { } try { meta->getColumnDisplaySize(6); FAIL("Only five columns available but requesting number six, should bail"); } catch (sql::InvalidArgumentException &) { } if (!is_ps) { res->close(); try { meta->getColumnDisplaySize(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getColumnNameAndLabel() { logMsg("resultsetmetadata::getColumnName() - MySQL_ResultSetMetaData::getColumnName(), MySQL_ResultSetMetaData::getColumnLabel()"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS getColumnNameAndLabel"); stmt->execute("CREATE TABLE getColumnNameAndLabel(col1 INT, col2 VARCHAR(10))"); res.reset(stmt->executeQuery("SELECT col1 AS intColumn, col2 AS charColumn FROM getColumnNameAndLabel")); doGetColumnNameAndLabel(false); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT col1 AS intColumn, col2 AS charColumn FROM getColumnNameAndLabel")); res.reset(pstmt->executeQuery()); doGetColumnNameAndLabel(true); stmt->execute("DROP TABLE IF EXISTS getColumnNameAndLabel"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetColumnNameAndLabel(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS("col1", meta->getColumnName(1)); ASSERT_EQUALS("intColumn", meta->getColumnLabel(1)); ASSERT_EQUALS("col2", meta->getColumnName(2)); ASSERT_EQUALS("charColumn", meta->getColumnLabel(2)); try { meta->getColumnName(0); FAIL("Column number starts at 1, invalid offset 0 not detected"); } catch (sql::InvalidArgumentException &) { } try { meta->getColumnLabel(0); FAIL("Column number starts at 1, invalid offset 0 not detected"); } catch (sql::InvalidArgumentException &) { } try { meta->getColumnName(6); FAIL("Only five columns available but requesting number six, should bail"); } catch (sql::InvalidArgumentException &) { } try { meta->getColumnLabel(6); FAIL("Only five columns available but requesting number six, should bail"); } catch (sql::InvalidArgumentException &) { } if (!is_ps) { res->close(); try { meta->getColumnName(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getColumnType() { logMsg("resultsetmetadata::getColumnType() - MySQL_ResultSetMetaData::getColumnType()"); try { std::stringstream sql; std::vector::iterator it; stmt.reset(con->createStatement()); bool type_found=false; sql::DatabaseMetaData * dbmeta=con->getMetaData(); ResultSet restypes(dbmeta->getTypeInfo()); logMsg("... looping over all kinds of columns and testing type and type name"); for (it=columns.begin(); it != columns.end(); it++) { stmt->execute("DROP TABLE IF EXISTS test"); sql.str(""); sql << "CREATE TABLE test(col1 " << it->sqldef << ")"; try { stmt->execute(sql.str()); sql.str(""); sql << "INSERT INTO test(col1) VALUES ('" << it->value << "')"; stmt->execute(sql.str()); res.reset(stmt->executeQuery("SELECT * FROM test")); checkResultSetScrolling(res); ResultSetMetaData * meta=res->getMetaData(); logMsg(it->sqldef); ASSERT_EQUALS(it->ctype, meta->getColumnType(1)); ASSERT_EQUALS(it->name, meta->getColumnTypeName(1)); sql.str(""); sql << "... OK, SQL:" << it->sqldef << " -> Type = " << it->name; sql << " (Code = " << it->ctype << ")"; logMsg(sql.str()); restypes->beforeFirst(); type_found=false; while (restypes->next()) { if (restypes->getInt("DATA_TYPE") == it->ctype) { type_found=true; break; } } if (!type_found) { sql.str(""); sql << "The type code " << it->ctype << " seems not to be in the type list "; sql << "returned by DatabaseMetaData::getTypeInfo()."; logMsg(sql.str()); FAIL("Wrong type code"); } sql.str(""); sql << "... OK type name is known by DatabaseMetaData::getTypeInfo()"; restypes->beforeFirst(); type_found=false; while (restypes->next()) { if (restypes->getString("TYPE_NAME") == std::string(it->name)) { type_found=true; break; } } if (!type_found) { sql.str(""); sql << "The type name " << it->name << " seems not to be in the type list "; sql << "returned by DatabaseMetaData::getTypeInfo()."; logMsg(sql.str()); FAIL("Wrong type name"); } sql.str(""); sql << "... OK type name is known by DatabaseMetaData::getTypeInfo()"; } catch (sql::SQLException &e) { logMsg(sql.str()); sql.str(""); sql << "... skipping " << it->name << " " << it->sqldef << ": "; sql << e.what(); logMsg(sql.str()); } } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::getPrecision() { logMsg("resultsetmetadata::getPrecision() - MySQL_ResultSetMetaData::getPrecision"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doGetPrecision(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doGetPrecision(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetPrecision(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); ASSERT_GT((unsigned int) 4, meta->getPrecision(1)); ASSERT_GT((unsigned int) 0, meta->getPrecision(2)); ASSERT_GT((unsigned int) 4, meta->getPrecision(3)); ASSERT_GT((unsigned int) 0, meta->getPrecision(4)); ASSERT_GT((unsigned int) 2, meta->getPrecision(5)); try { meta->getPrecision(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->getPrecision(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getScale() { logMsg("resultsetmetadata::getScale() - MySQL_ResultSetMetaData::getScale"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doGetScale(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doGetScale(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetScale(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); try { meta->getScale(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->getScale(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getSchemaName() { logMsg("resultsetmetadata::getSchemaName() - MySQL_ResultSetMetaData::getSchemaName"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); stmt->execute("INSERT INTO test(id) VALUES (1)"); res.reset(stmt->executeQuery("SELECT * FROM test")); checkResultSetScrolling(res); doGetSchemaName(false); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT * FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); doGetSchemaName(true); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetSchemaName(bool is_ps) { int i; ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->getSchemaName(1), con->getSchema()); runStandardQuery(); ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->getSchemaName(i), ""); try { meta->getSchemaName(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->getSchemaName(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getTableName() { logMsg("resultsetmetadata::getTableName() - MySQL_ResultSetMetaData::getTableName"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); stmt->execute("INSERT INTO test(id) VALUES (1)"); res.reset(stmt->executeQuery("SELECT * FROM test")); checkResultSetScrolling(res); logMsg("... Statement"); doGetTableName(false); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT * FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); doGetTableName(true); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetTableName(bool is_ps) { int i; ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->getTableName(1), "test"); runStandardQuery(); ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->getTableName(i), ""); try { meta->getTableName(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->getTableName(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isAutoIncrement() { logMsg("resultsetmetadata::isAutoIncrement() - MySQL_ResultSetMetaData::isAutoIncrement"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, col1 CHAR(1))"); stmt->execute("INSERT INTO test(id, col1) VALUES (1, 'a')"); logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT id, col1 FROM test")); checkResultSetScrolling(res); ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->isAutoIncrement(1), true); ASSERT_EQUALS(meta2->isAutoIncrement(2), false); runStandardQuery(); doIsAutoIncrement(false); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT id, col1 FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isAutoIncrement(1), true); ASSERT_EQUALS(meta2->isAutoIncrement(2), false); runStandardPSQuery(); doIsAutoIncrement(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsAutoIncrement(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->isAutoIncrement(i), false); try { meta->isAutoIncrement(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isAutoIncrement(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isCaseSensitive() { logMsg("resultsetmetadata::isCaseSensitive() - MySQL_ResultSetMetaData::isCaseSensitive"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, col1 CHAR(1), col2 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin')"); stmt->execute("INSERT INTO test(id, col1, col2) VALUES (1, 'a', 'b')"); logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT id, col1, col2 FROM test")); checkResultSetScrolling(res); ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->isCaseSensitive(1), false); ASSERT_EQUALS(meta2->isCaseSensitive(2), false); /* NOTE: There is no reliable way to detect CI/CS if ( !TestsRunner::getStartOptions()->getBool( "dont-use-is" ) ) { // connection_collation distorts the collation of the results (character_set_results) doesn't help // and thus we can't say for sure whether the original column was CI or CS. Only I_S.COLUMNS can tell us. ASSERT_EQUALS(meta2->isCaseSensitive(3), true); } else { logMsg("... skipping 'collate_bin' test because we don't use I_S"); } */ logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT id, col1, col2 FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isCaseSensitive(1), false); ASSERT_EQUALS(meta2->isCaseSensitive(2), false); /* if (!TestsRunner::getStartOptions()->getBool( "dont-use-is" )) { // connection_collation distorts the collation of the results (character_set_results) doesn't help // and thus we can't say for sure whether the original column was CI or CS. Only I_S.COLUMNS can tell us. ASSERT_EQUALS(meta2->isCaseSensitive(3), true); } */ logMsg("... Statement"); runStandardQuery(); doIsCaseSensitive(false); stmt->execute("SET @old_charset_res=@@session.character_set_results"); stmt->execute("SET character_set_results=NULL"); res.reset(stmt->executeQuery("SELECT id, col1, col2 FROM test")); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isCaseSensitive(1), false); ASSERT_EQUALS(meta2->isCaseSensitive(2), false); ASSERT_EQUALS(meta2->isCaseSensitive(3), true); stmt->execute("SET character_set_results=@old_charset_res"); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsCaseSensitive(true); stmt->execute("SET @old_charset_res=@@session.character_set_results"); stmt->execute("SET character_set_results=NULL"); pstmt.reset(con->prepareStatement("SELECT id, col1, col2 FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isCaseSensitive(1), false); ASSERT_EQUALS(meta2->isCaseSensitive(2), false); ASSERT_EQUALS(meta2->isCaseSensitive(3), true); stmt->execute("SET character_set_results=@old_charset_res"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsCaseSensitive(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 5; i++) ASSERT_EQUALS(meta->isCaseSensitive(i), false); try { meta->isCaseSensitive(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isCaseSensitive(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isZerofill() { logMsg("resultsetmetadata::isZerofill() - MySQL_ResultSetMetaData::isZerofill"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, col1 INT ZEROFILL)"); stmt->execute("INSERT INTO test(id, col1) VALUES (1, 1)"); logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT id, col1 FROM test")); checkResultSetScrolling(res); ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->isZerofill(1), false); ASSERT_EQUALS(meta2->isZerofill(2), true); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT id, col1 FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isZerofill(1), false); ASSERT_EQUALS(meta2->isZerofill(2), true); logMsg("... Statement"); runStandardQuery(); doIsZerofill(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsZerofill(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsZerofill(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 5; i++) ASSERT_EQUALS(meta->isZerofill(i), false); try { meta->isZerofill(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isZerofill(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isCurrency() { logMsg("resultsetmetadata::isCurrency() - MySQL_ResultSetMetaData::isCurrency"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsCurrency(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsCurrency(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsCurrency(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->isCurrency(i), false); try { meta->isCurrency(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isCurrency(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isDefinitelyWritable() { logMsg("resultsetmetadata::isDefinitelyWritable() - MySQL_ResultSetMetaData::isDefinitelyWritable"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsDefinitelyWritable(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsDefinitelyWritable(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsDefinitelyWritable(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) { ASSERT_EQUALS(meta->isDefinitelyWritable(i), false); ASSERT_EQUALS(meta->isWritable(i), false); ASSERT_EQUALS(meta->isReadOnly(i), true); } try { meta->isDefinitelyWritable(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isDefinitelyWritable(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isNullable() { logMsg("resultsetmetadata::isNullable() - MySQL_ResultSetMetaData::isNullable"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsNullable(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsNullable(true); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, col1 CHAR(1) DEFAULT NULL, col2 CHAR(10) NOT NULL)"); stmt->execute("INSERT INTO test(id, col2) VALUES (1, 'b')"); logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT id, col1, col2 FROM test")); checkResultSetScrolling(res); ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->isNullable(1), sql::ResultSetMetaData::columnNullable); ASSERT_EQUALS(meta2->isNullable(2), sql::ResultSetMetaData::columnNullable); ASSERT_EQUALS(meta2->isNullable(3), sql::ResultSetMetaData::columnNoNulls); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT id, col1, col2 FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isNullable(1), sql::ResultSetMetaData::columnNullable); ASSERT_EQUALS(meta2->isNullable(2), sql::ResultSetMetaData::columnNullable); ASSERT_EQUALS(meta2->isNullable(3), sql::ResultSetMetaData::columnNoNulls); stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsNullable(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->isNullable(i), sql::ResultSetMetaData::columnNoNulls); try { meta->isNullable(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isNullable(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isReadOnly() { logMsg("resultsetmetadata::isReadOnly() - MySQL_ResultSetMetaData::isReadOnly"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsReadOnly(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsReadOnly(true); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, col1 CHAR(1), col2 CHAR(10))"); stmt->execute("INSERT INTO test(id, col1, col2) VALUES (1, 'a', 'b')"); logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT id AS 'abc', col1, col2, 1 FROM test")); checkResultSetScrolling(res); ResultSetMetaData * meta2=res->getMetaData(); ASSERT_EQUALS(meta2->isReadOnly(1), false); ASSERT_EQUALS(meta2->isReadOnly(2), false); ASSERT_EQUALS(meta2->isReadOnly(3), false); ASSERT_EQUALS(meta2->isReadOnly(4), true); try { stmt->execute("DROP VIEW IF EXISTS v_test"); stmt->execute("CREATE VIEW v_test(col1, col2) AS SELECT id, id + 1 FROM test"); res.reset(stmt->executeQuery("SELECT col1, col2 FROM v_test")); checkResultSetScrolling(res); ResultSetMetaData * meta3=res->getMetaData(); ASSERT_EQUALS(meta3->isReadOnly(1), false); /* Expecting ERROR 1348 (HY000): Column 'col2' is not updatable */ ASSERT_EQUALS(meta3->isReadOnly(2), true); } catch (sql::SQLException &) { logMsg("... skipping VIEW test"); } logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT id AS 'abc', col1, col2, 1 FROM test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); meta2=(res->getMetaData()); ASSERT_EQUALS(meta2->isReadOnly(1), false); ASSERT_EQUALS(meta2->isReadOnly(2), false); ASSERT_EQUALS(meta2->isReadOnly(3), false); ASSERT_EQUALS(meta2->isReadOnly(4), true); try { stmt->execute("DROP VIEW IF EXISTS v_test"); stmt->execute("CREATE VIEW v_test(col1, col2) AS SELECT id, id + 1 FROM test"); pstmt.reset(con->prepareStatement("SELECT col1, col2 FROM v_test")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); ResultSetMetaData * meta3=res->getMetaData(); ASSERT_EQUALS(meta3->isReadOnly(1), false); /* Expecting ERROR 1348 (HY000): Column 'col2' is not updatable */ ASSERT_EQUALS(meta3->isReadOnly(2), true); stmt->execute("DROP VIEW IF EXISTS v_test"); } catch (sql::SQLException &) { logMsg("... skipping VIEW test"); } stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsReadOnly(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->isReadOnly(i), true); try { meta->isReadOnly(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isReadOnly(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isSearchable() { logMsg("resultsetmetadata::isSearchable() - MySQL_ResultSetMetaData::isSearchable"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsSearchable(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsSearchable(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsSearchable(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 6; i++) ASSERT_EQUALS(meta->isSearchable(i), true); try { meta->isSearchable(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isSearchable(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isSigned() { logMsg("resultsetmetadata::isSigned() - MySQL_ResultSetMetaData::isSigned"); std::stringstream sql; std::vector::iterator it; ResultSetMetaData * meta_st; ResultSetMetaData * meta_ps; ResultSet res_ps; try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsSigned(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsSigned(true); stmt.reset(con->createStatement()); for (it=columns.begin(); it != columns.end(); it++) { stmt->execute("DROP TABLE IF EXISTS test"); sql.str(""); sql << "CREATE TABLE test(col1 " << it->sqldef << ")"; try { stmt->execute(sql.str()); sql.str(""); sql << "INSERT INTO test(col1) VALUES ('" << it->value << "')"; stmt->execute(sql.str()); sql.str(""); sql << std::boolalpha << "... testing, SQL:" << it->sqldef << " -> Signed = " << it->is_signed; logMsg(sql.str()); } catch (sql::SQLException &e) { logMsg(sql.str()); sql.str(""); sql << "... skipping " << it->name << " " << it->sqldef << ": "; sql << e.what(); logMsg(sql.str()); continue; } res.reset(stmt->executeQuery("SELECT col1 FROM test")); checkResultSetScrolling(res); meta_st=(res->getMetaData()); pstmt.reset(con->prepareStatement("SELECT col1 FROM test")); res_ps.reset(pstmt->executeQuery()); meta_ps=(res_ps->getMetaData()); ASSERT_EQUALS(meta_st->isSigned(1), meta_ps->isSigned(1)); ASSERT_EQUALS(it->is_signed, meta_st->isSigned(1)); } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsSigned(bool is_ps) { int i; ResultSetMetaData * meta=res->getMetaData(); for (i=1; i < 5; i++) { ASSERT_EQUALS(meta->isSigned(i), true); } try { meta->isSigned(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isSigned(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::isWritable() { logMsg("resultsetmetadata::isWritable() - MySQL_ResultSetMetaData::isWritable"); try { /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); runStandardQuery(); doIsWritable(false); logMsg("... PreparedStatement"); runStandardPSQuery(); doIsWritable(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doIsWritable(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); /* NOTE: isReadable covers isWritable */ try { meta->isWritable(6); FAIL("Invalid offset 6 not recognized"); } catch (sql::SQLException &) { } if (!is_ps) { res->close(); try { meta->isWritable(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getColumnCharset() { logMsg("resultsetmetadata::getColumnCharset() - MySQL_ResultSetMetaData::getColumnCharset()"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS columnCharset"); stmt->execute("CREATE TABLE columnCharset(col1 VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_general_ci)"); stmt->execute("INSERT INTO columnCharset VALUES ('cal1val')"); stmt->execute("SET @@character_set_results=NULL"); /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT col1 from columnCharset")); doGetColumnCharset(false); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT col1 from columnCharset")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); doGetColumnCharset(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetColumnCharset(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS("latin1", meta->getColumnCharset(1)); if (!is_ps) { res->close(); try { meta->getCatalogName(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::getColumnCollation() { logMsg("resultsetmetadata::getColumnCollation() - MySQL_ResultSetMetaData::getColumnCollation()"); try { stmt.reset(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS columnCollation"); stmt->execute("CREATE TABLE columnCollation(col1 VARCHAR(10) COLLATE latin1_general_ci)"); stmt->execute("INSERT INTO columnCollation VALUES ('cal1val')"); stmt->execute("SET @@character_set_results=NULL"); /* This is a dull test, its about code coverage not achieved with the JDBC tests */ logMsg("... Statement"); res.reset(stmt->executeQuery("SELECT col1 from columnCollation")); doGetColumnCollation(false); logMsg("... PreparedStatement"); pstmt.reset(con->prepareStatement("SELECT col1 from columnCollation")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); doGetColumnCollation(true); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void resultsetmetadata::doGetColumnCollation(bool is_ps) { ResultSetMetaData * meta=res->getMetaData(); ASSERT_EQUALS("latin1_general_ci", meta->getColumnCollation(1)); if (!is_ps) { res->close(); try { meta->getColumnCollation(1); FAIL("Can fetch meta from invalid resultset"); } catch (sql::SQLException &) { } } } void resultsetmetadata::runStandardQuery() { stmt.reset(con->createStatement()); res.reset(stmt->executeQuery("SELECT 'Hello' AS a, ' ', 'world', '!', 123 AS z")); checkResultSetScrolling(res); } void resultsetmetadata::runStandardPSQuery() { pstmt.reset(con->prepareStatement("SELECT 'Hello' AS a, ' ', 'world', '!', 123 AS z")); res.reset(pstmt->executeQuery()); checkResultSetScrolling(res); } } /* namespace resultsetmetadata */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/resultsetmetadata.h000644 015771 000012 00000017544 12645244437 025276 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class resultsetmetadata : public unit_fixture { private: typedef unit_fixture super; protected: /* * Utility: run a query and fetch the resultset */ void runStandardQuery(); /** * Utility: run a query through PS interface and fetch the resultset */ void runStandardPSQuery(); void doGetCatalogName(bool is_ps, bool &got_warning); void doGetColumnCount(bool is_ps); void doGetColumnDisplaySize(bool is_ps); void doGetColumnNameAndLabel(bool is_ps); void doGetPrecision(bool is_ps); void doGetScale(bool is_ps); void doGetSchemaName(bool is_ps); void doGetTableName(bool is_ps); void doIsAutoIncrement(bool is_ps); void doIsCaseSensitive(bool is_ps); void doIsZerofill(bool is_ps); void doIsCurrency(bool is_ps); void doIsDefinitelyWritable(bool is_ps); void doIsNullable(bool is_ps); void doIsReadOnly(bool is_ps); void doIsSearchable(bool is_ps); void doIsSigned(bool is_ps); void doIsWritable(bool is_ps); void doGetColumnCharset(bool is_ps); void doGetColumnCollation(bool is_ps); public: EXAMPLE_TEST_FIXTURE(resultsetmetadata) { TEST_CASE(getCatalogName); TEST_CASE(getColumnCount); TEST_CASE(getColumnDisplaySize); TEST_CASE(getColumnNameAndLabel); TEST_CASE(getColumnType); TEST_CASE(getPrecision); TEST_CASE(getScale); TEST_CASE(getSchemaName); TEST_CASE(getTableName); TEST_CASE(isAutoIncrement); TEST_CASE(isCaseSensitive); TEST_CASE(isZerofill); TEST_CASE(isCurrency); TEST_CASE(isDefinitelyWritable); TEST_CASE(isNullable); TEST_CASE(isReadOnly); TEST_CASE(isSearchable); TEST_CASE(isSigned); TEST_CASE(isWritable); TEST_CASE(getColumnCharset); TEST_CASE(getColumnCollation); } /** * Test for ResultSetMetaData::getCatalogName() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getCatalogName(); /** * Test for ResultSetMetaData::getColumnCount() * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnCount(); /** * Test for ResultSetMetaData::getColumnDisplaySize * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnDisplaySize(); /** * Test for ResultSetMetaData::getColumnName, ResultSetMetaData::getColumnLabel * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnNameAndLabel(); /** * Test for ResultSetMetaData::getColumType * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnType(); /** * Test for ResultSetMetaData::getPrecision * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getPrecision(); /** * Test for ResultSetMetaData::getScale * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getScale(); /** * Test for ResultSetMetaData::getSchemaName * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getSchemaName(); /** * Test for ResultSetMetaData::getTableName * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getTableName(); /** * Test for ResultSetMetaData::isAutoIncrement * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isAutoIncrement(); /** * Test for ResultSetMetaData::isCaseSensitive * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isCaseSensitive(); /** * Test for ResultSetMetaData::isZerofill * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isZerofill(); /** * Test for ResultSetMetaData::isCurrency * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isCurrency(); /** * Test for ResultSetMetaData::isDefinitelyWritable * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isDefinitelyWritable(); /** * Test for ResultSetMetaData::isNullable * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isNullable(); /** * Test for ResultSetMetaData::isReadOnly * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isReadOnly(); /** * Test for ResultSetMetaData::isSearchable * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isSearchable(); /** * Test for ResultSetMetaData::isSigned * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isSigned(); /** * Test for ResultSetMetaData::isWritable * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void isWritable(); /** * Test for ResultSetMetaData::getColumnCharset * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnCharset(); /** * Test for ResultSetMetaData::getColumnCollation * * Focus on code coverage: invalid parameter, invalid resultset * JDBC compliance tests should take care that it does what its supposed to do */ void getColumnCollation(); }; REGISTER_FIXTURE(resultsetmetadata); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/savepoint.cpp000644 015771 000012 00000005112 12645244437 024072 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "savepoint.h" #include #include namespace testsuite { namespace classes { void savepoint::getSavepointId() { logMsg("savepoint::getSavepointId() - MySQL_Savepoint::getSavepointId()"); try { con->setAutoCommit(true); boost::scoped_ptr< sql::Savepoint > sp(con->setSavepoint("mysavepoint")); FAIL("You should not be able to set a savepoint in autoCommit mode"); } catch (sql::SQLException &) { } try { con->setAutoCommit(false); boost::scoped_ptr< sql::Savepoint > sp(con->setSavepoint("mysavepoint")); try { sp->getSavepointId(); FAIL("Anonymous savepoints are not supported"); } catch (sql::InvalidArgumentException &) { } con->releaseSavepoint(sp.get()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void savepoint::getSavepointName() { logMsg("savepoint::getSavepointName() - MySQL_Savepoint::getSavepointName()"); try { con->setAutoCommit(false); boost::scoped_ptr< sql::Savepoint > sp(con->setSavepoint("mysavepoint")); ASSERT_EQUALS("mysavepoint", sp->getSavepointName()); con->releaseSavepoint(sp.get()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } } /* namespace savepoint */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/savepoint.h000644 015771 000012 00000003343 12645244437 023543 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class savepoint : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(savepoint) { TEST_CASE(getSavepointId); TEST_CASE(getSavepointName); } /** * Test savepoint::getSavepointId() * * Save points must have names at the time of writing */ void getSavepointId(); /** * Test savepoint::getSavepointName() * * Save points must have names at the time of writing */ void getSavepointName(); }; REGISTER_FIXTURE(savepoint); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/statement.cpp000644 015771 000012 00000041344 12645244437 024075 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "statement.h" #include #include namespace testsuite { namespace classes { void statement::anonymousSelect() { logMsg("statement::anonymousSelect() - MySQL_Statement::*, MYSQL_Resultset::*"); stmt.reset(con->createStatement()); try { res.reset(stmt->executeQuery("SELECT ' ', NULL")); ASSERT(res->next()); ASSERT_EQUALS(" ", res->getString(1)); std::string mynull(res->getString(2)); ASSERT(res->isNull(2)); ASSERT(res->wasNull()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void statement::getWarnings() { logMsg("statement::getWarnings() - MySQL_Statement::get|clearWarnings()"); std::stringstream msg; unsigned int count= 0; stmt.reset(con->createStatement()); try { stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT UNSIGNED)"); // Generating 2 warnings to make sure we get only the last 1 - won't hurt stmt->execute("INSERT INTO test(id) VALUES (-2)"); // Lets hope that this will always cause a 1264 or similar warning stmt->execute("INSERT INTO test(id) VALUES (-1)"); for (const sql::SQLWarning* warn=stmt->getWarnings(); warn; warn=warn->getNextWarning()) { ++count; msg.str(""); msg << "... ErrorCode = '" << warn->getErrorCode() << "', "; msg << "SQLState = '" << warn->getSQLState() << "', "; msg << "ErrorMessage = '" << warn->getMessage() << "'"; logMsg(msg.str()); ASSERT((0 != warn->getErrorCode())); if (1264 == warn->getErrorCode()) { ASSERT_EQUALS("22003", warn->getSQLState()); } else { ASSERT(("" != warn->getSQLState())); } ASSERT(("" != warn->getMessage())); } ASSERT_EQUALS(1, count); for (const sql::SQLWarning* warn=stmt->getWarnings(); warn; warn=warn->getNextWarning()) { msg.str(""); msg << "... ErrorCode = '" << warn->getErrorCode() << "', "; msg << "SQLState = '" << warn->getSQLState() << "', "; msg << "ErrorMessage = '" << warn->getMessage() << "'"; logMsg(msg.str()); ASSERT((0 != warn->getErrorCode())); if (1264 == warn->getErrorCode()) { ASSERT_EQUALS("22003", warn->getSQLState()); } else { ASSERT(("" != warn->getSQLState())); } ASSERT(("" != warn->getMessage())); } stmt->clearWarnings(); for (const sql::SQLWarning* warn=stmt->getWarnings(); warn; warn=warn->getNextWarning()) { FAIL("There should be no more warnings!"); } // New warning stmt->execute("INSERT INTO test(id) VALUES (-3)"); // Verifying we have warnings now ASSERT(stmt->getWarnings() != NULL); // Statement without tables access does not reset warnings. stmt->execute("SELECT 1"); ASSERT(stmt->getWarnings() == NULL); res.reset(stmt->getResultSet()); res->next(); // TODO - how to use getNextWarning() ? stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void statement::clearWarnings() { logMsg("statement::clearWarnings() - MySQL_Statement::clearWarnings"); // const sql::SQLWarning* warn; // std::stringstream msg; stmt.reset(con->createStatement()); try { stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(col1 DATETIME, col2 DATE)"); stmt->execute("INSERT INTO test SET col1 = NOW()"); // Lets hope that this will always cause a 1264 or similar warning ASSERT(!stmt->execute("UPDATE test SET col2 = col1")); stmt->clearWarnings(); // TODO - how to verify? // TODO - how to use getNextWarning() ? stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void statement::callSP() { logMsg("statement::callSP() - MySQL_Statement::*"); std::stringstream msg; try { sql::ConnectOptionsMap connection_properties; /* url comes from the unit testing framework */ connection_properties["hostName"]=url; /* user comes from the unit testing framework */ connection_properties["userName"]=user; connection_properties["password"]=passwd; bool bval= !TestsRunner::getStartOptions()->getBool("dont-use-is"); connection_properties["metadataUseInfoSchema"]=bval; connection_properties.erase("CLIENT_MULTI_RESULTS"); connection_properties["CLIENT_MULTI_RESULTS"]=true; con.reset(driver->connect(connection_properties)); con->setSchema(db); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } try { stmt.reset(con->createStatement()); try { stmt->execute("DROP PROCEDURE IF EXISTS p"); } catch (sql::SQLException &e) { logMsg("... skipping:"); logMsg(e.what()); return; } sql::DatabaseMetaData * dbmeta=con->getMetaData(); ASSERT(!stmt->execute("DROP TABLE IF EXISTS test")); ASSERT(!stmt->execute("CREATE TABLE test(id INT)")); ASSERT(!stmt->execute("CREATE PROCEDURE p() BEGIN INSERT INTO test(id) VALUES (123), (456); END;")); ASSERT(!stmt->execute("CALL p()")); ASSERT_EQUALS(2, (int) stmt->getUpdateCount()); ASSERT(stmt->execute("SELECT id FROM test ORDER BY id ASC")); res.reset(stmt->getResultSet()); ASSERT(res->next()); ASSERT_EQUALS(123, res->getInt("id")); ASSERT(!stmt->execute("DROP TABLE IF EXISTS test")); stmt->execute("DROP PROCEDURE IF EXISTS p"); ASSERT(!stmt->execute("CREATE PROCEDURE p(OUT ver_param VARCHAR(250)) BEGIN SELECT VERSION() INTO ver_param; END;")); ASSERT(!stmt->execute("CALL p(@version)")); ASSERT(stmt->execute("SELECT @version AS _version")); res.reset(stmt->getResultSet()); ASSERT(res->next()); ASSERT_EQUALS(dbmeta->getDatabaseProductVersion(), res->getString("_version")); stmt->execute("DROP PROCEDURE IF EXISTS p"); ASSERT(!stmt->execute("CREATE PROCEDURE p(IN ver_in VARCHAR(250), OUT ver_out VARCHAR(250)) BEGIN SELECT ver_in INTO ver_out; END;")); ASSERT(!stmt->execute("CALL p('myver', @version)")); ASSERT(stmt->execute("SELECT @version AS _version")); res.reset(stmt->getResultSet()); ASSERT(res->next()); ASSERT_EQUALS("myver", res->getString("_version")); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT, label CHAR(1))"); ASSERT_EQUALS(3, stmt->executeUpdate("INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c')")); stmt->execute("DROP PROCEDURE IF EXISTS p"); ASSERT(!stmt->execute("CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id, label FROM test ORDER BY id ASC; END;")); ASSERT(stmt->execute("CALL p()")); msg.str(""); do { res.reset(stmt->getResultSet()); while (res->next()) { msg << res->getInt("id") << res->getString(2); } } while (stmt->getMoreResults()); ASSERT_EQUALS("1a2b3c", msg.str()); stmt->execute("DROP PROCEDURE IF EXISTS p"); ASSERT(!stmt->execute("CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id, label FROM test ORDER BY id ASC; SELECT id, label FROM test ORDER BY id DESC; END;")); ASSERT(stmt->execute("CALL p()")); msg.str(""); do { res.reset(stmt->getResultSet()); while (res->next()) { msg << res->getInt("id") << res->getString(2); } } while (stmt->getMoreResults()); ASSERT_EQUALS("1a2b3c3c2b1a", msg.str()); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void statement::selectZero() { logMsg("statement::selectZero() - MySQL_Statement::*"); stmt.reset(con->createStatement()); try { res.reset(stmt->executeQuery("SELECT 1, -1, 0")); ASSERT(res->next()); ASSERT_EQUALS("1", res->getString(1)); ASSERT_EQUALS("-1", res->getString(2)); ASSERT_EQUALS("0", res->getString(3)); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void statement::unbufferedFetch() { logMsg("statement::unbufferedFetch() - MySQL_Resultset::*"); sql::ConnectOptionsMap connection_properties; int id=0; try { /* This is the first way to do an unbuffered fetch... */ /* url comes from the unit testing framework */ connection_properties["hostName"]=url; /* user comes from the unit testing framework */ connection_properties["userName"]=user; connection_properties["password"]=passwd; bool bval= !TestsRunner::getStartOptions()->getBool("dont-use-is"); connection_properties["metadataUseInfoSchema"]=bval; logMsg("... setting TYPE_FORWARD_ONLY through connection map"); connection_properties.erase("defaultStatementResultType"); { connection_properties["defaultStatementResultType"]=sql::ResultSet::TYPE_FORWARD_ONLY; try { created_objects.clear(); con.reset(driver->connect(connection_properties)); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } con->setSchema(db); stmt.reset(con->createStatement()); ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_FORWARD_ONLY); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); stmt->execute("INSERT INTO test(id) VALUES (0), (2), (3), (4), (5)"); ASSERT_EQUALS(5, (int) stmt->getUpdateCount()); stmt->execute("UPDATE test SET id = 1 WHERE id = 0"); ASSERT_EQUALS(1, (int) stmt->getUpdateCount()); stmt->execute("DELETE FROM test WHERE id = 1"); ASSERT_EQUALS(1, (int) stmt->getUpdateCount()); stmt->execute("INSERT INTO test(id) VALUES (1)"); ASSERT_EQUALS(1, (int) stmt->getUpdateCount()); logMsg("... simple forward reading"); res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id ASC")); id=0; while (res->next()) { id++; ASSERT_EQUALS(res->getInt(1), res->getInt("id")); ASSERT_EQUALS(id, res->getInt("id")); } checkUnbufferedScrolling(); logMsg("... simple forward reading again"); res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id DESC")); try { res->beforeFirst(); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } id=5; while (res->next()) { ASSERT_EQUALS(res->getInt(1), res->getInt("id")); ASSERT_EQUALS(id, res->getInt("id")); id--; } } connection_properties.erase("defaultStatementResultType"); logMsg("... setting TYPE_FORWARD_ONLY through setClientOption()"); try { created_objects.clear(); con.reset(getConnection()); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } int option=sql::ResultSet::TYPE_FORWARD_ONLY; con->setSchema(db); con->setClientOption("defaultStatementResultType", (static_cast (&option))); stmt.reset(con->createStatement()); logMsg("... simple forward reading"); res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id ASC")); id=0; while (res->next()) { id++; ASSERT_EQUALS(res->getInt(1), res->getInt("id")); ASSERT_EQUALS(id, res->getInt("id")); } checkUnbufferedScrolling(); logMsg("... simple forward reading again"); res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id DESC")); try { res->beforeFirst(); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } id=5; while (res->next()) { ASSERT_EQUALS(res->getInt(1), res->getInt("id")); ASSERT_EQUALS(id, res->getInt("id")); id--; } logMsg("... setting TYPE_FORWARD_ONLY pointer magic"); try { created_objects.clear(); con.reset(getConnection()); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } con->setSchema(db); stmt.reset(con->createStatement()); res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)->executeQuery("SELECT id FROM test ORDER BY id ASC"))); logMsg("... simple forward reading"); id=0; while (res->next()) { id++; ASSERT_EQUALS(res->getInt(1), res->getInt("id")); ASSERT_EQUALS(id, res->getInt("id")); } checkUnbufferedScrolling(); logMsg("... simple forward reading again"); res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)->executeQuery("SELECT id FROM test ORDER BY id DESC"))); ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_FORWARD_ONLY); try { res->beforeFirst(); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } id=5; while (res->next()) { ASSERT_EQUALS(res->getInt(1), res->getInt("id")); ASSERT_EQUALS(id, res->getInt("id")); id--; } stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void statement::unbufferedOutOfSync() { logMsg("statement::unbufferedOutOfSync() - MySQL_Statement::*"); try { stmt.reset(con->createStatement()); res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)->executeQuery("SELECT 1"))); ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_FORWARD_ONLY); res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)->executeQuery("SELECT 1"))); FAIL("Commands should be out of sync"); } catch (sql::SQLException &e) { logMsg("... expecting Out-of-sync exception"); logMsg(e.what()); logMsg("SQLState: " + std::string(e.getSQLState())); } } void statement::checkUnbufferedScrolling() { logMsg("... checkUnbufferedScrolling"); try { res->previous(); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } try { res->absolute(1); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } try { res->afterLast(); logMsg("... a bit odd, but OK, its forward"); } catch (sql::SQLException &e) { fail(e.what(), __FILE__, __LINE__); } try { res->beforeFirst(); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } try { res->last(); FAIL("Nonscrollable result set not detected"); } catch (sql::SQLException &) { } } void statement::queryTimeout() { logMsg("statement::queryTimeout() - MySQL_Statement::setQueryTimeout"); int serverVersion= getMySQLVersion(con); int timeout= 2; if ( serverVersion < 57004 ) { SKIP("Server version >= 5.7.4 needed to run this test"); } stmt.reset(con->createStatement()); try { stmt->setQueryTimeout(timeout); ASSERT_EQUALS(timeout, stmt->getQueryTimeout()); time_t t1= time(NULL); stmt->execute("select sleep(5)"); time_t t2= time(NULL); ASSERT((t2 -t1) < 5); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } } /* namespace statement */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/statement.h000644 015771 000012 00000004364 12645244437 023543 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Example of a collection of tests * */ namespace testsuite { namespace classes { class statement : public unit_fixture { private: typedef unit_fixture super; /* * Helper method to check for forward only scrolling */ void checkUnbufferedScrolling(); protected: public: EXAMPLE_TEST_FIXTURE(statement) { TEST_CASE(anonymousSelect); TEST_CASE(getWarnings); TEST_CASE(clearWarnings); TEST_CASE(callSP); TEST_CASE(selectZero); TEST_CASE(unbufferedFetch); TEST_CASE(unbufferedOutOfSync); TEST_CASE(queryTimeout); } /** * SELECT ' ' as string */ void anonymousSelect(); /** * Calls getWarnings() */ void getWarnings(); /** * Calls clearWarnings() */ void clearWarnings(); /** * Calls a stored procedure */ void callSP(); /** * SELECT 0 as string */ void selectZero(); /** * Unbuffered fetch */ void unbufferedFetch(); /** * Unbuffered fetch - ouf of sync */ void unbufferedOutOfSync(); /** * check setQueryTimeout() and getQueryTimeout */ void queryTimeout(); }; REGISTER_FIXTURE(statement); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/uri.cpp000644 015771 000012 00000006621 12645244437 022667 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "uri.h" #include #include "driver/mysql_uri.h" namespace testsuite { namespace classes { /*Overriding setUp and tearDown */ void uri::setUp() { _uri.reset(new ::sql::mysql::MySQL_Uri()); } void uri::tearDown() { } void uri::tcp() { logMsg("uri::tcp()"); conn_string= "tcp://192.168.1.102:3306/t1"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT(tcpProtocol(*_uri)); ASSERT_EQUALS("192.168.1.102", _uri->Host()); ASSERT_EQUALS(3306, _uri->Port()); ASSERT_EQUALS("t1", _uri->Schema()); conn_string= "tcp://192.168.1.101:3307"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT(tcpProtocol(*_uri)); ASSERT_EQUALS("192.168.1.101", _uri->Host()); ASSERT_EQUALS(3307, _uri->Port()); ASSERT_EQUALS("", _uri->Schema()); conn_string= "192.168.1.102/t2"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT(tcpProtocol(*_uri)); ASSERT_EQUALS("192.168.1.102", _uri->Host()); ASSERT_EQUALS(3306, _uri->Port()); ASSERT_EQUALS("t2", _uri->Schema()); } void uri::tcpIpV6() { conn_string= "[2001:db8:0:f101::1]"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT_EQUALS(::sql::mysql::NativeAPI::PROTOCOL_TCP, _uri->Protocol()); ASSERT_EQUALS("2001:db8:0:f101::1", _uri->Host()); ASSERT_EQUALS(3306, _uri->Port()); ASSERT_EQUALS("", _uri->Schema()); conn_string= "tcp://[2001:db8:0:f101::2]:3307/test"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT_EQUALS(::sql::mysql::NativeAPI::PROTOCOL_TCP, _uri->Protocol()); ASSERT_EQUALS("2001:db8:0:f101::2", _uri->Host()); ASSERT_EQUALS(3307, _uri->Port()); ASSERT_EQUALS("test", _uri->Schema()); } void uri::socket() { conn_string= "unix:///tmp/mysql.socket"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT_EQUALS(::sql::mysql::NativeAPI::PROTOCOL_SOCKET, _uri->Protocol()); ASSERT_EQUALS("localhost", _uri->Host()); ASSERT_EQUALS("/tmp/mysql.socket", _uri->SocketOrPipe()); // We do not care about port in this case //ASSERT_EQUALS(0, _uri->Port()); } void uri::pipe() { conn_string= "pipe://MySQL"; ::sql::mysql::parseUri(conn_string, *_uri); ASSERT_EQUALS(::sql::mysql::NativeAPI::PROTOCOL_PIPE, _uri->Protocol()); ASSERT_EQUALS(".", _uri->Host()); ASSERT_EQUALS("MySQL", _uri->SocketOrPipe()); // We do not care about port in this case //ASSERT_EQUALS(0, _uri->Port()); } } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/uri.h000644 015771 000012 00000003541 12645244437 022332 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" namespace sql { namespace mysql { class MySQL_Uri; } } namespace testsuite { namespace classes { class uri: public unit_fixture { private: typedef unit_fixture super; boost::scoped_ptr< ::sql::mysql::MySQL_Uri> _uri; ::sql::SQLString conn_string; protected: public: /*Overriding setUp and tearDown */ void setUp(); void tearDown(); EXAMPLE_TEST_FIXTURE(uri) { TEST_CASE(tcp); TEST_CASE(tcpIpV6); TEST_CASE(socket); TEST_CASE(pipe); } /** * Test uri::tcp() * * */ void tcp(); /** * Test uri::tcpIpV6() * * */ void tcpIpV6(); /** * Test uri::socket() * * */ void socket(); /** * Test uri::pipe() * * */ void pipe(); }; REGISTER_FIXTURE(uri); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/variant.cpp000644 015771 000012 00000023435 12645244437 023536 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "variant.h" #include #include namespace testsuite { namespace classes { void variant::getValue() { logMsg("variant::getValue()"); sql::ConnectOptionsMap connection_properties; /* Test for integer variant values */ try { int val= 1234; connection_properties["first"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< int >()), 1234); val= 4567; connection_properties["second"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< int >()), 1234); ASSERT_EQUALS(*(connection_properties["second"].get< int >()), 4567); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); connection_properties.erase("second"); /* Test for bool variant values */ try { bool val= 1; connection_properties["first"]= val; ASSERT_EQUALS((bool)*(connection_properties["first"].get< bool >()), (bool)1); val= 0; connection_properties["second"]= val; ASSERT_EQUALS((bool)*(connection_properties["first"].get< bool >()), (bool)1); ASSERT_EQUALS((bool)*(connection_properties["second"].get< bool >()), (bool)0); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); connection_properties.erase("second"); /* Test for std::string variant values */ try { std::string val= "value1"; connection_properties["first"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< std::string >()), "value1"); val= "another_val"; connection_properties["second"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< std::string >()), "value1"); ASSERT_EQUALS(*(connection_properties["second"].get< std::string >()), "another_val"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); connection_properties.erase("second"); /* Test for sql::SQLString variant values */ try { sql::SQLString val= "value1"; connection_properties["first"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< sql::SQLString >()), "value1"); val= "another_val"; connection_properties["second"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< sql::SQLString >()), "value1"); ASSERT_EQUALS(*(connection_properties["second"].get< sql::SQLString >()), "another_val"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); connection_properties.erase("second"); /* Test for std::map< std::string, std::string > variant values */ try { std::string value1 ("value1"); std::string value2 ("value2"); std::map< std::string, std::string > connectAttrMap; connectAttrMap["key1"] = value1; connectAttrMap["key2"] = value2; connection_properties["first"]= connectAttrMap; ASSERT_EQUALS("value1", (*(connection_properties["first"].get< std::map < std::string, std::string > >()))["key1"]); ASSERT_EQUALS("value2", (*(connection_properties["first"].get< std::map < std::string, std::string > >()))["key2"]); value1 = "value3"; value2 = "value4"; connectAttrMap["key1"] = value1; connectAttrMap["key2"] = value2; connection_properties["second"]= connectAttrMap; ASSERT_EQUALS("value1", (*(connection_properties["first"].get< std::map < std::string, std::string > >()))["key1"]); ASSERT_EQUALS("value2", (*(connection_properties["first"].get< std::map < std::string, std::string > >()))["key2"]); ASSERT_EQUALS("value3", (*(connection_properties["second"].get< std::map < std::string, std::string > >()))["key1"]); ASSERT_EQUALS("value4", (*(connection_properties["second"].get< std::map < std::string, std::string > >()))["key2"]); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); connection_properties.erase("second"); /* Test for std::map< sql::SQLString, sql::SQLString > variant values */ try { sql::SQLString value1 ("value1"); sql::SQLString value2 ("value2"); std::map< sql::SQLString, sql::SQLString > connectAttrMap; connectAttrMap["key1"] = value1; connectAttrMap["key2"] = value2; connection_properties["first"]= connectAttrMap; ASSERT_EQUALS("value1", (*(connection_properties["first"].get< std::map < sql::SQLString, sql::SQLString > >()))["key1"]); ASSERT_EQUALS("value2", (*(connection_properties["first"].get< std::map < sql::SQLString, sql::SQLString > >()))["key2"]); value1 = "value3"; value2 = "value4"; connectAttrMap["key1"] = value1; connectAttrMap["key2"] = value2; connection_properties["second"]= connectAttrMap; ASSERT_EQUALS("value1", (*(connection_properties["first"].get< std::map < sql::SQLString, sql::SQLString > >()))["key1"]); ASSERT_EQUALS("value2", (*(connection_properties["first"].get< std::map < sql::SQLString, sql::SQLString > >()))["key2"]); ASSERT_EQUALS("value3", (*(connection_properties["second"].get< std::map < sql::SQLString, sql::SQLString > >()))["key1"]); ASSERT_EQUALS("value4", (*(connection_properties["second"].get< std::map < sql::SQLString, sql::SQLString > >()))["key2"]); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); connection_properties.erase("second"); } void variant::getUsingWrongStringType() { logMsg("variant::getValue()"); sql::ConnectOptionsMap connection_properties; /* Set std::string value and get sql::SQLString value */ try { std::string val= "value1"; connection_properties["first"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< sql::SQLString >()), "value1"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); /* Set sql::SQLString value and get using std::string value */ try { sql::SQLString val= "value1"; connection_properties["first"]= val; ASSERT_EQUALS(*(connection_properties["first"].get< std::string >()), "value1"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); /* Set std::map< std::string, std::string > value and get std::map < sql::SQLString, sql::SQLString > value */ try { std::string value1 ("value1"); std::string value2 ("value2"); std::map< std::string, std::string > connectAttrMap; connectAttrMap["key1"] = value1; connectAttrMap["key2"] = value2; connection_properties["first"]= connectAttrMap; ASSERT_EQUALS("value1", (*(connection_properties["first"].get< std::map < sql::SQLString, sql::SQLString > >()))["key1"]); ASSERT_EQUALS("value2", (*(connection_properties["first"].get< std::map < sql::SQLString, sql::SQLString > >()))["key2"]); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); /* Set std::map < sql::SQLString, sql::SQLString > value and get std::map< std::string, std::string > value */ try { sql::SQLString value1 ("value1"); sql::SQLString value2 ("value2"); std::map< sql::SQLString, sql::SQLString > connectAttrMap; connectAttrMap["key1"] = value1; connectAttrMap["key2"] = value2; connection_properties["first"]= connectAttrMap; ASSERT_EQUALS("value1", (*(connection_properties["first"].get< std::map < std::string, std::string > >()))["key1"]); ASSERT_EQUALS("value2", (*(connection_properties["first"].get< std::map < std::string, std::string > >()))["key2"]); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } connection_properties.erase("first"); } void variant::getUsingWrongDatatype() { logMsg("variant::getUsingWrongDatatype()"); sql::ConnectOptionsMap connection_properties; try { try { std::string user ("mysql_user"); connection_properties["user"]= user; const int *val= connection_properties["user"].get< int >(); FAIL("No exception II"); } catch (sql::InvalidArgumentException) { /* expected */ } } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/classes/variant.h000644 015771 000012 00000003256 12645244437 023202 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" namespace testsuite { namespace classes { class variant: public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(variant) { TEST_CASE(getValue); TEST_CASE(getUsingWrongStringType); TEST_CASE(getUsingWrongDatatype); } /** * Test variant::getValue() * * */ void getValue(); /** * Test variant::getWrongStringDatatype() * * */ void getUsingWrongStringType(); /** * Test variant::getUsingWrongDatatype() * * */ void getUsingWrongDatatype(); }; REGISTER_FIXTURE(variant); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/example/CMakeLists.txt000644 015771 000012 00000003326 12645244437 024121 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(example_sources ../unit_fixture.cpp ../main.cpp example.cpp) IF(WIN32) SET(example_sources ${example_sources} ../unit_fixture.h example.h) ENDIF(WIN32) ADD_EXECUTABLE(example ${example_sources}) SET_TARGET_PROPERTIES(example PROPERTIES OUTPUT_NAME "example" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(example ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) # # End of the instructions for building binary example from example.cpp|h # MESSAGE(STATUS "Configuring unit tests - examples") mysql-connector-c++-1.1.7/test/unit/example/example.cpp000644 015771 000012 00000016525 12645244437 023525 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "example.h" namespace testsuite { namespace example { void example_test_class::test_hello_world1() { logMsg("Hello world using framework magic"); try { /* By default the framework will establish a connection in setUp() and connect to the configured MySQL Server and select the configured schema. No other members will be initialized, however, there are several auto-ptr members which you can make use of: this->stmt, this->pstmt, this->res. The good thing about the auto-ptr members is that you don't need to care much about them. tearDown() will reset them and auto-ptr will ensure proper memory management. */ stmt.reset(con->createStatement()); /* Running a SELECT and storing the returned result set in this->res */ res.reset(stmt->executeQuery("SELECT 'Hello world!'")); /* Move result set cursor to first rowm, fetch result, write result to log */ res->next(); logMsg(res->getString(1)); } catch (sql::SQLException &e) { /* If anything goes wrong, write some info to the log... */ logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); /* ... and let the test fail. FAIL() is a macro. FAIL calls fail(const char* reason, const char* file, int line) */ fail(e.what(), __FILE__, __LINE__); } /* If all goes fine, there is no need to call PASS() or something. */ } void example_test_class::test_hello_world2() { logMsg("Hello world without framework magic"); try { /* Connection, Statement and ResultSet are typedefs from unit_fixture.h: typedef boost::scoped_ptr Connection; typedef boost::scoped_ptr PreparedStatement; typedef boost::scoped_ptr ParameterMetaData; typedef boost::scoped_ptr Statement; typedef boost::scoped_ptr Savepoint; typedef boost::scoped_ptr ResultSet; typedef sql::Driver Driver; typedef boost::scoped_ptr ResultSetMetaData; typedef boost::scoped_ptr DatabaseMetaData; Do yourself a favour and use boost::scoped_ptr in tests! */ Connection my_con(getConnection()); Statement my_stmt(my_con->createStatement()); /* The framework defines a couple of public members (from unit_fixture.h): Connection con; PreparedStatement pstmt; Statement stmt; ResultSet res; The members are managed in unit_fixture.cpp setUp() and tearDown(). You don't need to clean up them as long as setUp() and tearDown() are called and are not overwritten by your own method. However note, if you declare a local variable of the same type and name of any of the above members, for example ResultSet res, some compilers will spawn warnings that you are hiding members. */ res.reset(my_stmt->executeQuery("SELECT 'Hello world!' AS _world")); res->next(); logMsg(res->getString("_world")); res->close(); ResultSet res2(my_stmt->executeQuery("SELECT 'What a boring example' AS _complain")); res2->next(); logMsg(res2->getString("_complain")); res2->close(); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void example_test_class::test_assert_equals() { logMsg("ASSERT_EQUALS() macro demo"); /* Be careful: ASSERT_EQUALS() is not available for each and every type! You can find more details in test_asserts.h. */ int a=-1; ASSERT_EQUALS(a, a); unsigned int h=1; ASSERT_EQUALS(h, h); int64_t i=-10; ASSERT_EQUALS(i, i); uint64_t j=10; ASSERT_EQUALS(j, j); bool b=false; ASSERT_EQUALS(b, b); float c= -1.23f; ASSERT_EQUALS(c, c); double d=1.23; ASSERT_EQUALS(d, d); /* For fuzzy comparisons e.g. 1.01 vs. 1.01 fetched from MySQL */ double k = 1.01; double l = 1.0999992; fuzzyEquals(k, l, 0.001); long double e=1.23e12; ASSERT_EQUALS(e, e); const char f[]="foo"; ASSERT_EQUALS(f, f); std::string g("good idea"); ASSERT_EQUALS(g, g); } void example_test_class::test_assert_lessthan() { logMsg("ASSERT_LT() macro demo"); /* Be careful: ASSERT_LT(expected, value) is not available for each and every type! In fact at the time of writing its only available for int and unsigned int */ int a=1, b=2; ASSERT_LT(b, a); ASSERT_LT((unsigned int) b, (unsigned int) a); /* There is no "less or equal than", use LT instead. Example: 1 <= 2 */ ASSERT_LT(3, 1); } void example_test_class::test_assert_greaterthan() { logMsg("ASSERT_GT() macro demo"); /* Be careful: ASSERT_GT(expected, value) is not available for each and every type! In fact at the time of writing its only available for int and unsigned int */ int a=1, b=2; ASSERT_GT(a, b); ASSERT_GT((unsigned int) a, (unsigned int) b); /* There is no "greater or equal than", use GT instead. Example: 2 >= 1 */ ASSERT_GT(0, 2); } void example_test_class::test_assert_equals_fail() { logMsg("ASSERT_EQUALS failure - EXPECTED failure"); ASSERT_EQUALS(true, false); } void example_test_class::test_assert_message() { logMsg("ASSERT_MESSAGE example"); /* Wrapper of void assertTrue(const char * msg, bool expression , const char* file, int line); */ ASSERT_MESSAGE(1 < 2, "ASSERT_MESSAGE example (true)"); ASSERT_MESSAGE(1 > 2, "ASSERT_MESSAGE example (fail) - EXPECTED failure"); } void example_test_class::test_skip() { logMsg("SKIP() example"); /* Test if MySQL has a certain feature, e.g. if Procedures are supported */ if (true) SKIP("EXAMPLE: the server does not support stored procedures"); /* If MySQL does not suppoer feature xyz, call SKIP() and test execution ends. You get here only if you feature is available */ logMsg("Feature is available, use it."); } void example_test_class::test_todo() { logMsg("TODO() example"); /* Test if MySQL has a certain feature, e.g. if Procedures are supported */ TODO("If you know that a test mail fail and you intentionally want to let it fail temporarily, for example, as long as a bug has not been fixed, mark it as TODO"); //FAIL("Expected failure, known failure - its on your TODO"); } } /* namespace example */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/example/example.h000644 015771 000012 00000010431 12645244437 023160 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Example of a collection of tests * */ namespace testsuite { namespace example { class example_test_class : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(example_test_class) { TEST_CASE(test_hello_world1); TEST_CASE(test_hello_world2); TEST_CASE(test_assert_equals); TEST_CASE(test_assert_equals_fail); TEST_CASE(test_assert_message); TEST_CASE(test_assert_lessthan); TEST_CASE(test_assert_greaterthan); TEST_CASE(test_skip); TEST_CASE(test_todo); } /** * SELECT 'Hello world' example using framework magic * * Runs SELECT 'Hello world!' using the Connection and Statement * object that has been implicitly created by setUp() before calling the test. * * The unit_fixture class defines a coupld of useful members for you: * - Connection * - Statement * - PreparedStatement * - ResultSet * * The Connection object is the only one which is initialized and ready for * use. All other objects are in an undefined state. All members are defined * as auto-ptr, meaning, you don't need to worry about cleaning up them. */ void test_hello_world1(); /** * SELECT 'Hello world' example without framework magic * * The same as test1() but with less framework magic and, for example, * manual connect using the framework method getConnection() */ void test_hello_world2(); /** * Demo of ASSERT_EQUALS macro * * ASSERT_EQUALS macro can handle the following types: * - int * - bool * - double * - float * - long double * - char* * * ASSERT_EQUALS is a wrapper for: * void assertEquals( expected, result, const char* file, int line); */ void test_assert_equals(); /** * Demo of a failing ASSERT_EQUALS */ void test_assert_equals_fail(); /** * Demo of ASSERT_MESSAGE */ void test_assert_message(); /** * Demo of ASSERT_LT * * At the time of writing ASSERT_LT is only defined for int and unsigned int * comparisons. This has the nice side effect that you can rewrite * "less or equal than" conditions as "less than" conditions. */ void test_assert_lessthan(); /** * Demo of ASSERT_GT * * At the time of writing ASSERT_GT is only defined for int and unsigned int * comparisons. This has the nice side effect that you can rewrite * "greater or equal than" conditions as "greater than" conditions. */ void test_assert_greaterthan(); /** * Demo of SKIP() * * If a test requires a certain MySQL feature only available with MySQL version x.y.z * you should test if MySQL can give you what you need. If it can't SKIP the test. * SKIP will stop test execution. */ void test_skip(); /** * Demo of TODO() * * If you know that a certain test will fail, for example, because its a regression * test for an open bug report, you should mark the test as a TODO. Whoever runs the * test will be able to see that you are working on the bug and the test failure * is expected and does not need to be escalated in any way. */ void test_todo(); }; REGISTER_FIXTURE(example_test_class); } /* namespace example */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/main.cpp000644 015771 000012 00000004326 12645244437 021357 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../framework/test_runner.h" #include "../framework/start_options.h" #include "../framework/test_tapOutputter.h" #include "../framework/test_filter.h" #include int main(int argc, char** argv) { const String::value_type * unnamedStartParams[]={"dbUrl" , "dbUser" , "dbPasswd" , "dbSchema" , NULL}; Properties defaultStringValues; defaultStringValues.insert(Properties::value_type("dbUrl", "tcp://127.0.0.1:3306")); defaultStringValues.insert(Properties::value_type("dbUser", "root")); defaultStringValues.insert(Properties::value_type("dbPasswd", "root")); defaultStringValues.insert(Properties::value_type("dbSchema", "test")); std::map defaultBoolValues; testsuite::StartOptions options(unnamedStartParams, & defaultStringValues , & defaultBoolValues); options.parseParams(argc, argv); testsuite::FiltersSuperposition filter(options.getString("filter")); testsuite::TestsRunner & testsRunner=testsuite::TestsRunner::theInstance(); testsRunner.setStartOptions(& options); testsRunner.setTestsFilter(filter); return testsRunner.runTests() ? EXIT_SUCCESS : EXIT_FAILURE; } mysql-connector-c++-1.1.7/test/unit/performance/CMakeLists.txt000644 015771 000012 00000003325 12645244437 024766 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(perf_statement_sources ../unit_fixture.cpp ../main.cpp perf_statement.cpp) IF(WIN32) SET(perf_statement_sources ${perf_statement_sources} ../unit_fixture.h perf_statement.h) ENDIF(WIN32) ADD_EXECUTABLE(perf_statement ${perf_statement_sources}) SET_TARGET_PROPERTIES(perf_statement PROPERTIES OUTPUT_NAME "perf_statement" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(perf_statement ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring performance test - statement") mysql-connector-c++-1.1.7/test/unit/performance/perf_statement.cpp000644 015771 000012 00000014401 12645244437 025747 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "perf_statement.h" #include namespace testsuite { namespace performance { void perf_statement::simpleSelect1k() { logMsg("perf_statement::simpleSelect1k() - MySQL_Statement::*, MYSQL_Resultset::*"); String varchar(""); std::stringstream query; int i; stmt.reset(con->createStatement()); try { TIMER_START("SELECT 1k FROM DUAL - statement"); for (i=0; i < 50000; ++i) { res.reset(stmt->executeQuery("SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' FROM DUAL")); while (res->next()) { varchar=res->getString(1); varchar=res->getString(2); varchar=res->getString(3); varchar=res->getString(4); } } TIMER_STOP("SELECT 1k FROM DUAL - statement"); // Same - not buffered stmt->setResultSetType( sql::ResultSet::TYPE_FORWARD_ONLY ); TIMER_START("SELECT 1k FROM DUAL - statement fw only"); for (i=0; i < 50000; ++i) { res.reset(stmt->executeQuery("SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' FROM DUAL")); while (res->next()) { varchar=res->getString(1); varchar=res->getString(2); varchar=res->getString(3); varchar=res->getString(4); } } TIMER_STOP("SELECT 1k FROM DUAL - statement fw only"); // Same with prepare statements pstmt.reset( con->prepareStatement( "SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' FROM DUAL" ) ); TIMER_START("SELECT 1k FROM DUAL - prepared statement"); for (i=0; i < 50000; ++i) { res.reset(pstmt->executeQuery()); while (res->next()) { varchar=res->getString(1); varchar=res->getString(2); varchar=res->getString(3); varchar=res->getString(4); } } TIMER_STOP("SELECT 1k FROM DUAL - prepared statement"); } catch (sql::SQLException &e) { logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); fail(e.what(), __FILE__, __LINE__); } } void perf_statement::setUp() { super::setUp(); realFrameworkTiming= TestsListener::doTiming(); } void perf_statement::tearDown() { TestsListener::doTiming( realFrameworkTiming ); super::tearDown(); } } /* namespace perf_statement */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/performance/perf_statement.h000644 015771 000012 00000003103 12645244437 025411 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Example of a collection of tests * */ namespace testsuite { namespace performance { class perf_statement : public unit_fixture { private: typedef unit_fixture super; bool realFrameworkTiming; protected: public: EXAMPLE_TEST_FIXTURE(perf_statement) { TEST_CASE(simpleSelect1k); } /** * SELECT ' ' as string */ void simpleSelect1k(); void setUp(); void tearDown(); }; REGISTER_FIXTURE(perf_statement); } /* namespace classes */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/template_bug_group/CMakeLists.txt000644 015771 000012 00000004424 12645244437 026352 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(bug123_sources ../unit_fixture.cpp ../main.cpp bug123.cpp) IF(WIN32) SET(bug123_sources ${bug123_sources} ../unit_fixture.h bug123.h) ENDIF(WIN32) ADD_EXECUTABLE(bug123 ${bug123_sources}) SET_TARGET_PROPERTIES(bug123 PROPERTIES OUTPUT_NAME "bug123" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(bug123 ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) # # End of the instructions for building binary bug123 from bug123.cpp|h # # # Instructions for compiling bug456.cpp|h into the binary bug456 # SET(bug456_sources ../unit_fixture.cpp ../main.cpp bug456.cpp) IF(WIN32) SET(bug456_sources ${bug456_sources} ../unit_fixture.h bug456.h) ENDIF(WIN32) ADD_EXECUTABLE(bug456 ${bug456_sources}) SET_TARGET_PROPERTIES(bug456 PROPERTIES OUTPUT_NAME "bug456" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV} ${MYSQL_LINK_FLAGS}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV}") TARGET_LINK_LIBRARIES(bug456 ${MY_TARGET_LINK_LIBRARIES} ${MY_GCOV_LINK_LIBRARIES}) MESSAGE(STATUS "Configuring unit tests - group template_bug") mysql-connector-c++-1.1.7/test/unit/template_bug_group/bug123.cpp000644 015771 000012 00000005010 12645244437 025311 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "bug123.h" namespace testsuite { namespace regression { void template_bug123_class::template_bug123_method() { logMsg("Regression test for #[TODO - add bug numer]"); try { /* By default the framework will establish a connection in setUp() and connect to the configured MySQL Server and select the configured schema. No other members will be initialized, however, there are several auto-ptr members which you can make use of: this->stmt, this->pstmt, this->res. The good thing about the auto-ptr members is that you don't need to care much about them. tearDown() will reset them and auto-ptr will ensure proper memory management. */ stmt.reset(con->createStatement()); /* Running a SELECT and storing the returned result set in this->res */ res.reset(stmt->executeQuery("SELECT 'Hello world!'")); /* Move result set cursor to first rowm, fetch result, write result to log */ res->next(); logMsg(res->getString(1)); } catch (sql::SQLException &e) { /* If anything goes wrong, write some info to the log... */ logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); /* ... and let the test fail. FAIL() is a macro. FAIL calls fail(const char* reason, const char* file, int line) */ fail(e.what(), __FILE__, __LINE__); } /* If all goes fine, there is no need to call PASS() or something. */ } } /* namespace regression */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/template_bug_group/bug123.h000644 015771 000012 00000003170 12645244437 024763 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Test for Bug [TODO - add bug number] * */ namespace testsuite { namespace regression { class template_bug123_class : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(template_bug123_class) { TEST_CASE(template_bug123_method); } /** * http://bugs.mysql.com/[TODO - add bug number] * * [TODO - any longer description may go here] */ void template_bug123_method(); }; REGISTER_FIXTURE(template_bug123_class); } /* namespace regression */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/template_bug_group/bug456.cpp000644 015771 000012 00000005010 12645244437 025322 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "bug456.h" namespace testsuite { namespace regression { void template_bug456_class::template_bug456_method() { logMsg("Regression test for #[TODO - add bug numer]"); try { /* By default the framework will establish a connection in setUp() and connect to the configured MySQL Server and select the configured schema. No other members will be initialized, however, there are several auto-ptr members which you can make use of: this->stmt, this->pstmt, this->res. The good thing about the auto-ptr members is that you don't need to care much about them. tearDown() will reset them and auto-ptr will ensure proper memory management. */ stmt.reset(con->createStatement()); /* Running a SELECT and storing the returned result set in this->res */ res.reset(stmt->executeQuery("SELECT 'Hello world!'")); /* Move result set cursor to first rowm, fetch result, write result to log */ res->next(); logMsg(res->getString(1)); } catch (sql::SQLException &e) { /* If anything goes wrong, write some info to the log... */ logErr(e.what()); logErr("SQLState: " + std::string(e.getSQLState())); /* ... and let the test fail. FAIL() is a macro. FAIL calls fail(const char* reason, const char* file, int line) */ fail(e.what(), __FILE__, __LINE__); } /* If all goes fine, there is no need to call PASS() or something. */ } } /* namespace regression */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/template_bug_group/bug456.h000644 015771 000012 00000003170 12645244437 024774 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../unit_fixture.h" /** * Test for Bug [TODO - add bug number] * */ namespace testsuite { namespace regression { class template_bug456_class : public unit_fixture { private: typedef unit_fixture super; protected: public: EXAMPLE_TEST_FIXTURE(template_bug456_class) { TEST_CASE(template_bug456_method); } /** * http://bugs.mysql.com/[TODO - add bug number] * * [TODO - any longer description may go here] */ void template_bug456_method(); }; REGISTER_FIXTURE(template_bug456_class); } /* namespace regression */ } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/unit_fixture.cpp000644 015771 000012 00000104546 12645244437 023165 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "unit_fixture.h" #include #ifndef L64 #ifdef _WIN32 #define L64(x) x##i64 #else #define L64(x) x##LL #endif #endif namespace testsuite { Driver * unit_fixture::driver=NULL; unit_fixture::unit_fixture(const String & name) : super(name), con(NULL), pstmt(NULL), stmt(NULL), res(NULL) { init(); } void unit_fixture::init() { url=TestsRunner::theInstance().getStartOptions()->getString("dbUrl"); user=TestsRunner::theInstance().getStartOptions()->getString("dbUser"); passwd=TestsRunner::theInstance().getStartOptions()->getString("dbPasswd"); db=TestsRunner::theInstance().getStartOptions()->getString("dbSchema"); columns.push_back(columndefinition("BIT", "BIT", sql::DataType::BIT, "0", false, 1, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("BIT", "BIT NOT NULL", sql::DataType::BIT, "1", false, 1, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("BIT", "BIT(5) NOT NULL", sql::DataType::BIT, "0", false, 5, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("BIT", "BIT(8)", sql::DataType::BIT, "0", false, 8, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("TINYINT", "TINYINT", sql::DataType::TINYINT, "127", true, 3, 0, true, "", 0, "NO", false, "127")); columns.push_back(columndefinition("TINYINT", "TINYINT NOT NULL", sql::DataType::TINYINT, "127", true, 3, 0, false, "", 0, "NO", false, "127")); columns.push_back(columndefinition("TINYINT", "TINYINT NOT NULL DEFAULT -1", sql::DataType::TINYINT, "12", true, 3, 0, false, "-1", 0, "NO", false, "12")); columns.push_back(columndefinition("TINYINT", "TINYINT(1)", sql::DataType::TINYINT, "3", true, 3, 0, true, "", 0, "NO", false, "3")); columns.push_back(columndefinition("TINYINT UNSIGNED", "TINYINT UNSIGNED", sql::DataType::TINYINT, "255", false, 3, 0, true, "", 0, "NO", false, "255")); columns.push_back(columndefinition("TINYINT UNSIGNED ZEROFILL", "TINYINT ZEROFILL", sql::DataType::TINYINT, "1", false, 3, 0, true, "", 0, "NO", false)); // Alias of BOOLEAN columns.push_back(columndefinition("TINYINT", "BOOLEAN", sql::DataType::TINYINT, "1", true, 3, 0, true, "", 0, "NO", false, "1")); columns.push_back(columndefinition("TINYINT", "BOOLEAN NOT NULL", sql::DataType::TINYINT, "2", true, 3, 0, false, "", 0, "NO", false, "2")); columns.push_back(columndefinition("TINYINT", "BOOLEAN DEFAULT 0", sql::DataType::TINYINT, "3", true, 3, 0, true, "0", 0, "NO", false, "3")); columns.push_back(columndefinition("SMALLINT", "SMALLINT", sql::DataType::SMALLINT, "-32768", true, 5, 0, true, "", 0, "NO", true, "-32768")); columns.push_back(columndefinition("SMALLINT", "SMALLINT NOT NULL", sql::DataType::SMALLINT, "32767", true, 5, 0, false, "", 0, "NO", false, "32767")); columns.push_back(columndefinition("SMALLINT", "SMALLINT NOT NULL DEFAULT -1", sql::DataType::SMALLINT, "-32768", true, 5, 0, false, "-1", 0, "NO", false)); columns.push_back(columndefinition("SMALLINT", "SMALLINT(3)", sql::DataType::SMALLINT, "-32768", true, 5, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("SMALLINT UNSIGNED", "SMALLINT UNSIGNED", sql::DataType::SMALLINT, "65535", false, 5, 0, true, "", 0, "NO", false, "65535")); columns.push_back(columndefinition("SMALLINT UNSIGNED ZEROFILL", "SMALLINT ZEROFILL", sql::DataType::SMALLINT, "123", false, 5, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("SMALLINT UNSIGNED ZEROFILL", "SMALLINT UNSIGNED ZEROFILL DEFAULT 101", sql::DataType::SMALLINT, "123", false, 5, 0, true, "00101", 0, "NO", false)); columns.push_back(columndefinition("MEDIUMINT", "MEDIUMINT", sql::DataType::MEDIUMINT, "-8388608", true, 7, 0, true, "", 0, "NO", true, "-8388608")); columns.push_back(columndefinition("MEDIUMINT", "MEDIUMINT NOT NULL", sql::DataType::MEDIUMINT, "-8388608", true, 7, 0, false, "", 0, "NO", true)); columns.push_back(columndefinition("MEDIUMINT", "MEDIUMINT(1)", sql::DataType::MEDIUMINT, "2", true, 7, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("MEDIUMINT", "MEDIUMINT(2) DEFAULT 12", sql::DataType::MEDIUMINT, "2", true, 7, 0, true, "12", 0, "NO", true)); columns.push_back(columndefinition("MEDIUMINT UNSIGNED", "MEDIUMINT UNSIGNED", sql::DataType::MEDIUMINT, "16777215", false, 7, 0, true, "", 0, "NO", false, "16777215")); columns.push_back(columndefinition("MEDIUMINT UNSIGNED ZEROFILL", "MEDIUMINT UNSIGNED ZEROFILL", sql::DataType::MEDIUMINT, "1677721", false, 7, 0, true, "", 0, "NO", false)); // Alias of INTEGER columns.push_back(columndefinition("INT", "INTEGER", sql::DataType::INTEGER, "2147483647", true, 10, 0, true, "", 0, "NO", false, "2147483647")); columns.push_back(columndefinition("INT", "INTEGER NOT NULL", sql::DataType::INTEGER, "2147483647", true, 10, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("INT", "INTEGER(1)", sql::DataType::INTEGER, "3", true, 10, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("INT UNSIGNED", "INT UNSIGNED", sql::DataType::INTEGER, "4294967295", false, 10, 0, true, "", 0, "NO", false, "4294967295")); // If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column. columns.push_back(columndefinition("INT UNSIGNED ZEROFILL", "INT(4) SIGNED ZEROFILL", sql::DataType::INTEGER, "1", false, 10, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("INT", "INT(4) SIGNED DEFAULT -123", sql::DataType::INTEGER, "1", true, 10, 0, true, "-123", 0, "NO", false)); columns.push_back(columndefinition("BIGINT", "BIGINT", sql::DataType::BIGINT, "-9223372036854775808", true, 19, 0, true, "", 0, "NO", true, "-9223372036854775808")); columns.push_back(columndefinition("BIGINT", "BIGINT NOT NULL", sql::DataType::BIGINT, "-9223372036854775808", true, 19, 0, false, "", 0, "NO", true)); columns.push_back(columndefinition("BIGINT UNSIGNED", "BIGINT UNSIGNED", sql::DataType::BIGINT, "18446744073709551615", false, 20, 0, true, "", 0, "NO", false, "18446744073709551615")); columns.push_back(columndefinition("BIGINT UNSIGNED", "BIGINT UNSIGNED", sql::DataType::BIGINT, "18446744073709551615", false, 20, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("BIGINT UNSIGNED ZEROFILL", "BIGINT(4) ZEROFILL DEFAULT 10101", sql::DataType::BIGINT, "2", false, 20, 0, true, "10101", 0, "NO", false)); columns.push_back(columndefinition("FLOAT", "FLOAT", sql::DataType::REAL, "-1.01", true, 12, 0, true, "", 0, "NO", true)); columns.push_back(columndefinition("FLOAT", "FLOAT NOT NULL", sql::DataType::REAL, "-1.01", true, 12, 0, false, "", 0, "NO", true)); columns.push_back(columndefinition("FLOAT UNSIGNED", "FLOAT UNSIGNED", sql::DataType::REAL, "1.01", false, 12, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("FLOAT UNSIGNED ZEROFILL", "FLOAT(5,3) UNSIGNED ZEROFILL", sql::DataType::REAL, "1.01", false, 5, 3, true, "", 0, "NO", false)); columns.push_back(columndefinition("FLOAT", "FLOAT(6)", sql::DataType::REAL, "1.01", true, 12, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("FLOAT", "FLOAT(9) DEFAULT 1.01", sql::DataType::REAL, "1.01", true, 12, 0, true, "1.01", 0, "NO", false)); columns.push_back(columndefinition("DOUBLE", "DOUBLE", sql::DataType::DOUBLE, "-1.01", true, 22, 0, true, "", 0, "NO", true)); columns.push_back(columndefinition("DOUBLE", "DOUBLE NOT NULL", sql::DataType::DOUBLE, "-1.01", true, 22, 0, false, "", 0, "NO", true)); columns.push_back(columndefinition("DOUBLE UNSIGNED", "DOUBLE UNSIGNED", sql::DataType::DOUBLE, "1.01", false, 22, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("DOUBLE UNSIGNED", "DOUBLE UNSIGNED DEFAULT 1.123", sql::DataType::DOUBLE, "1.01", false, 22, 0, true, "1.123", 0, "NO", true)); columns.push_back(columndefinition("DOUBLE UNSIGNED ZEROFILL", "DOUBLE(5,3) UNSIGNED ZEROFILL", sql::DataType::DOUBLE, "1.01", false, 5, 3, true, "", 0, "NO", true)); columns.push_back(columndefinition("DECIMAL", "DECIMAL", sql::DataType::DECIMAL, "-1.01", true, 10, 0, true, "", 0, "NO", true)); columns.push_back(columndefinition("DECIMAL", "DECIMAL NOT NULL", sql::DataType::DECIMAL, "-1.01", true, 10, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("DECIMAL UNSIGNED", "DECIMAL UNSIGNED", sql::DataType::DECIMAL, "1.01", false, 10, 0, true, "", 0, "NO", true)); columns.push_back(columndefinition("DECIMAL UNSIGNED ZEROFILL", "DECIMAL(5,3) UNSIGNED ZEROFILL", sql::DataType::DECIMAL, "1.01", false, 5, 3, true, "", 0, "NO", false)); columns.push_back(columndefinition("DECIMAL UNSIGNED ZEROFILL", "DECIMAL(6,3) UNSIGNED ZEROFILL DEFAULT 34.56", sql::DataType::DECIMAL, "1.01", false, 6, 3, true, "034.560", 0, "NO", false)); columns.push_back(columndefinition("DATE", "DATE", sql::DataType::DATE, "2009-02-09", true, 10, 0, true, "", 0, "NO", false, "2009-02-09")); columns.push_back(columndefinition("DATE", "DATE NOT NULL", sql::DataType::DATE, "2009-02-12", true, 10, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("DATE", "DATE NOT NULL DEFAULT '2009-02-16'", sql::DataType::DATE, "2009-02-12", true, 10, 0, false, "2009-02-16", 0, "NO", false)); columns.push_back(columndefinition("DATETIME", "DATETIME", sql::DataType::TIMESTAMP, "2009-02-09 20:05:43", true, 19, 0, true, "", 0, "NO", false, "2009-02-09 20:05:43")); columns.push_back(columndefinition("DATETIME", "DATETIME NOT NULL", sql::DataType::TIMESTAMP, "2009-02-12 17:49:21", true, 19, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("DATETIME", "DATETIME NOT NULL DEFAULT '2009-02-12 21:36:54'", sql::DataType::TIMESTAMP, "2009-02-12 17:49:21", true, 19, 0, false, "2009-02-12 21:36:54", 0, "NO", false)); // TODO this might be server dependent! columns.push_back(columndefinition("TIMESTAMP", "TIMESTAMP", sql::DataType::TIMESTAMP, "2038-01-09 03:14:07", false, 19, 0, false, "0000-00-00 00:00:00", 0, "NO", false)); columns.push_back(columndefinition("TIME", "TIME", sql::DataType::TIME, "-838:59:59", true, 8, 0, true, "", 0, "NO", true)); columns.push_back(columndefinition("TIME", "TIME NOT NULL", sql::DataType::TIME, "838:59:59", true, 8, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("TIME", "TIME DEFAULT '12:39:41'", sql::DataType::TIME, "-838:59:59", true, 8, 0, true, "12:39:41", 0, "NO", true)); columns.push_back(columndefinition("YEAR", "YEAR", sql::DataType::YEAR, "1901", false, 4, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("YEAR", "YEAR NOT NULL", sql::DataType::YEAR, "1902", false, 4, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("YEAR", "YEAR(4)", sql::DataType::YEAR, "2009", false, 4, 0, true, "", 0, "NO", false, "2009")); columns.push_back(columndefinition("YEAR", "YEAR(2)", sql::DataType::YEAR, "1", false, 4, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("YEAR", "YEAR(3) DEFAULT '2009'", sql::DataType::YEAR, "1", false, 4, 0, true, "2009", 0, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR", sql::DataType::CHAR, "a", true, 1, 0, true, "", 0, "NO", false, "a")); columns.push_back(columndefinition("CHAR", "CHAR NOT NULL", sql::DataType::CHAR, "a", true, 1, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(255)", sql::DataType::CHAR, "abc", true, 255, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("BINARY", "CHAR(255) CHARACTER SET binary", sql::DataType::BINARY, "abc", true, 255, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(254) NOT NULL", sql::DataType::CHAR, "abc", true, 254, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(254) NOT NULL DEFAULT 'abc'", sql::DataType::CHAR, "abc", true, 254, 0, false, "abc", 0, "NO", false)); // 3byte columns.push_back(columndefinition("CHAR", "NATIONAL CHAR(255)", sql::DataType::CHAR, "abc", true, 255, 0, true, "", 765, "NO", false)); columns.push_back(columndefinition("CHAR", "NATIONAL CHAR(215) NOT NULL", sql::DataType::CHAR, "abc", true, 215, 0, false, "", 645, "NO", false)); columns.push_back(columndefinition("CHAR", "NATIONAL CHAR(215) NOT NULL DEFAULT 'Ulf'", sql::DataType::CHAR, "abc", true, 215, 0, false, "Ulf", 645, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(255) CHARACTER SET 'utf8'", sql::DataType::CHAR, "abc", true, 255, 0, true, "", 765, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(55) CHARACTER SET 'utf8' NOT NULL ", sql::DataType::CHAR, "abc", true, 55, 0, false, "", 165, "NO", false)); // TODO this might be server dependent! columns.push_back(columndefinition("CHAR", "CHAR(250) CHARACTER SET 'utf8' COLLATE 'utf8_bin'", sql::DataType::CHAR, "abc", true, 250, 0, true, "", 750, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(250) CHARACTER SET 'utf8' COLLATE 'utf8_bin' DEFAULT 'Wendel'", sql::DataType::CHAR, "abc", true, 250, 0, true, "Wendel", 750, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(43) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL", sql::DataType::CHAR, "abc", true, 43, 0, false, "", 129, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(123) CHARACTER SET 'ucs2'", sql::DataType::CHAR, "abc", true, 123, 0, true, "", 246, "NO", false)); // The CHAR BYTE data type is an alias for the BINARY data type. This is a compatibility feature. columns.push_back(columndefinition("BINARY", "CHAR(255) BYTE", sql::DataType::BINARY, "abc", true, 255, 0, true, "", 255, "NO", false)); columns.push_back(columndefinition("BINARY", "CHAR(12) BYTE NOT NULL", sql::DataType::BINARY, "abc", true, 12, 0, false, "", 12, "NO", false)); columns.push_back(columndefinition("CHAR", "CHAR(14) DEFAULT 'Andrey'", sql::DataType::CHAR, "abc", true, 14, 0, true, "Andrey", 0, "NO", false)); columns.push_back(columndefinition("BINARY", "CHAR(25) CHARACTER SET 'binary'", sql::DataType::BINARY, "abc", true, 25, 0, true, "", 25, "NO", false)); columns.push_back(columndefinition("VARCHAR", "VARCHAR(10)", sql::DataType::VARCHAR, "a", true, 10, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("VARBINARY", "VARCHAR(10) CHARACTER SET binary", sql::DataType::VARBINARY, "a", true, 10, 0, true, "", 0, "NO", false)); columns.push_back(columndefinition("VARCHAR", "VARCHAR(7) NOT NULL", sql::DataType::VARCHAR, "a", true, 7, 0, false, "", 0, "NO", false)); columns.push_back(columndefinition("VARCHAR", "VARCHAR(255) DEFAULT 'Good night twitter. BTW, go MySQL!'", sql::DataType::VARCHAR, "a", true, 255, 0, true, "Good night twitter. BTW, go MySQL!", 0, "NO", false)); columns.push_back(columndefinition("VARCHAR", "VARCHAR(11) CHARACTER SET 'utf8'", sql::DataType::VARCHAR, "a", true, 11, 0, true, "", 33, "NO", false)); columns.push_back(columndefinition("VARCHAR", "VARCHAR(11) CHARACTER SET 'ascii' DEFAULT 'Hristov'", sql::DataType::VARCHAR, "a", true, 11, 0, true, "Hristov", 11, "NO", false)); columns.push_back(columndefinition("VARCHAR", "VARCHAR(12) CHARACTER SET 'utf8' COLLATE 'utf8_bin'", sql::DataType::VARCHAR, "a", true, 12, 0, true, "", 36, "NO", false)); columns.push_back(columndefinition("VARBINARY", "VARCHAR(13) BYTE", sql::DataType::VARBINARY, "a", true, 13, 0, true, "", 13, "NO", false)); columns.push_back(columndefinition("VARBINARY", "VARCHAR(14) BYTE NOT NULL", sql::DataType::VARBINARY, "a", true, 14, 0, false, "", 14, "NO", false)); columns.push_back(columndefinition("BINARY", "BINARY(1)", sql::DataType::BINARY, "a", true, 1, 0, true, "", 1, "NO", false)); columns.push_back(columndefinition("VARBINARY", "VARBINARY(1)", sql::DataType::VARBINARY, "a", true, 1, 0, true, "", 1, "NO", false)); columns.push_back(columndefinition("VARBINARY", "VARBINARY(2) NOT NULL", sql::DataType::VARBINARY, "a", true, 2, 0, false, "", 2, "NO", false)); columns.push_back(columndefinition("VARBINARY", "VARBINARY(20) NOT NULL DEFAULT 'Lawrin'", sql::DataType::VARBINARY, "a", true, 20, 0, false, "Lawrin", 20, "NO", false)); columns.push_back(columndefinition("TINYBLOB", "TINYBLOB", sql::DataType::VARBINARY, "a", true, 255, 0, true, "", 255, "NO", false)); columns.push_back(columndefinition("TINYTEXT", "TINYTEXT", sql::DataType::VARCHAR, "a", true, 255, 0, true, "", 255, "NO", false, "a")); columns.push_back(columndefinition("TINYTEXT", "TINYTEXT NOT NULL", sql::DataType::VARCHAR, "a", true, 255, 0, false, "", 255, "NO", false)); columns.push_back(columndefinition("TINYTEXT", "TINYTEXT", sql::DataType::VARCHAR, "a", true, 255, 0, true, "", 255, "NO", false)); columns.push_back(columndefinition("TINYBLOB", "TINYTEXT CHARACTER SET binary", sql::DataType::VARBINARY, "a", true, 255, 0, true, "", 255, "NO", false)); columns.push_back(columndefinition("TINYTEXT", "TINYTEXT CHARACTER SET 'utf8'", sql::DataType::VARCHAR, "a", true, 255, 0, true, "", 255, "NO", false)); columns.push_back(columndefinition("TINYTEXT", "TINYTEXT CHARACTER SET 'utf8' COLLATE 'utf8_bin'", sql::DataType::VARCHAR, "a", true, 255, 0, true, "", 255, "NO", false)); columns.push_back(columndefinition("BLOB", "BLOB", sql::DataType::LONGVARBINARY, "a", true, 65535, 0, true, "", 65536, "NO", false)); columns.push_back(columndefinition("BLOB", "BLOB NOT NULL", sql::DataType::LONGVARBINARY, "a", true, 65535, 0, false, "", 65535, "NO", false)); columns.push_back(columndefinition("TEXT", "TEXT", sql::DataType::LONGVARCHAR, "a", true, 65535, 0, true, "", 65536, "NO", false)); columns.push_back(columndefinition("TEXT", "TEXT NOT NULL", sql::DataType::LONGVARCHAR, "a", true, 65535, 0, false, "", 65535, "NO", false)); columns.push_back(columndefinition("MEDIUMBLOB", "MEDIUMBLOB", sql::DataType::LONGVARBINARY, "a", true, 16777215, 0, true, "", 16777215, "NO", false)); columns.push_back(columndefinition("MEDIUMBLOB", "MEDIUMBLOB NOT NULL", sql::DataType::LONGVARBINARY, "a", true, 16777215, 0, false, "", 16777215, "NO", false)); columns.push_back(columndefinition("MEDIUMTEXT", "MEDIUMTEXT", sql::DataType::LONGVARCHAR, "a", true, 16777215, 0, true, "", 16777215, "NO", false)); columns.push_back(columndefinition("MEDIUMBLOB", "MEDIUMTEXT CHARACTER SET binary", sql::DataType::LONGVARBINARY, "a", true, 16777215, 0, true, "", 16777215, "NO", false)); columns.push_back(columndefinition("MEDIUMTEXT", "MEDIUMTEXT NOT NULL", sql::DataType::LONGVARCHAR, "a", true, 16777215, 0, false, "", 16777215, "NO", false)); columns.push_back(columndefinition("MEDIUMTEXT", "MEDIUMTEXT CHARSET 'utf8'", sql::DataType::LONGVARCHAR, "a", true, 16777215, 0, true, "", 16777215, "NO", false)); columns.push_back(columndefinition("MEDIUMTEXT", "MEDIUMTEXT CHARSET 'utf8' COLLATE 'utf8_bin'", sql::DataType::LONGVARCHAR, "a", true, 16777215, 0, true, "", 16777215, "NO", false)); columns.push_back(columndefinition("LONGBLOB", "LONGBLOB", sql::DataType::LONGVARBINARY, "a", true, L64(4294967295), 0, true, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("LONGBLOB", "LONGBLOB NOT NULL", sql::DataType::LONGVARBINARY, "a", true, L64(4294967295), 0, false, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("LONGTEXT", "LONGTEXT", sql::DataType::LONGVARCHAR, "a", true, L64(4294967295), 0, true, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("LONGBLOB", "LONGTEXT CHARACTER SET binary", sql::DataType::LONGVARBINARY, "a", true, L64(4294967295), 0, true, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("LONGTEXT", "LONGTEXT NOT NULL", sql::DataType::LONGVARCHAR, "a", true, L64(4294967295), 0, false, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("LONGTEXT", "LONGTEXT CHARSET 'utf8'", sql::DataType::LONGVARCHAR, "a", true, L64(4294967295), 0, true, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("LONGTEXT", "LONGTEXT CHARSET 'utf8' COLLATE 'utf8_bin'", sql::DataType::LONGVARCHAR, "a", true, L64(4294967295), 0, true, "", L64(4294967295), "NO", false)); columns.push_back(columndefinition("ENUM", "ENUM('yes', 'no')", sql::DataType::ENUM, "yes", true, 3, 0, true, "", 3, "NO", false)); columns.push_back(columndefinition("ENUM", "ENUM('yes', 'no') CHARACTER SET 'binary'", sql::DataType::ENUM, "yes", true, 3, 0, true, "", 3, "NO", false)); columns.push_back(columndefinition("ENUM", "ENUM('yes', 'no') NOT NULL", sql::DataType::ENUM, "yes", true, 3, 0, false, "", 3, "NO", false, "yes")); columns.push_back(columndefinition("ENUM", "ENUM('yes', 'no', 'not sure') NOT NULL", sql::DataType::ENUM, "yes", true, 8, 0, false, "", 8, "NO", false)); columns.push_back(columndefinition("ENUM", "ENUM('yes', 'no', 'buy') NOT NULL DEFAULT 'buy'", sql::DataType::ENUM, "yes", true, 3, 0, false, "buy", 3, "NO", false)); columns.push_back(columndefinition("SET", "SET('yes', 'no')", sql::DataType::SET, "yes", true, 6, 0, true, "", 6, "NO", false, "yes")); columns.push_back(columndefinition("SET", "SET('yes', 'no') CHARACTER SET 'binary'", sql::DataType::SET, "yes", true, 6, 0, true, "", 6, "NO", false, "yes")); columns.push_back(columndefinition("SET", "SET('yes', 'no') CHARSET 'ascii'", sql::DataType::SET, "yes", true, 6, 0, true, "", 6, "NO", false)); columns.push_back(columndefinition("SET", "SET('yes', 'no') CHARSET 'ascii' DEFAULT 'yes'", sql::DataType::SET, "yes", true, 6, 0, true, "yes", 6, "NO", false)); columns.push_back(columndefinition("SET", "SET('yes', 'no', 'ascii') CHARSET 'ascii' NOT NULL", sql::DataType::SET, "yes", true, 12, 0, false, "", 12, "NO", false)); /* ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException Retrieves a description of the given attribute of the given type for a user-defined type (UDT) that is available in the given schema and catalog. Descriptions are returned only for attributes of UDTs matching the catalog, schema, type, and attribute name criteria. They are ordered by TYPE_CAT, TYPE_SCHEM, TYPE_NAME and ORDINAL_POSITION. This description does not contain inherited attributes. The ResultSet object that is returned has the following columns: 1. TYPE_CAT String => type catalog (may be null) 2. TYPE_SCHEM String => type schema (may be null) 3. TYPE_NAME String => type name 4. ATTR_NAME String => attribute name 5. DATA_TYPE int => attribute type SQL type from java.sql.Types 6. ATTR_TYPE_NAME String => Data source dependent type name. For a UDT, the type name is fully qualified. For a REF, the type name is fully qualified and represents the target type of the reference type. 7. ATTR_SIZE int => column size. For char or date types this is the maximum number of characters; for numeric or decimal types this is precision. 8. DECIMAL_DIGITS int => the number of fractional digits. Null is returned for data types where DECIMAL_DIGITS is not applicable. 9. NUM_PREC_RADIX int => Radix (typically either 10 or 2) 10. NULLABLE int => whether NULL is allowed * attributeNoNulls - might not allow NULL values * attributeNullable - definitely allows NULL values * attributeNullableUnknown - nullability unknown 11. REMARKS String => comment describing column (may be null) 12. ATTR_DEF String => default value (may be null) 13. SQL_DATA_TYPE int => unused 14. SQL_DATETIME_SUB int => unused 15. CHAR_OCTET_LENGTH int => for char types the maximum number of bytes in the column 16. ORDINAL_POSITION int => index of the attribute in the UDT (starting at 1) 17. IS_NULLABLE String => ISO rules are used to determine the nullability for a attribute. * YES --- if the attribute can include NULLs * NO --- if the attribute cannot include NULLs * empty string --- if the nullability for the attribute is unknown 18. SCOPE_CATALOG String => catalog of table that is the scope of a reference attribute (null if DATA_TYPE isn't REF) 19. SCOPE_SCHEMA String => schema of table that is the scope of a reference attribute (null if DATA_TYPE isn't REF) 20. SCOPE_TABLE String => table name that is the scope of a reference attribute (null if the DATA_TYPE isn't REF) 21. SOURCE_DATA_TYPE short => source type of a distinct type or user-generated Ref type,SQL type from java.sql.Types (null if DATA_TYPE isn't DISTINCT or user-generated REF) */ attributes.push_back(udtattribute("TYPE_CAT", 0)); attributes.push_back(udtattribute("TYPE_SCHEM", 0)); attributes.push_back(udtattribute("TYPE_NAME", 0)); attributes.push_back(udtattribute("ATTR_NAME", 0)); attributes.push_back(udtattribute("DATA_TYPE", 0)); attributes.push_back(udtattribute("ATTR_TYPE_NAME", 0)); attributes.push_back(udtattribute("ATTR_SIZE", 0)); attributes.push_back(udtattribute("DECIMAL_DIGITS", 0)); attributes.push_back(udtattribute("NUM_PREC_RADIX", 0)); attributes.push_back(udtattribute("NULLABLE", 0)); attributes.push_back(udtattribute("REMARKS", 0)); attributes.push_back(udtattribute("ATTR_DEF", 0)); attributes.push_back(udtattribute("SQL_DATA_TYPE", 0)); attributes.push_back(udtattribute("SQL_DATETIME_SUB", 0)); attributes.push_back(udtattribute("CHAR_OCTET_LENGTH", 0)); attributes.push_back(udtattribute("ORDINAL_POSITION", 0)); attributes.push_back(udtattribute("IS_NULLABLE", 0)); attributes.push_back(udtattribute("SCOPE_CATALOG", 0)); attributes.push_back(udtattribute("SCOPE_SCHEMA", 0)); attributes.push_back(udtattribute("SCOPE_TABLE", 0)); attributes.push_back(udtattribute("SOURCE_DATA_TYPE", 0)); } void unit_fixture::setUp() { created_objects.clear(); try { con.reset(getConnection()); } catch (sql::SQLException & sqle) { logErr(String("Couldn't get connection") + sqle.what()); throw sqle; } /* TODO: conect message incl. version using logDebug() */ /* logDebug("Driver: " + driver->getName()); + " " + String(driver->getMajorVersion() + driver->getMajorVersion + String(".") + driver->getMinorVersion());*/ con->setSchema(db); stmt.reset(con->createStatement()); } void unit_fixture::tearDown() { res.reset(); for (int i=0; i < static_cast (created_objects.size() - 1); i+=2) { try { dropSchemaObject(created_objects[ i ], created_objects[ i + 1 ]); } catch (sql::SQLException &) { } } stmt.reset(); pstmt.reset(); con.reset(); } void unit_fixture::createSchemaObject(String object_type, String object_name, String columns_and_other_stuff) { created_objects.push_back(object_type); created_objects.push_back(object_name); dropSchemaObject(object_type, object_name); String sql("CREATE "); sql.append(object_type); sql.append(" "); sql.append(object_name); sql.append(" "); sql.append(columns_and_other_stuff); stmt->executeUpdate(sql); } void unit_fixture::dropSchemaObject(String object_type, String object_name) { stmt->executeUpdate(String("DROP ") + object_type + " IF EXISTS " + object_name); } void unit_fixture::createTable(String table_name, String columns_and_other_stuff) { createSchemaObject("TABLE", table_name, columns_and_other_stuff); } void unit_fixture::dropTable(String table_name) { dropSchemaObject("TABLE", table_name); } sql::Connection * unit_fixture::getConnection(sql::ConnectOptionsMap *additional_options) { if (driver == NULL) { driver=sql::mysql::get_driver_instance(); } sql::ConnectOptionsMap connection_properties; connection_properties["hostName"]=url; connection_properties["userName"]=user; connection_properties["password"]=passwd; bool bval= !TestsRunner::getStartOptions()->getBool("dont-use-is"); connection_properties["metadataUseInfoSchema"]=bval; bval=TestsRunner::getStartOptions()->getBool("use-dynamic-load"); if (bval) { sql::SQLString clientlib(DYNLOAD_MYSQL_LIB); connection_properties["clientlib"]=clientlib; logMsg("Connection using dynamic load of clientlib " DYNLOAD_MYSQL_LIB); } if (additional_options != NULL) { for (sql::ConnectOptionsMap::const_iterator cit= additional_options->begin(); cit != additional_options->end(); ++cit) { connection_properties[cit->first]= cit->second; } } return driver->connect(connection_properties); } void unit_fixture::logMsg(const String & message) { TestsListener::messagesLog(message + "\n"); } void unit_fixture::logErr(const String & message) { TestsListener::errorsLog(message + "\n"); } void unit_fixture::logDebug(const String & message) { logMsg(message); } /* There is not really need to have it as a class method */ int unit_fixture::getMySQLVersion(Connection & con) { DatabaseMetaData * dbmeta=con->getMetaData(); return dbmeta->getDatabaseMajorVersion() * 10000 + dbmeta->getDatabaseMinorVersion() * 1000 + dbmeta->getDatabasePatchVersion(); } std::string unit_fixture::exceptionIsOK(sql::SQLException & e) { return exceptionIsOK(e, "HY000", 0); } std::string unit_fixture::exceptionIsOK(sql::SQLException &e, const std::string& sql_state, int errNo) { std::stringstream reason; reason.str(""); std::string what(e.what()); if (what.empty()) { reason << "Exception must not have an empty message."; logMsg(reason.str()); return reason.str(); } if (e.getErrorCode() != errNo) { reason << "Expecting error code '" << errNo << "' got '" << e.getErrorCode() << "'"; logMsg(reason.str()); return reason.str(); } if (e.getSQLState() != sql_state) { reason << "Expecting sqlstate '" << sql_state << "' got '" << e.getSQLState() << "'"; logMsg(reason.str()); return reason.str(); } return reason.str(); } void unit_fixture::checkResultSetScrolling(ResultSet &res_ref) { /* if (res_ref->getType() == sql::ResultSet::TYPE_FORWARD_ONLY) return; */ int before; before=static_cast (res_ref->getRow()); if (!res_ref->last()) { res_ref->absolute(before); return; } int num_rows; int i; num_rows=(int) res_ref->getRow(); res_ref->beforeFirst(); ASSERT(!res_ref->previous()); ASSERT(res_ref->next()); ASSERT_EQUALS(1, (int) res_ref->getRow()); ASSERT(!res_ref->isBeforeFirst()); ASSERT(!res_ref->isAfterLast()); if (num_rows > 1) { ASSERT(res_ref->next()); ASSERT(res_ref->previous()); ASSERT_EQUALS(1, (int) res_ref->getRow()); } ASSERT(res_ref->first()); ASSERT_EQUALS(1, (int) res_ref->getRow()); ASSERT(res_ref->isFirst()); ASSERT(!res_ref->isBeforeFirst()); ASSERT(!res_ref->isAfterLast()); if (num_rows == 1) ASSERT(res_ref->isLast()); else ASSERT(!res_ref->isLast()); if (num_rows > 1) { ASSERT(res_ref->next()); ASSERT(res_ref->previous()); ASSERT_EQUALS(1, (int) res_ref->getRow()); } ASSERT(!res_ref->previous()); ASSERT(res_ref->last()); ASSERT_EQUALS(num_rows, (int) res_ref->getRow()); ASSERT(res_ref->isLast()); ASSERT(!res_ref->isBeforeFirst()); ASSERT(!res_ref->isAfterLast()); if (num_rows == 1) ASSERT(res_ref->isFirst()); else ASSERT(!res_ref->isFirst()); if (num_rows > 1) { ASSERT(res_ref->previous()); ASSERT_EQUALS(num_rows - 1, (int) res_ref->getRow()); ASSERT(res_ref->next()); ASSERT_EQUALS(num_rows, (int) res_ref->getRow()); } ASSERT(!res_ref->next()); res_ref->beforeFirst(); ASSERT_EQUALS(0, (int) res_ref->getRow()); ASSERT(res_ref->isBeforeFirst()); ASSERT(!res_ref->isAfterLast()); ASSERT(!res_ref->isFirst()); ASSERT(!res_ref->previous()); ASSERT(res_ref->next()); ASSERT_EQUALS(1, (int) res_ref->getRow()); res_ref->absolute(1); ASSERT_EQUALS(1, (int) res_ref->getRow()); ASSERT(!res_ref->previous()); res_ref->afterLast(); ASSERT_EQUALS(num_rows + 1, (int) res_ref->getRow()); ASSERT(res_ref->isAfterLast()); ASSERT(!res_ref->isBeforeFirst()); ASSERT(!res_ref->isFirst()); ASSERT(res_ref->previous()); ASSERT_EQUALS(num_rows, (int) res_ref->getRow()); ASSERT(!res_ref->next()); i=0; res_ref->beforeFirst(); while (res_ref->next()) { ASSERT(!res_ref->isAfterLast()); i++; ASSERT_EQUALS(i, (int) res_ref->getRow()); } ASSERT_EQUALS(num_rows, i); // relative(1) is equivalent to next() i=0; res_ref->beforeFirst(); while (res_ref->relative(1)) { ASSERT(!res_ref->isAfterLast()); i++; ASSERT_EQUALS(i, (int) res_ref->getRow()); } ASSERT_EQUALS(num_rows, i); i=0; res_ref->first(); do { ASSERT(!res_ref->isAfterLast()); i++; ASSERT_EQUALS(i, (int) res_ref->getRow()); } while (res_ref->next()); ASSERT_EQUALS(num_rows, i); // relative(1) is equivalent to next() i=0; res_ref->first(); do { ASSERT(!res_ref->isAfterLast()); i++; ASSERT_EQUALS(i, (int) res_ref->getRow()); } while (res_ref->relative(1)); ASSERT_EQUALS(num_rows, i); i=num_rows; res_ref->last(); do { ASSERT(!res_ref->isBeforeFirst()); ASSERT_EQUALS(i, (int) res_ref->getRow()); i--; } while (res_ref->previous()); ASSERT_EQUALS(0, i); // relative(-1) is equivalent to previous() i=num_rows; res_ref->last(); do { ASSERT(!res_ref->isBeforeFirst()); ASSERT_EQUALS(i, (int) res_ref->getRow()); i--; } while (res_ref->relative(-1)); ASSERT_EQUALS(0, i); i=num_rows; res_ref->afterLast(); while (res_ref->previous()) { ASSERT(!res_ref->isBeforeFirst()); ASSERT_EQUALS(i, (int) res_ref->getRow()); i--; } ASSERT_EQUALS(0, i); // relative(-1) is equivalent to previous() i=num_rows; res_ref->afterLast(); while (res_ref->relative(-1)) { ASSERT(!res_ref->isBeforeFirst()); ASSERT_EQUALS(i, (int) res_ref->getRow()); i--; } ASSERT_EQUALS(0, i); res_ref->last(); res_ref->relative(0); ASSERT(res_ref->isLast()); res_ref->absolute(before); ASSERT_EQUALS(before, (int) res_ref->getRow()); } } /* namespace testsuite */ mysql-connector-c++-1.1.7/test/unit/unit_fixture.h000644 015771 000012 00000025354 12645244437 022631 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _UNIT_FIXTURE_ #define _UNIT_FIXTURE_ #include #include "../framework/framework.h" #include #include #include #include namespace testsuite { /* TODO - document */ typedef boost::scoped_ptr Connection; typedef boost::scoped_ptr PreparedStatement; typedef sql::ParameterMetaData ParameterMetaData; typedef boost::scoped_ptr Statement; typedef boost::scoped_ptr Savepoint; typedef boost::scoped_ptr ResultSet; typedef sql::Driver Driver; typedef sql::ResultSetMetaData ResultSetMetaData; typedef sql::DatabaseMetaData DatabaseMetaData; struct columndefinition { std::string name; // TYPE_NAME std::string sqldef; int ctype; // DATA_TYPE std::string value; bool is_signed; unsigned int precision; // COLUMN_SIZE int decimal_digits; // DECIMAL_DIGITS bool is_nullable; // IS_NULLABLE int nullable; // NULLABLE std::string column_def; // COLUMN_DEF bool is_case_sensitive; std::string remarks; // REMARKS int is_searchable; bool fixed_prec_scale; bool auto_increment; std::string local_type_name; int minimum_scale; int maximum_scale; int num_prec_radix; // NUM_PREC_RADIX int sql_data_type; // SQL_DATA_TYPE int sql_datetime_sub; // SQL_DATA_TYPE_SUB unsigned int char_octet_length; std::string is_autoincrement; bool is_negative; std::string as_string; // value as it should be returns by getString() bool check_as_string; columndefinition(const std::string & _name, const std::string & _sqldef, int _ctype, const std::string & _value, bool _is_signed, unsigned int _precision, int _decimal_digits, bool _is_nullable, std::string _column_def, unsigned int _char_octet_length, const std::string & _is_autoincrement, bool _is_negative) : name(_name), sqldef(_sqldef), ctype(_ctype), value(_value), is_signed(_is_signed), precision(_precision), decimal_digits(_decimal_digits), is_nullable(_is_nullable), nullable((_is_nullable) ? sql::DatabaseMetaData::columnNullable : sql::DatabaseMetaData::columnNoNulls), column_def(_column_def), is_case_sensitive(false), remarks(""), is_searchable(sql::DatabaseMetaData::typeSearchable), fixed_prec_scale(false), auto_increment(false), local_type_name(""), minimum_scale(0), maximum_scale(0), num_prec_radix(10), sql_data_type(0), sql_datetime_sub(0), char_octet_length(_char_octet_length), is_autoincrement(_is_autoincrement), is_negative(_is_negative), check_as_string(false) { } columndefinition(const std::string & _name, const std::string & _sqldef, int _ctype, const std::string & _value, bool _is_signed, unsigned int _precision, int _decimal_digits, bool _is_nullable, const std::string & _column_def, int _char_octet_length, const std::string & _is_autoincrement, bool _is_negative, const std::string & _as_string) : name(_name), sqldef(_sqldef), ctype(_ctype), value(_value), is_signed(_is_signed), precision(_precision), decimal_digits(_decimal_digits), is_nullable(_is_nullable), nullable((_is_nullable) ? sql::DatabaseMetaData::columnNullable : sql::DatabaseMetaData::columnNoNulls), column_def(_column_def), is_case_sensitive(false), remarks(""), is_searchable(sql::DatabaseMetaData::typeSearchable), fixed_prec_scale(false), auto_increment(false), local_type_name(""), minimum_scale(0), maximum_scale(0), num_prec_radix(10), sql_data_type(0), sql_datetime_sub(0), char_octet_length(_char_octet_length), is_autoincrement(_is_autoincrement), is_negative(_is_negative), as_string(_as_string), check_as_string(true) { } }; struct udtattribute { std::string name; int ctype; udtattribute(std::string n, int c) : name(n), ctype(c) { } }; class unit_fixture : public TestSuite { private: typedef TestSuite super; protected: /** * List of SQL schema objects created during the test run * * Used by tearDown() to clean up the database after the test run */ List created_objects; /** * Driver to be used * * The element is managed by getConnection(). You do not need * to worry about the creation of a connection or a driver object, * use getConnection() to obtain a connection object. */ static Driver *driver; /** * Copies command line connection parameter into protected slots * */ void init(); /** * Effective database connection URL * * URL refers to the conector/C++ connection URL syntax * * Fallback to default_url, see also default_url */ String url; /** * Name of the schema to use (USE ) * * The schema will be selected during setUp() before running a test * Fallback to default_db, see also default_db */ String db; /** * Database user for getConnection() * * Fallback to default_user, see also default_user */ String user; /** * Database user password * * Fallback to default_password, see also default_password */ String passwd; /** * Database connection, initiated during setUp() and cleaned up in tearDown() * */ Connection con; /** * PreparedStatement to be used in tests, not initialized. Cleaned up in tearDown() */ PreparedStatement pstmt; /** * Statement to be used in tests, not initialized. Cleaned up in tearDown() */ Statement stmt; /** * ResultSet to be used in tests, not initialized. Cleaned up in tearDown() */ ResultSet res; /** * List of all column types known by MySQL * */ std::vector< columndefinition > columns; /** * List of all columns which getAttribute() should deliver * */ std::vector< udtattribute > attributes; /** * Creates a SQL schema object * * Use this method to create arbitrary SQL object if you want the test * framework to clean up SQL schema objects for you at the end of the test * in tearDown(). The framework will register all objects created with any * of the createXYZ() methods and call the appropriate dropXYZ() method during * tearDown(). * * Although this method is protected and available in the test, you should * prefer calling any of the specialized wrappers, for example createTable(). * * @param object_type SQL type, e.g. TABLE, FUNCTION, ... * @param object_name SQL element name, e.g. "table1" * @param columns_and_other_stuff Additional SQL definitions * @throws SQLException & */ void createSchemaObject(String object_type, String object_name, String columns_and_other_stuff); /** * Drops a SQL schema object * * All SQL objects created by createSchemaObject() will be implicitly * dropped during tearDown(). * * @param object_type SQL type e.g. TABLE, FUNCTION, ... * @param object_name SQL element name, e.g. "table1" * @throws SQLException & */ void dropSchemaObject(String object_type, String object_name); /** * Create a SQL table of the given name and with the specified SQL definition * * @param table_name SQL table name * @param columns_and_other_stuff Additional SQL definitions * @throws SQLException & */ void createTable(String table_name, String columns_and_other_stuff); /** * Drops a SQL table * * Note: all SQL tables created by createTable() will implicitly dropped * during tearDown(). * * @param table_name SQL table name * @throws SQLException & */ void dropTable(String table_name); /** * Returns a Connector/C++ connection object * * Note: you are responsible for handling the object, you might * want to use typedef boost::scoped_ptrcon(getConnection()) * or similar for convenience reasons. * * @throws SQLException & */ sql::Connection * getConnection(sql::ConnectOptionsMap *additional_opts=NULL); /** * Checks if the passed SQLException is caused by the specified error * */ std::string exceptionIsOK(sql::SQLException &e, const std::string& sql_state, int errNo); /** * Checks if the passed exception has the SQLState HY000 and the (vendor) error code 0 */ std::string exceptionIsOK(sql::SQLException &e); /** * Helper function to check scrolling through a result set */ void checkResultSetScrolling(ResultSet &res); /** * Helper function to fetch the MySQL Server version as a classical integer in the range from 30000 - 99999 */ int getMySQLVersion(Connection &con); public: /** * Creates a new BaseTestCase object. * * @param name The name of the unit test case */ unit_fixture(const String & name); /** * Writes a message to the debug log * * @param message */ void logDebug(const String & message); /** * Write (info) message to test protocol * * @param message Message to be included in the protocol */ void logMsg(const String & message); /** * Write error to test protocol * * @param message Message to be included in the protocol */ void logErr(const String & message); /** * Creates resources used by all tests. * * Opens a connection and stores the object in this->con. * All other members (this->stmt, this->pstmt, this->res) are uninitialized! * * @throws SQLException & */ virtual void setUp(); /** * Destroys resources created during the test case. * * @throws SQLException & */ virtual void tearDown(); }; } /* namespace testsuite */ #define EXAMPLE_TEST_FIXTURE( theFixtureClass ) typedef theFixtureClass TestSuiteClass;\ theFixtureClass( const String & /* name */ ) \ : unit_fixture( #theFixtureClass ) #endif // _UNIT_FIXTURE_ mysql-connector-c++-1.1.7/thread/CMakeLists.txt000644 015771 000012 00000005332 12645244437 021776 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # SET(MYSQLCPPCONN_THREAD_SOURCES my_pthread.c my_wincond.c my_winthread.c my_thr_init.c thr_mutex.c) ADD_LIBRARY(mysqlcppconn_thread SHARED ${MYSQLCPPCONN_THREAD_SOURCES}) ADD_LIBRARY(mysqlcppconn_thread-static STATIC ${MYSQLCPPCONN_THREAD_SOURCES}) IF(WIN32) ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") #Disables bunch of pretty useless warnings on win ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS") SET(MYTHREAD_TARGET_LINK_LIBRARIES_DYNAMIC ws2_32) SET(MYTHREAD_TARGET_LINK_LIBRARIES_STATIC ws2_32) ELSEIF(NOT WIN32) SET(MYTHREAD_TARGET_LINK_LIBRARIES_DYNAMIC pthread) SET(MYTHREAD_TARGET_LINK_LIBRARIES_STATIC pthread) ENDIF(WIN32) TARGET_LINK_LIBRARIES(mysqlcppconn_thread ${MYTHREAD_TARGET_LINK_LIBRARIES_DYNAMIC}) TARGET_LINK_LIBRARIES(mysqlcppconn_thread-static ${MYTHREAD_TARGET_LINK_LIBRARIES_STATIC}) SET_TARGET_PROPERTIES(mysqlcppconn_thread PROPERTIES SOVERSION "1" LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV} $ENV{CFLAGS}") SET_TARGET_PROPERTIES(mysqlcppconn_thread-static PROPERTIES LINK_FLAGS "${MYSQLCPPCONN_LINK_FLAGS_ENV}" COMPILE_FLAGS "${MYSQLCPPCONN_COMPILE_FLAGS_ENV} $ENV{CFLAGS}") IF(WIN32) INSTALL(TARGETS mysqlcppconn_thread mysqlcppconn_thread-static RUNTIME DESTINATION lib ARCHIVE DESTINATION lib ) ELSE(WIN32) INSTALL(TARGETS mysqlcppconn_thread mysqlcppconn_thread-static LIBRARY DESTINATION ${INSTALL_LIBDIR} ARCHIVE DESTINATION ${INSTALL_LIBDIR} ) ENDIF(WIN32) MESSAGE(STATUS "Configuring thread") mysql-connector-c++-1.1.7/thread/my_no_pthread.h000644 015771 000012 00000003427 12645244437 022242 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(_my_no_pthread_h) && !defined(THREAD) #define _my_no_pthread_h /* This block is to access some thread-related type definitions even in builds which do not need thread functions, as some variables (based on these types) are declared even in non-threaded builds. Case in point: 'mf_keycache.c' */ #if defined(_WIN32) || defined(_WIN64) #else /* Normal threads */ #include #endif /* defined(__WIN__) */ /* This undefs some pthread mutex locks when one isn't using threads to make thread safe code, that should also work in single thread environment, easier to use. */ #define pthread_mutex_init(A,B) #define pthread_mutex_lock(A) #define pthread_mutex_unlock(A) #define pthread_mutex_destroy(A) #endif mysql-connector-c++-1.1.7/thread/my_pthread.c000644 015771 000012 00000034676 12645244437 021553 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Functions to get threads more portable */ #define DONT_REMAP_PTHREAD_FUNCTIONS #ifdef THREAD #include "my_pthread.h" extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net; extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time; #else #include "my_no_pthread.h" #endif #ifdef THREAD #include //#include "m_string.h" #include "thr_alarm.h" #if (defined(__BSD__) || defined(_BSDI_VERSION)) #define SCHED_POLICY SCHED_RR #else #define SCHED_POLICY SCHED_OTHER #endif uint thd_lib_detected= 0; /* To allow use of pthread_getspecific with two arguments */ #ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC #undef pthread_getspecific void *my_pthread_getspecific_imp(pthread_key_t key) { void *value; if (pthread_getspecific(key,(void *) &value)) return 0; return value; } #endif #ifdef __NETWARE__ /* Don't kill the LibC Reaper thread or the main thread */ #include #undef pthread_exit void my_pthread_exit(void *status) { NXThreadId_t tid; NXContext_t ctx; char name[NX_MAX_OBJECT_NAME_LEN+1] = ""; tid= NXThreadGetId(); if (tid == NX_INVALID_THREAD_ID || !tid) return; if (NXThreadGetContext(tid, &ctx) || NXContextGetName(ctx, name, sizeof(name)-1)) return; /* "MYSQLD.NLM's LibC Reaper" or "MYSQLD.NLM's main thread" with a debug build of LibC the reaper can have different names */ if (!strindex(name, "\'s")) pthread_exit(status); } #endif /* Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7 (and DEC OSF/1 3.2 too) */ int my_pthread_create_detached=1; #if defined(HAVE_NONPOSIX_SIGWAIT) || defined(HAVE_DEC_3_2_THREADS) int my_sigwait(const sigset_t *set,int *sig) { int signal=sigwait((sigset_t*) set); if (signal < 0) return errno; *sig=signal; return 0; } #endif /* localtime_r for SCO 3.2V4.2 */ #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) extern pthread_mutex_t LOCK_localtime_r; #endif #if !defined(HAVE_LOCALTIME_R) struct tm *localtime_r(const time_t *clock, struct tm *res) { struct tm *tmp; pthread_mutex_lock(&LOCK_localtime_r); tmp=localtime(clock); *res= *tmp; pthread_mutex_unlock(&LOCK_localtime_r); return res; } #endif #if !defined(HAVE_GMTIME_R) /* Reentrant version of standard gmtime() function. Needed on some systems which don't implement it. */ struct tm *gmtime_r(const time_t *clock, struct tm *res) { struct tm *tmp; pthread_mutex_lock(&LOCK_localtime_r); tmp= gmtime(clock); *res= *tmp; pthread_mutex_unlock(&LOCK_localtime_r); return res; } #endif /**************************************************************************** ** Replacement of sigwait if the system doesn't have one (like BSDI 3.0) ** ** Note: ** This version of sigwait() is assumed to called in a loop so the signalmask ** is permanently modified to reflect the signal set. This is done to get ** a much faster implementation. ** ** This implementation isn't thread safe: It assumes that only one ** thread is using sigwait. ** ** If one later supplies a different signal mask, all old signals that ** was used before are unblocked and set to SIGDFL. ** ** Author: Gary Wisniewski , much modified by Monty ****************************************************************************/ #if !defined(HAVE_SIGWAIT) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) #if !defined(DONT_USE_SIGSUSPEND) static sigset_t sigwait_set,rev_sigwait_set,px_recd; void px_handle_sig(int sig) { sigaddset(&px_recd, sig); } void sigwait_setup(sigset_t *set) { int i; struct sigaction sact,sact1; sigset_t unblock_mask; sact.sa_flags = 0; sact.sa_handler = px_handle_sig; memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */ sigemptyset(&unblock_mask); pthread_sigmask(SIG_UNBLOCK,(sigset_t*) 0,&rev_sigwait_set); for (i = 1; i <= sizeof(sigwait_set)*8; i++) { if (sigismember(set,i)) { sigdelset(&rev_sigwait_set,i); if (!sigismember(&sigwait_set,i)) sigaction(i, &sact, (struct sigaction*) 0); } else { sigdelset(&px_recd,i); /* Don't handle this */ if (sigismember(&sigwait_set,i)) { /* Remove the old handler */ sigaddset(&unblock_mask,i); sigdelset(&rev_sigwait_set,i); sact1.sa_flags = 0; sact1.sa_handler = SIG_DFL; sigemptyset(&sact1.sa_mask); sigaction(i, &sact1, 0); } } } memcpy_fixed(&sigwait_set,set,sizeof(*set)); pthread_sigmask(SIG_BLOCK,(sigset_t*) set,(sigset_t*) 0); pthread_sigmask(SIG_UNBLOCK,&unblock_mask,(sigset_t*) 0); } int sigwait(sigset_t *setp, int *sigp) { if (memcmp(setp,&sigwait_set,sizeof(sigwait_set))) sigwait_setup(setp); /* Init or change of set */ for (;;) { /* This is a fast, not 100% portable implementation to find the signal. Because the handler is blocked there should be at most 1 bit set, but the specification on this is somewhat shady so we use a set instead a single variable. */ ulong *ptr= (ulong*) &px_recd; ulong *end=ptr+sizeof(px_recd)/sizeof(ulong); for ( ; ptr != end ; ptr++) { if (*ptr) { ulong set= *ptr; int found= (int) ((char*) ptr - (char*) &px_recd)*8+1; while (!(set & 1)) { found++; set>>=1; } *sigp=found; sigdelset(&px_recd,found); return 0; } } sigsuspend(&rev_sigwait_set); } return 0; } #else /* !DONT_USE_SIGSUSPEND */ /**************************************************************************** ** Replacement of sigwait if the system doesn't have one (like BSDI 3.0) ** ** Note: ** This version of sigwait() is assumed to called in a loop so the signalmask ** is permanently modified to reflect the signal set. This is done to get ** a much faster implementation. ** ** This implementation uses a extra thread to handle the signals and one ** must always call sigwait() with the same signal mask! ** ** BSDI 3.0 NOTE: ** ** pthread_kill() doesn't work on a thread in a select() or sleep() loop? ** After adding the sleep to sigwait_thread, all signals are checked and ** delivered every second. This isn't that terrible performance vice, but ** someone should report this to BSDI and ask for a fix! ** Another problem is that when the sleep() ends, every select() in other ** threads are interrupted! ****************************************************************************/ static sigset_t pending_set; static bool inited=0; static pthread_cond_t COND_sigwait; static pthread_mutex_t LOCK_sigwait; void sigwait_handle_sig(int sig) { pthread_mutex_lock(&LOCK_sigwait); sigaddset(&pending_set, sig); pthread_cond_signal(&COND_sigwait); /* inform sigwait() about signal */ pthread_mutex_unlock(&LOCK_sigwait); } void *sigwait_thread(void *set_arg) { sigset_t *set=(sigset_t*) set_arg; int i; struct sigaction sact; sact.sa_flags = 0; sact.sa_handler = sigwait_handle_sig; memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */ sigemptyset(&pending_set); for (i = 1; i <= sizeof(pending_set)*8; i++) { if (sigismember(set,i)) { sigaction(i, &sact, (struct sigaction*) 0); } } /* Ensure that init_thr_alarm() is called */ DBUG_ASSERT(thr_client_alarm); sigaddset(set, thr_client_alarm); pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0); alarm_thread=pthread_self(); /* For thr_alarm */ for (;;) { /* Wait for signals */ #ifdef HAVE_NOT_BROKEN_SELECT fd_set fd; FD_ZERO(&fd); select(0,&fd,0,0,0); #else sleep(1); /* Because of broken BSDI */ #endif } } int sigwait(sigset_t *setp, int *sigp) { if (!inited) { pthread_attr_t thr_attr; pthread_t sigwait_thread_id; inited=1; sigemptyset(&pending_set); pthread_mutex_init(&LOCK_sigwait,MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_sigwait,NULL); pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&thr_attr,8196); pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp); pthread_attr_destroy(&thr_attr); } pthread_mutex_lock(&LOCK_sigwait); for (;;) { ulong *ptr= (ulong*) &pending_set; ulong *end=ptr+sizeof(pending_set)/sizeof(ulong); for ( ; ptr != end ; ptr++) { if (*ptr) { ulong set= *ptr; int found= (int) ((char*) ptr - (char*) &pending_set)*8+1; while (!(set & 1)) { found++; set>>=1; } *sigp=found; sigdelset(&pending_set,found); pthread_mutex_unlock(&LOCK_sigwait); return 0; } } pthread_cond_wait(&COND_sigwait,&LOCK_sigwait); } return 0; } #endif /* DONT_USE_SIGSUSPEND */ #endif /* HAVE_SIGWAIT */ /**************************************************************************** The following functions fixes that all pthread functions should work according to latest posix standard ****************************************************************************/ /* Undefined wrappers set my_pthread.h so that we call os functions */ #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_unlock #undef pthread_mutex_destroy #undef pthread_mutex_wait #undef pthread_mutex_timedwait #undef pthread_mutex_trylock #undef pthread_mutex_t #undef pthread_cond_init #undef pthread_cond_wait #undef pthread_cond_timedwait #undef pthread_cond_t #undef pthread_attr_getstacksize /***************************************************************************** ** Patches for AIX and DEC OSF/1 3.2 *****************************************************************************/ #if defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT) #include int my_pthread_mutex_noposix_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr) { int error; if (!attr) error=pthread_mutex_init(mp,pthread_mutexattr_default); else error=pthread_mutex_init(mp,*attr); return error; } int my_pthread_cond_noposix_init(pthread_cond_t *mp, const pthread_condattr_t *attr) { int error; if (!attr) error=pthread_cond_init(mp,pthread_condattr_default); else error=pthread_cond_init(mp,*attr); return error; } #endif /***************************************************************************** Patches for HPUX We need these because the pthread_mutex.. code returns -1 on error, instead of the error code. Note that currently we only remap pthread_ functions used by MySQL. If we are depending on the value for some other pthread_xxx functions, this has to be added here. ****************************************************************************/ #if defined(HPUX10) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { int error=pthread_cond_timedwait(cond, mutex, abstime); if (error == -1) /* Safety if the lib is fixed */ { if (!(error=errno)) error= ETIMEDOUT; /* Can happen on HPUX */ } if (error == EAGAIN) /* Correct errno to Posix */ error= ETIMEDOUT; return error; } #endif #if defined(HPUX10) void my_pthread_attr_getstacksize(pthread_attr_t *connection_attrib, size_t *stack_size) { *stack_size= pthread_attr_getstacksize(*connection_attrib); } #endif #ifdef HAVE_POSIX1003_4a_MUTEX /* In HP-UX-10.20 and other old Posix 1003.4a Draft 4 implementations pthread_mutex_trylock returns 1 on success, not 0 like pthread_mutex_lock From the HP-UX-10.20 man page: RETURN VALUES If the function fails, errno may be set to one of the following values: Return | Error | Description _______|__________|_________________________________________ 1 | | Successful completion. 0 | | The mutex is locked; therefore, it was | | not acquired. -1 | [EINVAL] | The value specified by mutex is invalid. */ /* Convert pthread_mutex_trylock to return values according to latest POSIX RETURN VALUES 0 If we are able successfully lock the mutex. EBUSY Mutex was locked by another thread # Other error number returned by pthread_mutex_trylock() (Not likely) */ int my_pthread_mutex_trylock(pthread_mutex_t *mutex) { int error= pthread_mutex_trylock(mutex); if (error == 1) return 0; /* Got lock on mutex */ if (error == 0) /* Someon else is locking mutex */ return EBUSY; if (error == -1) /* Safety if the lib is fixed */ error= errno; /* Probably invalid parameter */ return error; } #endif /* HAVE_POSIX1003_4a_MUTEX */ /* Some help functions */ int pthread_no_free(void *not_used __attribute__((unused))) { return 0; } int pthread_dummy(int ret) { return ret; } #endif /* THREAD */ mysql-connector-c++-1.1.7/thread/my_pthread.h000644 015771 000012 00000053466 12645244437 021556 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Defines to make different thread packages compatible */ #ifndef _my_pthread_h #define _my_pthread_h #ifndef ETIME #define ETIME ETIMEDOUT /* For FreeBSD */ #endif #ifdef __cplusplus #define EXTERNC extern "C" extern "C" { #else #define EXTERNC #endif /* __cplusplus */ #if defined(_WIN32) || defined(_WIN64) typedef CRITICAL_SECTION pthread_mutex_t; typedef DWORD pthread_t; typedef struct thread_attr { DWORD dwStackSize ; DWORD dwCreatingFlag ; } pthread_attr_t ; typedef struct { int dummy; } pthread_condattr_t; /* Implementation of posix conditions */ typedef struct st_pthread_link { DWORD thread_id; struct st_pthread_link *next; } pthread_link; typedef struct { uint32 waiting; CRITICAL_SECTION lock_waiting; enum { SIGNAL= 0, BROADCAST= 1, MAX_EVENTS= 2 } EVENTS; HANDLE events[MAX_EVENTS]; HANDLE broadcast_block_event; } pthread_cond_t; typedef int pthread_mutexattr_t; #define pthread_self() GetCurrentThreadId() #define pthread_handler_t EXTERNC void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); /* Struct and macros to be used in combination with the windows implementation of pthread_cond_timedwait */ /* Declare a union to make sure FILETIME is properly aligned so it can be used directly as a 64 bit value. The value stored is in 100ns units. */ union ft64 { FILETIME ft; __int64 i64; }; struct timespec { union ft64 tv; /* The max timeout value in millisecond for pthread_cond_timedwait */ long max_timeout_msec; }; #define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \ (ABSTIME).tv.i64= (TIME)+(__int64)(NSEC)/100; \ (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \ } while(0) #define set_timespec_nsec(ABSTIME,NSEC) do { \ union ft64 tv; \ GetSystemTimeAsFileTime(&tv.ft); \ set_timespec_time_nsec((ABSTIME), tv.i64, (NSEC)); \ } while(0) int win_pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_attr_init(pthread_attr_t *connect_att); int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); int pthread_attr_destroy(pthread_attr_t *connect_att); struct tm *localtime_r(const time_t *timep,struct tm *tmp); struct tm *gmtime_r(const time_t *timep,struct tm *tmp); void pthread_exit(void *a); int pthread_join(pthread_t thread, void **value_ptr); #define ETIMEDOUT 145 /* Win32 doesn't have this */ #define HAVE_LOCALTIME_R 1 #define _REENTRANT 1 #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 #undef SAFE_MUTEX /* This will cause conflicts */ #define pthread_key(T,V) DWORD V #define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) #define pthread_key_delete(A) TlsFree(A) #define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V))) #define pthread_setspecific(A,B) (!TlsSetValue((A),(B))) #define pthread_getspecific(A) (TlsGetValue(A)) #define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) #define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V)) #define pthread_equal(A,B) ((A) == (B)) #define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0) #define pthread_mutex_lock(A) (EnterCriticalSection(A),0) #define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A)) #define pthread_mutex_unlock(A) (LeaveCriticalSection(A),0) #define pthread_mutex_destroy(A) DeleteCriticalSection(A) #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH) /* Dummy defines for easier code */ #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) #define pthread_attr_setscope(A,B) #define pthread_detach_this_thread() #define pthread_condattr_init(A) #define pthread_condattr_destroy(A) #define pthread_yield() SwitchToThread() #else /* Normal threads */ #ifdef HAVE_rts_threads #define sigwait org_sigwait #include #undef sigwait #endif #include #ifndef _REENTRANT #define _REENTRANT #endif #ifdef HAVE_THR_SETCONCURRENCY #include /* Probably solaris */ #endif #ifdef HAVE_SCHED_H #include #endif #ifdef HAVE_SYNCH_H #include #endif #ifdef __NETWARE__ void my_pthread_exit(void *status); #define pthread_exit(A) my_pthread_exit(A) #endif #define pthread_key(T,V) pthread_key_t V #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V)) #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V)) #define pthread_detach_this_thread() #define pthread_handler_t EXTERNC void * typedef void *(* pthread_handler)(void *); /* Test first for RTS or FSU threads */ #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) #define HAVE_rts_threads extern int my_pthread_create_detached; #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) #define PTHREAD_CREATE_DETACHED &my_pthread_create_detached #define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL #define USE_ALARM_THREAD #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ #if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910 int sigwait(sigset_t *set, int *sig); #endif #ifndef HAVE_NONPOSIX_SIGWAIT #define my_sigwait(A,B) sigwait((A),(B)) #else int my_sigwait(const sigset_t *set,int *sig); #endif #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT #ifndef SAFE_MUTEX #define pthread_mutex_init(a,b) my_pthread_mutex_noposix_init((a),(b)) extern int my_pthread_mutex_noposix_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr); #endif /* SAFE_MUTEX */ #define pthread_cond_init(a,b) my_pthread_cond_noposix_init((a),(b)) extern int my_pthread_cond_noposix_init(pthread_cond_t *mp, const pthread_condattr_t *attr); #endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK) #define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C)) #endif #if !defined(HAVE_SIGWAIT) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX) int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ #endif /* We define my_sigset() and use that instead of the system sigset() so that we can favor an implementation based on sigaction(). On some systems, such as Mac OS X, sigset() results in flags such as SA_RESTART being set, and we want to make sure that no such flags are set. */ #if defined(HAVE_SIGACTION) && !defined(my_sigset) #define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \ DBUG_ASSERT((A) != 0); \ sigemptyset(&l_set); \ l_s.sa_handler = (B); \ l_s.sa_mask = l_set; \ l_s.sa_flags = 0; \ l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\ DBUG_ASSERT(l_rc == 0); \ } while (0) #elif defined(HAVE_SIGSET) && !defined(my_sigset) #define my_sigset(A,B) sigset((A),(B)) #elif !defined(my_sigset) #define my_sigset(A,B) signal((A),(B)) #endif #if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS) #define pthread_attr_setscope(A,B) #undef HAVE_GETHOSTBYADDR_R /* No definition */ #endif #if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX) extern int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime); #define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C)) #endif #if !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC) #define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) #else #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) void *my_pthread_getspecific_imp(pthread_key_t key); #endif #ifndef HAVE_LOCALTIME_R struct tm *localtime_r(const time_t *clock, struct tm *res); #endif #ifndef HAVE_GMTIME_R struct tm *gmtime_r(const time_t *clock, struct tm *res); #endif #ifdef HAVE_PTHREAD_CONDATTR_CREATE /* DCE threads on HPUX 10.20 */ #define pthread_condattr_init pthread_condattr_create #define pthread_condattr_destroy pthread_condattr_delete #endif /* FSU THREADS */ #if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete) #define pthread_key_delete(A) pthread_dummy(0) #endif #ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */ #define pthread_cond_destroy(A) pthread_dummy(0) #define pthread_mutex_destroy(A) pthread_dummy(0) #define pthread_attr_delete(A) pthread_dummy(0) #define pthread_condattr_delete(A) pthread_dummy(0) #define pthread_attr_setstacksize(A,B) pthread_dummy(0) #define pthread_equal(A,B) ((A) == (B)) #define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b)) #define pthread_attr_init(A) pthread_attr_create(A) #define pthread_attr_destroy(A) pthread_attr_delete(A) #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH) #undef pthread_detach_this_thread #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } #endif #ifdef HAVE_DARWIN5_THREADS #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH) #define pthread_condattr_init(A) pthread_dummy(0) #define pthread_condattr_destroy(A) pthread_dummy(0) #undef pthread_detach_this_thread #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } #endif #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) /* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ #define pthread_key_create(A,B) \ pthread_keycreate(A,(B) ?\ (pthread_destructor_t) (B) :\ (pthread_destructor_t) pthread_dummy) #define pthread_attr_init(A) pthread_attr_create(A) #define pthread_attr_destroy(A) pthread_attr_delete(A) #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) #ifndef pthread_sigmask #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) #endif #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH) #undef pthread_detach_this_thread #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } #elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */ #define HAVE_PTHREAD_KILL #endif #endif /* defined(__WIN__) */ #if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) #undef pthread_cond_timedwait #define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c)) int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime); #endif #if defined(HPUX10) #define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B) void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size); #endif #if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) #undef pthread_mutex_trylock #define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a)) int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #endif #if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG) /* no pthread_yield() available */ #ifdef HAVE_SCHED_YIELD #define pthread_yield() sched_yield() #elif defined(HAVE_PTHREAD_YIELD_NP) /* can be Mac OS X */ #define pthread_yield() pthread_yield_np() #elif defined(HAVE_THR_YIELD) #define pthread_yield() thr_yield() #endif #endif /* The defines set_timespec and set_timespec_nsec should be used for calculating an absolute time at which pthread_cond_timedwait should timeout */ #define set_timespec(ABSTIME,SEC) set_timespec_nsec((ABSTIME),(SEC)*1000000000ULL) #ifndef set_timespec_nsec #define set_timespec_nsec(ABSTIME,NSEC) \ set_timespec_time_nsec((ABSTIME),my_getsystime(),(NSEC)) #endif /* !set_timespec_nsec */ /* adapt for two different flavors of struct timespec */ #ifdef HAVE_TIMESPEC_TS_SEC #define MY_tv_sec ts_sec #define MY_tv_nsec ts_nsec #else #define MY_tv_sec tv_sec #define MY_tv_nsec tv_nsec #endif /* HAVE_TIMESPEC_TS_SEC */ #ifndef set_timespec_time_nsec #define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \ ulonglong nsec= (NSEC); \ ulonglong now= (TIME) + (nsec/100); \ (ABSTIME).MY_tv_sec= (now / ULL(10000000)); \ (ABSTIME).MY_tv_nsec= (now % ULL(10000000) * 100 + (nsec % 100)); \ } while(0) #endif /* !set_timespec_time_nsec */ /* safe_mutex adds checking to mutex for easier debugging */ #if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY) #define SAFE_MUTEX_DETECT_DESTROY #endif struct st_hash; typedef struct st_safe_mutex_t { pthread_mutex_t global,mutex; const char *file, *name; uint line,count; myf create_flags, active_flags; ulong id; pthread_t thread; struct st_hash *locked_mutex, *used_mutex; struct st_safe_mutex_t *prev, *next; #ifdef SAFE_MUTEX_DETECT_DESTROY struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */ #endif } safe_mutex_t; typedef struct st_safe_mutex_deadlock_t { const char *file, *name; safe_mutex_t *mutex; uint line; ulong count; ulong id; my_bool warning_only; } safe_mutex_deadlock_t; #ifdef SAFE_MUTEX_DETECT_DESTROY /* Used to track the destroying of mutexes. This needs to be a seperate structure because the safe_mutex_t structure could be freed before the mutexes are destroyed. */ typedef struct st_safe_mutex_info_t { struct st_safe_mutex_info_t *next; struct st_safe_mutex_info_t *prev; const char *init_file; uint32 init_line; } safe_mutex_info_t; #endif /* SAFE_MUTEX_DETECT_DESTROY */ int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr, const char *name, myf my_flags, const char *file, uint line); int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file, uint line); int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, uint line); int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, struct timespec *abstime, const char *file, uint line); void safe_mutex_global_init(void); void safe_mutex_end(FILE *file); void safe_mutex_free_deadlock_data(safe_mutex_t *mp); /* Wrappers if safe mutex is actually used */ #define MYF_TRY_LOCK 1 #define MYF_NO_DEADLOCK_DETECTION 2 #ifdef SAFE_MUTEX #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_unlock #undef pthread_mutex_destroy #undef pthread_mutex_wait #undef pthread_mutex_timedwait #undef pthread_mutex_t #undef pthread_cond_wait #undef pthread_cond_timedwait #undef pthread_mutex_trylock #define my_pthread_mutex_init(A,B,C,D) safe_mutex_init((A),(B),(C),(D),__FILE__,__LINE__) #define pthread_mutex_init(A,B) safe_mutex_init((A),(B),#A,0,__FILE__,__LINE__) #define pthread_mutex_lock(A) safe_mutex_lock((A), 0, __FILE__, __LINE__) #define my_pthread_mutex_lock(A,B) safe_mutex_lock((A), (B), __FILE__, __LINE__) #define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) #define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) #define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) #define pthread_mutex_trylock(A) safe_mutex_lock((A), MYF_TRY_LOCK, __FILE__, __LINE__) #define pthread_mutex_t safe_mutex_t #define safe_mutex_assert_owner(mp) \ DBUG_ASSERT((mp)->count > 0 && \ pthread_equal(pthread_self(), (mp)->thread)) #define safe_mutex_assert_not_owner(mp) \ DBUG_ASSERT(! (mp)->count || \ ! pthread_equal(pthread_self(), (mp)->thread)) #else #define my_pthread_mutex_init(A,B,C,D) pthread_mutex_init((A),(B)) #define my_pthread_mutex_lock(A,B) pthread_mutex_lock(A) #define safe_mutex_assert_owner(mp) #define safe_mutex_assert_not_owner(mp) #define safe_mutex_free_deadlock_data(mp) #endif /* SAFE_MUTEX */ #if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) typedef struct st_my_pthread_fastmutex_t { pthread_mutex_t mutex; uint spins; uint rng_state; } my_pthread_fastmutex_t; void fastmutex_global_init(void); int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, const pthread_mutexattr_t *attr); int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_unlock #undef pthread_mutex_destroy #undef pthread_mutex_wait #undef pthread_mutex_timedwait #undef pthread_mutex_t #undef pthread_cond_wait #undef pthread_cond_timedwait #undef pthread_mutex_trylock #define pthread_mutex_init(A,B) my_pthread_fastmutex_init((A),(B)) #define pthread_mutex_lock(A) my_pthread_fastmutex_lock(A) #define pthread_mutex_unlock(A) pthread_mutex_unlock(&(A)->mutex) #define pthread_mutex_destroy(A) pthread_mutex_destroy(&(A)->mutex) #define pthread_cond_wait(A,B) pthread_cond_wait((A),&(B)->mutex) #define pthread_cond_timedwait(A,B,C) pthread_cond_timedwait((A),&(B)->mutex,(C)) #define pthread_mutex_trylock(A) pthread_mutex_trylock(&(A)->mutex) #define pthread_mutex_t my_pthread_fastmutex_t #endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */ #define GETHOSTBYADDR_BUFF_SIZE 2048 #ifndef HAVE_THR_SETCONCURRENCY #define thr_setconcurrency(A) pthread_dummy(0) #endif #if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize) #define pthread_attr_setstacksize(A,B) pthread_dummy(0) #endif /* Define mutex types, see my_thr_init.c */ #define MY_MUTEX_INIT_SLOW NULL #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP extern pthread_mutexattr_t my_fast_mutexattr; #define MY_MUTEX_INIT_FAST &my_fast_mutexattr #else #define MY_MUTEX_INIT_FAST NULL #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP extern pthread_mutexattr_t my_errorcheck_mutexattr; #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr #else #define MY_MUTEX_INIT_ERRCHK NULL #endif #ifndef ESRCH /* Define it to something */ #define ESRCH 1 #endif typedef ulong my_thread_id; extern void my_threadattr_global_init(void); extern my_bool my_thread_global_init(void); extern void my_thread_global_end(void); extern my_bool my_thread_init(void); extern void my_thread_end(void); extern const char *my_thread_name(void); extern my_thread_id my_thread_dbug_id(void); extern int pthread_no_free(void *); extern int pthread_dummy(int); /* All thread specific variables are in the following struct */ #define THREAD_NAME_SIZE 10 #ifndef DEFAULT_THREAD_STACK #if SIZEOF_CHARP > 4 /* MySQL can survive with 32K, but some glibc libraries require > 128K stack To resolve hostnames. Also recursive stored procedures needs stack. */ #define DEFAULT_THREAD_STACK (256*1024L) #else #define DEFAULT_THREAD_STACK (195*1024) #endif #endif #define MY_PTHREAD_LOCK_READ 0 #define MY_PTHREAD_LOCK_WRITE 1 struct st_my_thread_var { int thr_errno; pthread_cond_t suspend; pthread_mutex_t mutex; pthread_mutex_t * volatile current_mutex; pthread_cond_t * volatile current_cond; pthread_t pthread_self; my_thread_id id; int cmp_length; int volatile abort; my_bool init; struct st_my_thread_var *next,**prev; void *opt_info; uint lock_type; /* used by conditional release the queue */ void *stack_ends_here; safe_mutex_t *mutex_in_use; #ifndef DBUG_OFF void *dbug; char name[THREAD_NAME_SIZE+1]; #endif }; extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); extern void **my_thread_var_dbug(); extern safe_mutex_t **my_thread_var_mutex_in_use(); extern uint my_thread_end_wait_time; extern my_bool safe_mutex_deadlock_detector; #define my_thread_var (_my_thread_var()) #define my_errno my_thread_var->thr_errno /* Keep track of shutdown,signal, and main threads so that my_end() will not report errors with them */ /* Which kind of thread library is in use */ #define THD_LIB_OTHER 1 #define THD_LIB_NPTL 2 #define THD_LIB_LT 4 extern uint thd_lib_detected; #ifdef __cplusplus } #endif #endif /* _my_ptread_h */ mysql-connector-c++-1.1.7/thread/my_thr_init.c000644 015771 000012 00000034655 12645244437 021741 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file Functions for initialization and allocation of all mysys & debug thread variables. */ #ifdef THREAD #include "my_pthread.h" extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net; extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time; #else #include "my_no_pthread.h" #endif //#include "mysys_priv.h" //#include #include #ifdef THREAD pthread_key(struct st_my_thread_var*, THR_KEY_mysys); pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open, THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_heap, THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time; /** For insert/delete in the list of MyISAM open tables */ pthread_mutex_t THR_LOCK_myisam; /** For writing to the MyISAM logs */ pthread_mutex_t THR_LOCK_myisam_log; pthread_cond_t THR_COND_threads; uint THR_thread_count= 0; uint my_thread_end_wait_time= 5; #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) pthread_mutex_t LOCK_localtime_r; #endif #ifndef HAVE_GETHOSTBYNAME_R pthread_mutex_t LOCK_gethostbyname_r; #endif #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_t my_fast_mutexattr; #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP pthread_mutexattr_t my_errorcheck_mutexattr; #endif #ifdef _MSC_VER static void install_sigabrt_handler(); #endif #ifdef TARGET_OS_LINUX /* Dummy thread spawned in my_thread_global_init() below to avoid race conditions in NPTL pthread_exit code. */ static pthread_handler_t nptl_pthread_exit_hack_handler(void *arg __attribute((unused))) { /* Do nothing! */ pthread_exit(0); return 0; } #endif /* TARGET_OS_LINUX */ /** Initialize thread attributes. */ void my_threadattr_global_init(void) { #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP /* Set mutex type to "fast" a.k.a "adaptive" In this case the thread may steal the mutex from some other thread that is waiting for the same mutex. This will save us some context switches but may cause a thread to 'starve forever' while waiting for the mutex (not likely if the code within the mutex is short). */ pthread_mutexattr_init(&my_fast_mutexattr); /* ?= MY_MUTEX_INIT_FAST */ pthread_mutexattr_settype(&my_fast_mutexattr, PTHREAD_MUTEX_ADAPTIVE_NP); #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* Set mutex type to "errorcheck" */ pthread_mutexattr_init(&my_errorcheck_mutexattr); pthread_mutexattr_settype(&my_errorcheck_mutexattr, PTHREAD_MUTEX_ERRORCHECK); #endif } static uint get_thread_lib(void); /* initialize thread environment SYNOPSIS my_thread_global_init() RETURN 0 ok 1 error (Couldn't create THR_KEY_mysys) */ my_bool my_thread_global_init(void) { int pth_ret; thd_lib_detected= get_thread_lib(); if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0) { fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret); return 1; } #ifdef TARGET_OS_LINUX /* BUG#24507: Race conditions inside current NPTL pthread_exit() implementation. To avoid a possible segmentation fault during concurrent executions of pthread_exit(), a dummy thread is spawned which initializes internal variables of pthread lib. See bug description for a full explanation. TODO: Remove this code when fixed versions of glibc6 are in common use. */ if (thd_lib_detected == THD_LIB_NPTL) { pthread_t dummy_thread; pthread_attr_t dummy_thread_attr; pthread_attr_init(&dummy_thread_attr); pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED); pthread_create(&dummy_thread,&dummy_thread_attr, nptl_pthread_exit_hack_handler, NULL); } #endif /* TARGET_OS_LINUX */ /* Mutex used by my_thread_init() and after my_thread_destroy_mutex() */ my_pthread_mutex_init(&THR_LOCK_threads, MY_MUTEX_INIT_FAST, "THR_LOCK_threads", MYF_NO_DEADLOCK_DETECTION); my_pthread_mutex_init(&THR_LOCK_malloc, MY_MUTEX_INIT_FAST, "THR_LOCK_malloc", MYF_NO_DEADLOCK_DETECTION); if (my_thread_init()) return 1; /* Mutex uses by mysys */ pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW); pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW); pthread_mutex_init(&THR_LOCK_myisam_log,MY_MUTEX_INIT_SLOW); pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST); pthread_cond_init(&THR_COND_threads, NULL); #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW); #endif #ifndef HAVE_GETHOSTBYNAME_R pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW); #endif return 0; } /** Wait for all threads in system to die @fn my_wait_for_other_threads_to_die() @param number_of_threads Wait until this number of threads @retval 0 Less or equal to number_of_threads left @retval 1 Wait failed */ my_bool my_wait_for_other_threads_to_die(uint number_of_threads) { struct timespec abstime; my_bool all_threads_killed= 1; set_timespec(abstime, my_thread_end_wait_time); pthread_mutex_lock(&THR_LOCK_threads); while (THR_thread_count > number_of_threads) { int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads, &abstime); if (error == ETIMEDOUT || error == ETIME) { all_threads_killed= 0; break; } } pthread_mutex_unlock(&THR_LOCK_threads); return all_threads_killed; } /** End the mysys thread system. Called when ending the last thread */ void my_thread_global_end(void) { my_bool all_threads_killed; if (!(all_threads_killed= my_wait_for_other_threads_to_die(0))) { #ifdef HAVE_PTHREAD_KILL /* We shouldn't give an error here, because if we don't have pthread_kill(), programs like mysqld can't ensure that all threads are killed when we enter here. */ if (THR_thread_count) fprintf(stderr, "Error in my_thread_global_end(): %d threads didn't exit\n", THR_thread_count); #endif } pthread_key_delete(THR_KEY_mysys); #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_fast_mutexattr); #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_errorcheck_mutexattr); #endif if (all_threads_killed) { pthread_mutex_destroy(&THR_LOCK_threads); pthread_cond_destroy(&THR_COND_threads); pthread_mutex_destroy(&THR_LOCK_malloc); } } /* Free all mutex used by mysys */ void my_thread_destroy_mutex(void) { struct st_my_thread_var *tmp; tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); if (tmp) { safe_mutex_free_deadlock_data(&tmp->mutex); } pthread_mutex_destroy(&THR_LOCK_open); pthread_mutex_destroy(&THR_LOCK_lock); pthread_mutex_destroy(&THR_LOCK_isam); pthread_mutex_destroy(&THR_LOCK_myisam); pthread_mutex_destroy(&THR_LOCK_myisam_log); pthread_mutex_destroy(&THR_LOCK_heap); pthread_mutex_destroy(&THR_LOCK_net); pthread_mutex_destroy(&THR_LOCK_time); pthread_mutex_destroy(&THR_LOCK_charset); #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) pthread_mutex_destroy(&LOCK_localtime_r); #endif #ifndef HAVE_GETHOSTBYNAME_R pthread_mutex_destroy(&LOCK_gethostbyname_r); #endif } static my_thread_id thread_id= 0; /* Allocate thread specific memory for the thread, used by mysys and dbug SYNOPSIS my_thread_init() NOTES We can't use mutex_locks here if we are using windows as we may have compiled the program with SAFE_MUTEX, in which case the checking of mutex_locks will not work until the pthread_self thread specific variable is initialized. This function may called multiple times for a thread, for example if one uses my_init() followed by mysql_server_init(). RETURN 0 ok 1 Fatal error; mysys/dbug functions can't be used */ my_bool my_thread_init(void) { struct st_my_thread_var *tmp; my_bool error=0; #ifdef EXTRA_DEBUG_THREADS fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n", (ulong) pthread_self()); #endif if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys)) { #ifdef EXTRA_DEBUG_THREADS fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n", (long) pthread_self()); #endif goto end; } #ifdef _MSC_VER install_sigabrt_handler(); #endif if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp)))) { error= 1; goto end; } pthread_setspecific(THR_KEY_mysys,tmp); tmp->pthread_self= pthread_self(); my_pthread_mutex_init(&tmp->mutex, MY_MUTEX_INIT_FAST, "mysys_var->mutex", 0); pthread_cond_init(&tmp->suspend, NULL); tmp->stack_ends_here= (char*)&tmp + STACK_DIRECTION * (long)my_thread_stack_size; pthread_mutex_lock(&THR_LOCK_threads); tmp->id= ++thread_id; ++THR_thread_count; pthread_mutex_unlock(&THR_LOCK_threads); tmp->init= 1; #ifndef DBUG_OFF /* Generate unique name for thread */ (void) my_thread_name(); #endif end: return error; } /* Deallocate memory used by the thread for book-keeping SYNOPSIS my_thread_end() NOTE This may be called multiple times for a thread. This happens for example when one calls 'mysql_server_init()' mysql_server_end() and then ends with a mysql_end(). */ void my_thread_end(void) { struct st_my_thread_var *tmp; tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); #ifdef EXTRA_DEBUG_THREADS fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n", (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L); #endif if (tmp && tmp->init) { #if !defined(__bsdi__) && !defined(__OpenBSD__) /* bsdi and openbsd 3.5 dumps core here */ pthread_cond_destroy(&tmp->suspend); #endif pthread_mutex_destroy(&tmp->mutex); #if !defined(DBUG_OFF) /* tmp->dbug is allocated inside DBUG library */ if (tmp->dbug) { /* Frees memory allocated in SET DEBUG=...; does nothing if there were no SET DEBUG in a thread. */ DBUG_POP(); free(tmp->dbug); tmp->dbug=0; } #endif #ifndef DBUG_OFF /* To find bugs when accessing unallocated data */ bfill(tmp, sizeof(tmp), 0x8F); #endif free(tmp); pthread_setspecific(THR_KEY_mysys,0); /* Decrement counter for number of running threads. We are using this in my_thread_global_end() to wait until all threads have called my_thread_end and thus freed all memory they have allocated in my_thread_init() and DBUG_xxxx */ pthread_mutex_lock(&THR_LOCK_threads); DBUG_ASSERT(THR_thread_count != 0); if (--THR_thread_count == 0) pthread_cond_signal(&THR_COND_threads); pthread_mutex_unlock(&THR_LOCK_threads); } else { pthread_setspecific(THR_KEY_mysys,0); } } struct st_my_thread_var *_my_thread_var(void) { return my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); } #ifndef DBUG_OFF /* Return pointer to DBUG for holding current state */ extern void **my_thread_var_dbug() { struct st_my_thread_var *tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); return tmp && tmp->init ? &tmp->dbug : 0; } #endif /* Return pointer to mutex_in_use */ safe_mutex_t **my_thread_var_mutex_in_use() { struct st_my_thread_var *tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); return tmp ? &tmp->mutex_in_use : 0; } /**************************************************************************** Get name of current thread. ****************************************************************************/ my_thread_id my_thread_dbug_id() { return my_thread_var->id; } #ifdef DBUG_OFF const char *my_thread_name(void) { return "no_name"; } #else const char *my_thread_name(void) { char name_buff[100]; struct st_my_thread_var *tmp=my_thread_var; if (!tmp->name[0]) { my_thread_id id= my_thread_dbug_id(); sprintf(name_buff,"T@%lu", (ulong) id); strmake(tmp->name,name_buff,THREAD_NAME_SIZE); } return tmp->name; } #endif /* DBUG_OFF */ static uint get_thread_lib(void) { #ifdef _CS_GNU_LIBPTHREAD_VERSION char buff[64]; confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff)); if (!strncasecmp(buff, "NPTL", 4)) return THD_LIB_NPTL; if (!strncasecmp(buff, "linuxthreads", 12)) return THD_LIB_LT; #endif return THD_LIB_OTHER; } #ifdef _WIN32 /* In Visual Studio 2005 and later, default SIGABRT handler will overwrite any unhandled exception filter set by the application and will try to call JIT debugger. This is not what we want, this we calling __debugbreak to stop in debugger, if process is being debugged or to generate EXCEPTION_BREAKPOINT and then handle_segfault will do its magic. */ #if (_MSC_VER >= 1400) static void my_sigabrt_handler(int sig) { __debugbreak(); } #endif /*_MSC_VER >=1400 */ static void install_sigabrt_handler(void) { #if (_MSC_VER >=1400) /*abort() should not override our exception filter*/ _set_abort_behavior(0,_CALL_REPORTFAULT); signal(SIGABRT,my_sigabrt_handler); #endif /* _MSC_VER >=1400 */ } #endif #endif /* THREAD */ mysql-connector-c++-1.1.7/thread/my_wincond.c000644 015771 000012 00000014641 12645244437 021553 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /***************************************************************************** ** The following is a simple implementation of posix conditions *****************************************************************************/ #if defined(_WIN32) #undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */ #include #include #include #include "my_pthread.h" int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { cond->waiting= 0; InitializeCriticalSection(&cond->lock_waiting); cond->events[SIGNAL]= CreateEvent(NULL, /* no security */ FALSE, /* auto-reset event */ FALSE, /* non-signaled initially */ NULL); /* unnamed */ /* Create a manual-reset event. */ cond->events[BROADCAST]= CreateEvent(NULL, /* no security */ TRUE, /* manual-reset */ FALSE, /* non-signaled initially */ NULL); /* unnamed */ cond->broadcast_block_event= CreateEvent(NULL, /* no security */ TRUE, /* manual-reset */ TRUE, /* signaled initially */ NULL); /* unnamed */ if( cond->events[SIGNAL] == NULL || cond->events[BROADCAST] == NULL || cond->broadcast_block_event == NULL ) return ENOMEM; return 0; } int pthread_cond_destroy(pthread_cond_t *cond) { DeleteCriticalSection(&cond->lock_waiting); if (CloseHandle(cond->events[SIGNAL]) == 0 || CloseHandle(cond->events[BROADCAST]) == 0 || CloseHandle(cond->broadcast_block_event) == 0) return EINVAL; return 0; } int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { return pthread_cond_timedwait(cond,mutex,NULL); } int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { int result; long timeout; union ft64 now; if( abstime != NULL ) { GetSystemTimeAsFileTime(&now.ft); /* Calculate time left to abstime - subtract start time from current time(values are in 100ns units) - convert to millisec by dividing with 10000 */ timeout= (long)((abstime->tv.i64 - now.i64) / 10000); /* Don't allow the timeout to be negative */ if (timeout < 0) timeout= 0L; /* Make sure the calucated timeout does not exceed original timeout value which could cause "wait for ever" if system time changes */ if (timeout > abstime->max_timeout_msec) timeout= abstime->max_timeout_msec; } else { /* No time specified; don't expire */ timeout= INFINITE; } /* Block access if previous broadcast hasn't finished. This is just for safety and should normally not affect the total time spent in this function. */ WaitForSingleObject(cond->broadcast_block_event, INFINITE); EnterCriticalSection(&cond->lock_waiting); cond->waiting++; LeaveCriticalSection(&cond->lock_waiting); LeaveCriticalSection(mutex); result= WaitForMultipleObjects(2, cond->events, FALSE, timeout); EnterCriticalSection(&cond->lock_waiting); cond->waiting--; if (cond->waiting == 0) { /* We're the last waiter to be notified or to stop waiting, so reset the manual event. */ /* Close broadcast gate */ ResetEvent(cond->events[BROADCAST]); /* Open block gate */ SetEvent(cond->broadcast_block_event); } LeaveCriticalSection(&cond->lock_waiting); EnterCriticalSection(mutex); return result == WAIT_TIMEOUT ? ETIMEDOUT : 0; } int pthread_cond_signal(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); if(cond->waiting > 0) SetEvent(cond->events[SIGNAL]); LeaveCriticalSection(&cond->lock_waiting); return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); /* The mutex protect us from broadcasting if there isn't any thread waiting to open the block gate after this call has closed it. */ if(cond->waiting > 0) { /* Close block gate */ ResetEvent(cond->broadcast_block_event); /* Open broadcast gate */ SetEvent(cond->events[BROADCAST]); } LeaveCriticalSection(&cond->lock_waiting); return 0; } int pthread_attr_init(pthread_attr_t *connect_att) { connect_att->dwStackSize = 0; connect_att->dwCreatingFlag = 0; return 0; } int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack) { connect_att->dwStackSize=stack; return 0; } int pthread_attr_destroy(pthread_attr_t *connect_att) { memset((void*) connect_att, 0, sizeof(*connect_att)); return 0; } /**************************************************************************** ** Fix localtime_r() to be a bit safer ****************************************************************************/ struct tm *localtime_r(const time_t *timep,struct tm *tmp) { if (*timep == (time_t) -1) /* This will crash win32 */ { memset((void*)tmp, 0, sizeof(*tmp)); } else { struct tm *res=localtime(timep); if (!res) /* Wrong date */ { memset((void*)tmp, 0, sizeof(*tmp)); /* Keep things safe */ return 0; } *tmp= *res; } return tmp; } #endif /* __WIN__ */ mysql-connector-c++-1.1.7/thread/my_winthread.c000644 015771 000012 00000007335 12645244437 022101 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /***************************************************************************** ** Simulation of posix threads calls for Windows *****************************************************************************/ #if defined (_WIN32) /* SAFE_MUTEX will not work until the thread structure is up to date */ #undef SAFE_MUTEX #include #include "my_pthread.h" #include #include // re-defining calls to debug functions from libmysql #ifdef DBUG_PRINT #undef DBUG_PRINT #endif #define DBUG_PRINT(keyword, argslist) #ifdef DBUG_ENTER #undef DBUG_ENTER #endif #define DBUG_ENTER(p) #ifdef DBUG_RETURN #undef DBUG_RETURN #endif #define DBUG_RETURN(a1) return(a1) static void install_sigabrt_handler(void); struct thread_start_parameter { pthread_handler func; void *arg; }; /** Adapter to @c pthread_mutex_trylock() @retval 0 Mutex was acquired @retval EBUSY Mutex was already locked by a thread */ int win_pthread_mutex_trylock(pthread_mutex_t *mutex) { if (TryEnterCriticalSection(mutex)) { /* Don't allow recursive lock */ if (mutex->RecursionCount > 1){ LeaveCriticalSection(mutex); return EBUSY; } return 0; } return EBUSY; } static unsigned int __stdcall pthread_start(void *p) { struct thread_start_parameter *par= (struct thread_start_parameter *)p; pthread_handler func= par->func; void *arg= par->arg; free(p); (*func)(arg); return 0; } int pthread_create(pthread_t *thread_id, pthread_attr_t *attr, pthread_handler func, void *param) { uintptr_t handle; struct thread_start_parameter *par; unsigned int stack_size; DBUG_ENTER("pthread_create"); par= (struct thread_start_parameter *)malloc(sizeof(*par)); if (!par) goto error_return; par->func= func; par->arg= param; stack_size= attr?attr->dwStackSize:0; handle= _beginthreadex(NULL, stack_size , pthread_start, par, 0, thread_id); if (!handle) goto error_return; DBUG_PRINT("info", ("thread id=%u",*thread_id)); /* Do not need thread handle, close it */ CloseHandle((HANDLE)handle); DBUG_RETURN(0); error_return: DBUG_PRINT("error", ("Can't create thread to handle request (error %d)",errno)); DBUG_RETURN(-1); } void pthread_exit(void *a) { _endthreadex(0); } int pthread_join(pthread_t thread, void **value_ptr) { DWORD ret; HANDLE handle; handle= OpenThread(SYNCHRONIZE, FALSE, thread); if (!handle) { errno= EINVAL; goto error_return; } ret= WaitForSingleObject(handle, INFINITE); if(ret != WAIT_OBJECT_0) { errno= EINVAL; goto error_return; } CloseHandle(handle); return 0; error_return: if(handle) CloseHandle(handle); return -1; } #endif mysql-connector-c++-1.1.7/thread/thr_alarm.h000644 015771 000012 00000006144 12645244437 021362 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Prototypes when using thr_alarm library functions */ #ifndef _thr_alarm_h #define _thr_alarm_h #ifdef __cplusplus extern "C" { #endif #ifndef USE_ALARM_THREAD #define USE_ONE_SIGNAL_HAND /* One must call process_alarm */ #endif #ifdef HAVE_rts_threads #undef USE_ONE_SIGNAL_HAND #define USE_ALARM_THREAD #define THR_SERVER_ALARM SIGUSR1 #else #define THR_SERVER_ALARM SIGALRM #endif typedef struct st_alarm_info { ulong next_alarm_time; uint active_alarms; uint max_used_alarms; } ALARM_INFO; void thr_alarm_info(ALARM_INFO *info); #if defined(DONT_USE_THR_ALARM) || !defined(THREAD) #define USE_ALARM_THREAD #undef USE_ONE_SIGNAL_HAND typedef my_bool thr_alarm_t; typedef my_bool ALARM; #define thr_alarm_init(A) (*(A))=0 #define thr_alarm_in_use(A) (*(A) != 0) #define thr_end_alarm(A) #define thr_alarm(A,B,C) ((*(A)=1)-1) /* The following should maybe be (*(A)) */ #define thr_got_alarm(A) 0 #define init_thr_alarm(A) #define thr_alarm_kill(A) #define resize_thr_alarm(N) #define end_thr_alarm(A) #else #if defined(__WIN__) typedef struct st_thr_alarm_entry { rf_SetTimer crono; } thr_alarm_entry; #else /* System with posix threads */ typedef int thr_alarm_entry; #define thr_got_alarm(thr_alarm) (**(thr_alarm)) #endif /* __WIN__ */ typedef thr_alarm_entry* thr_alarm_t; typedef struct st_alarm { ulong expire_time; thr_alarm_entry alarmed; /* set when alarm is due */ pthread_t thread; my_thread_id thread_id; my_bool malloced; } ALARM; extern uint thr_client_alarm; extern pthread_t alarm_thread; #define thr_alarm_init(A) (*(A))=0 #define thr_alarm_in_use(A) (*(A)!= 0) void init_thr_alarm(uint max_alarm); void resize_thr_alarm(uint max_alarms); my_bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff); void thr_alarm_kill(my_thread_id thread_id); void thr_end_alarm(thr_alarm_t *alarmed); void end_thr_alarm(my_bool free_structures); sig_handler process_alarm(int); #ifndef thr_got_alarm my_bool thr_got_alarm(thr_alarm_t *alrm); #endif #endif /* DONT_USE_THR_ALARM */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _thr_alarm_h */ mysql-connector-c++-1.1.7/thread/thr_mutex.c000644 015771 000012 00000063217 12645244437 021427 0ustar00pb2userwheel000000 000000 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPLv2 , like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPLv2 as it is applied to this software, see the FLOSS License Exception . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This makes a wrapper for mutex handling to make it easier to debug mutex */ #include #if defined(TARGET_OS_LINUX) && !defined (__USE_UNIX98) #define __USE_UNIX98 /* To get rw locks under Linux */ #endif #if defined(THREAD) && defined(SAFE_MUTEX) #undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */ #include "mysys_priv.h" #include "my_static.h" #include #include #ifndef DO_NOT_REMOVE_THREAD_WRAPPERS /* Remove wrappers */ #undef pthread_mutex_t #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_unlock #undef pthread_mutex_destroy #undef pthread_cond_wait #undef pthread_cond_timedwait #undef safe_mutex_free_deadlock_data #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT #define pthread_mutex_init(a,b) my_pthread_noposix_mutex_init((a),(b)) #endif #endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */ static pthread_mutex_t THR_LOCK_mutex; static ulong safe_mutex_count= 0; /* Number of mutexes created */ static ulong safe_mutex_id= 0; my_bool safe_mutex_deadlock_detector= 1; /* On by default */ #ifdef SAFE_MUTEX_DETECT_DESTROY static struct st_safe_mutex_create_info_t *safe_mutex_create_root= NULL; #endif static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex, safe_mutex_deadlock_t *locked_mutex); static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex, safe_mutex_t *current_mutex); static my_bool remove_from_locked_mutex(safe_mutex_t *mp, safe_mutex_t *delete_mutex); static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex, safe_mutex_t *mutex); static void print_deadlock_warning(safe_mutex_t *new_mutex, safe_mutex_t *conflicting_mutex); void safe_mutex_global_init(void) { pthread_mutex_init(&THR_LOCK_mutex,MY_MUTEX_INIT_FAST); safe_mutex_id= safe_mutex_count= 0; safe_mutex_deadlock_detector= 1; #ifdef SAFE_MUTEX_DETECT_DESTROY safe_mutex_create_root= 0; #endif } static inline void remove_from_active_list(safe_mutex_t *mp) { if (!(mp->active_flags & (MYF_NO_DEADLOCK_DETECTION | MYF_TRY_LOCK))) { /* Remove mutex from active mutex linked list */ if (mp->next) mp->next->prev= mp->prev; if (mp->prev) mp->prev->next= mp->next; else *my_thread_var_mutex_in_use()= mp->next; } mp->prev= mp->next= 0; } int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr __attribute__((unused)), const char *name, myf my_flags, const char *file, uint line) { DBUG_ENTER("safe_mutex_init"); DBUG_PRINT("enter",("mutex: 0x%lx name: %s", (ulong) mp, name)); bzero((char*) mp,sizeof(*mp)); pthread_mutex_init(&mp->global,MY_MUTEX_INIT_ERRCHK); pthread_mutex_init(&mp->mutex,attr); /* Mark that mutex is initialized */ mp->file= file; mp->line= line; /* Skip the very common '&' prefix from the autogenerated name */ mp->name= name[0] == '&' ? name + 1 : name; if (safe_mutex_deadlock_detector && !( my_flags & MYF_NO_DEADLOCK_DETECTION)) { if (!my_multi_malloc(MY_FAE | MY_WME, &mp->locked_mutex, sizeof(*mp->locked_mutex), &mp->used_mutex, sizeof(*mp->used_mutex), NullS)) { /* Disable deadlock handling for this mutex */ my_flags|= MYF_NO_DEADLOCK_DETECTION; } else { pthread_mutex_lock(&THR_LOCK_mutex); mp->id= ++safe_mutex_id; pthread_mutex_unlock(&THR_LOCK_mutex); my_hash_init(mp->locked_mutex, &my_charset_bin, 1000, offsetof(safe_mutex_deadlock_t, id), sizeof(mp->id), 0, 0, HASH_UNIQUE); my_hash_init(mp->used_mutex, &my_charset_bin, 1000, offsetof(safe_mutex_t, id), sizeof(mp->id), 0, 0, HASH_UNIQUE); } } else my_flags|= MYF_NO_DEADLOCK_DETECTION; mp->create_flags= my_flags; #ifdef SAFE_MUTEX_DETECT_DESTROY /* Monitor the freeing of mutexes. This code depends on single thread init and destroy */ if ((mp->info= (safe_mutex_info_t *) malloc(sizeof(safe_mutex_info_t)))) { struct st_safe_mutex_info_t *info= mp->info; info->init_file= file; info->init_line= line; info->prev= NULL; info->next= NULL; pthread_mutex_lock(&THR_LOCK_mutex); if ((info->next= safe_mutex_create_root)) safe_mutex_create_root->prev= info; safe_mutex_create_root= info; safe_mutex_count++; pthread_mutex_unlock(&THR_LOCK_mutex); } #else thread_safe_increment(safe_mutex_count, &THR_LOCK_mutex); #endif /* SAFE_MUTEX_DETECT_DESTROY */ DBUG_RETURN(0); } int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file, uint line) { int error; DBUG_PRINT("mutex", ("%s (0x%lx) locking", mp->name ? mp->name : "Null", (ulong) mp)); if (!mp->file) { fprintf(stderr, "safe_mutex: Trying to lock unitialized mutex at %s, line %d\n", file, line); fflush(stderr); abort(); } pthread_mutex_lock(&mp->global); if (mp->count > 0) { /* Check that we are not trying to lock mutex twice. This is an error even if we are using 'try_lock' as it's not portably what happens if you lock the mutex many times and this is in any case bad behaviour that should not be encouraged */ if (pthread_equal(pthread_self(),mp->thread)) { fprintf(stderr, "safe_mutex: Trying to lock mutex at %s, line %d, when the" " mutex was already locked at %s, line %d in thread %s\n", file,line,mp->file, mp->line, my_thread_name()); fflush(stderr); abort(); } } pthread_mutex_unlock(&mp->global); /* If we are imitating trylock(), we need to take special precautions. - We cannot use pthread_mutex_lock() only since another thread can overtake this thread and take the lock before this thread causing pthread_mutex_trylock() to hang. In this case, we should just return EBUSY. Hence, we use pthread_mutex_trylock() to be able to return immediately. - We cannot just use trylock() and continue execution below, since this would generate an error and abort execution if the thread was overtaken and trylock() returned EBUSY . In this case, we instead just return EBUSY, since this is the expected behaviour of trylock(). */ if (my_flags & MYF_TRY_LOCK) { error= pthread_mutex_trylock(&mp->mutex); if (error == EBUSY) return error; } else error= pthread_mutex_lock(&mp->mutex); if (error || (error=pthread_mutex_lock(&mp->global))) { fprintf(stderr,"Got error %d when trying to lock mutex %s at %s, line %d\n", error, mp->name, file, line); fflush(stderr); abort(); } mp->thread= pthread_self(); if (mp->count++) { fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex %s at %s, " "line %d more than 1 time\n", mp->name, file,line); fflush(stderr); abort(); } mp->file= file; mp->line= line; mp->active_flags= mp->create_flags | my_flags; pthread_mutex_unlock(&mp->global); /* Deadlock detection */ mp->prev= mp->next= 0; if (!(mp->active_flags & (MYF_TRY_LOCK | MYF_NO_DEADLOCK_DETECTION))) { safe_mutex_t **mutex_in_use= my_thread_var_mutex_in_use(); if (!mutex_in_use) { /* thread has not called my_thread_init() */ mp->active_flags|= MYF_NO_DEADLOCK_DETECTION; } else { safe_mutex_t *mutex_root; if ((mutex_root= *mutex_in_use)) /* If not first locked */ { /* Protect locked_mutex against changes if a mutex is deleted */ pthread_mutex_lock(&THR_LOCK_mutex); if (! my_hash_search(mutex_root->locked_mutex, (uchar*) &mp->id, 0)) { safe_mutex_deadlock_t *deadlock; safe_mutex_t *mutex; /* Create object to store mutex info */ if (!(deadlock= my_malloc(sizeof(*deadlock), MYF(MY_ZEROFILL | MY_WME | MY_FAE)))) goto abort_loop; deadlock->name= mp->name; deadlock->id= mp->id; deadlock->mutex= mp; /* The following is useful for debugging wrong mutex usage */ deadlock->file= file; deadlock->line= line; /* Check if potential deadlock */ mutex= mutex_root; do { if (my_hash_search(mp->locked_mutex, (uchar*) &mutex->id, 0)) { print_deadlock_warning(mp, mutex); /* Mark wrong usage to avoid future warnings for same error */ deadlock->warning_only= 1; add_to_locked_mutex(deadlock, mutex_root); DBUG_ASSERT(deadlock->count > 0); goto abort_loop; } } while ((mutex= mutex->next)); /* Copy current mutex and all mutex that has been locked after current mutex (mp->locked_mutex) to all mutex that was locked before previous mutex (mutex_root->used_mutex) For example if A->B would have been done before and we are now locking (C) in B->C, then we would add C into B->locked_mutex and A->locked_mutex */ my_hash_iterate(mutex_root->used_mutex, (my_hash_walk_action) add_used_to_locked_mutex, deadlock); /* Copy all current mutex and all mutex locked after current one into the prev mutex */ add_used_to_locked_mutex(mutex_root, deadlock); DBUG_ASSERT(deadlock->count > 0); } abort_loop: pthread_mutex_unlock(&THR_LOCK_mutex); } /* Link mutex into mutex_in_use list */ if ((mp->next= *mutex_in_use)) (*mutex_in_use)->prev= mp; *mutex_in_use= mp; } } DBUG_PRINT("mutex", ("%s (0x%lx) locked", mp->name, (ulong) mp)); return error; } int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line) { int error; DBUG_PRINT("mutex", ("%s (0x%lx) unlocking", mp->name, (ulong) mp)); pthread_mutex_lock(&mp->global); if (mp->count == 0) { fprintf(stderr, "safe_mutex: Trying to unlock mutex %s that wasn't locked at " "%s, line %d\n" "Last used at %s, line: %d\n", mp->name ? mp->name : "Null", file, line, mp->file ? mp->file : "Null", mp->line); fflush(stderr); abort(); } if (!pthread_equal(pthread_self(),mp->thread)) { fprintf(stderr, "safe_mutex: Trying to unlock mutex %s at %s, line %d that was " "locked by " "another thread at: %s, line: %d\n", mp->name, file, line, mp->file, mp->line); fflush(stderr); abort(); } mp->thread= 0; mp->count--; remove_from_active_list(mp); #ifdef __WIN__ pthread_mutex_unlock(&mp->mutex); error=0; #else error=pthread_mutex_unlock(&mp->mutex); if (error) { fprintf(stderr, "safe_mutex: Got error: %d (%d) when trying to unlock mutex " "%s at %s, line %d\n", error, errno, mp->name, file, line); fflush(stderr); abort(); } #endif /* __WIN__ */ pthread_mutex_unlock(&mp->global); return error; } int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, uint line) { int error; safe_mutex_t save_state; pthread_mutex_lock(&mp->global); if (mp->count == 0) { fprintf(stderr, "safe_mutex: Trying to cond_wait on a unlocked mutex %s at %s, " "line %d\n", mp->name ? mp->name : "Null", file, line); fflush(stderr); abort(); } if (!pthread_equal(pthread_self(),mp->thread)) { fprintf(stderr, "safe_mutex: Trying to cond_wait on a mutex %s at %s, line %d " "that was locked by another thread at: %s, line: %d\n", mp->name, file, line, mp->file, mp->line); fflush(stderr); abort(); } if (mp->count-- != 1) { fprintf(stderr, "safe_mutex: Count was %d on locked mutex %s at %s, line %d\n", mp->count+1, mp->name, file, line); fflush(stderr); abort(); } save_state= *mp; remove_from_active_list(mp); pthread_mutex_unlock(&mp->global); error=pthread_cond_wait(cond,&mp->mutex); pthread_mutex_lock(&mp->global); if (error) { fprintf(stderr, "safe_mutex: Got error: %d (%d) when doing a safe_mutex_wait on " "%s at %s, line %d\n", error, errno, mp->name, file, line); fflush(stderr); abort(); } /* Restore state as it was before */ mp->thread= save_state.thread; mp->active_flags= save_state.active_flags; mp->next= save_state.next; mp->prev= save_state.prev; if (mp->count++) { fprintf(stderr, "safe_mutex: Count was %d in thread 0x%lx when locking mutex %s " "at %s, line %d\n", mp->count-1, my_thread_dbug_id(), mp->name, file, line); fflush(stderr); abort(); } mp->file= file; mp->line=line; pthread_mutex_unlock(&mp->global); return error; } int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, struct timespec *abstime, const char *file, uint line) { int error; safe_mutex_t save_state; pthread_mutex_lock(&mp->global); if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread)) { fprintf(stderr, "safe_mutex: Trying to cond_wait at %s, line %d on a not hold " "mutex %s\n", file, line, mp->name ? mp->name : "Null"); fflush(stderr); abort(); } mp->count--; /* Mutex will be released */ save_state= *mp; remove_from_active_list(mp); pthread_mutex_unlock(&mp->global); error=pthread_cond_timedwait(cond,&mp->mutex,abstime); #ifdef EXTRA_DEBUG if (error && (error != EINTR && error != ETIMEDOUT && error != ETIME)) { fprintf(stderr, "safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait " "on %s at %s, line %d\n", error, errno, mp->name, file, line); } #endif pthread_mutex_lock(&mp->global); /* Restore state as it was before */ mp->thread= save_state.thread; mp->active_flags= save_state.active_flags; mp->next= save_state.next; mp->prev= save_state.prev; if (mp->count++) { fprintf(stderr, "safe_mutex: Count was %d in thread 0x%lx when locking mutex " "%s at %s, line %d (error: %d (%d))\n", mp->count-1, my_thread_dbug_id(), mp->name, file, line, error, error); fflush(stderr); abort(); } mp->file= file; mp->line=line; pthread_mutex_unlock(&mp->global); return error; } int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line) { int error=0; DBUG_ENTER("safe_mutex_destroy"); DBUG_PRINT("enter", ("mutex: 0x%lx name: %s", (ulong) mp, mp->name)); if (!mp->file) { fprintf(stderr, "safe_mutex: Trying to destroy unitialized mutex at %s, line %d\n", file, line); fflush(stderr); abort(); } if (mp->count != 0) { fprintf(stderr, "safe_mutex: Trying to destroy a mutex %s that was locked at %s, " "line %d at %s, line %d\n", mp->name, mp->file, mp->line, file, line); fflush(stderr); abort(); } /* Free all entries that points to this one */ safe_mutex_free_deadlock_data(mp); #ifdef __WIN__ pthread_mutex_destroy(&mp->global); pthread_mutex_destroy(&mp->mutex); #else if (pthread_mutex_destroy(&mp->global)) error=1; if (pthread_mutex_destroy(&mp->mutex)) error=1; #endif mp->file= 0; /* Mark destroyed */ #ifdef SAFE_MUTEX_DETECT_DESTROY if (mp->info) { struct st_safe_mutex_info_t *info= mp->info; pthread_mutex_lock(&THR_LOCK_mutex); if (info->prev) info->prev->next = info->next; else safe_mutex_create_root = info->next; if (info->next) info->next->prev = info->prev; safe_mutex_count--; pthread_mutex_unlock(&THR_LOCK_mutex); free(info); mp->info= NULL; /* Get crash if double free */ } #else thread_safe_sub(safe_mutex_count, 1, &THR_LOCK_mutex); #endif /* SAFE_MUTEX_DETECT_DESTROY */ DBUG_RETURN(error); } /** Free all data related to deadlock detection This is also useful together with safemalloc when you don't want to have reports of not freed memory for mysys mutexes. */ void safe_mutex_free_deadlock_data(safe_mutex_t *mp) { /* Free all entries that points to this one */ if (!(mp->create_flags & MYF_NO_DEADLOCK_DETECTION)) { pthread_mutex_lock(&THR_LOCK_mutex); my_hash_iterate(mp->used_mutex, (my_hash_walk_action) remove_from_locked_mutex, mp); my_hash_iterate(mp->locked_mutex, (my_hash_walk_action) remove_from_used_mutex, mp); pthread_mutex_unlock(&THR_LOCK_mutex); my_hash_free(mp->used_mutex); my_hash_free(mp->locked_mutex); my_free(mp->locked_mutex, 0); mp->create_flags|= MYF_NO_DEADLOCK_DETECTION; } } /* Free global resources and check that all mutex has been destroyed SYNOPSIS safe_mutex_end() file Print errors on this file NOTES We can't use DBUG_PRINT() here as we have in my_end() disabled DBUG handling before calling this function. In MySQL one may get one warning for a mutex created in my_thr_init.c This is ok, as this thread may not yet have been exited. */ void safe_mutex_end(FILE *file __attribute__((unused))) { if (!safe_mutex_count) /* safetly */ pthread_mutex_destroy(&THR_LOCK_mutex); #ifdef SAFE_MUTEX_DETECT_DESTROY if (!file) return; if (safe_mutex_count) { fprintf(file, "Warning: Not destroyed mutex: %lu\n", safe_mutex_count); (void) fflush(file); } { struct st_safe_mutex_info_t *ptr; for (ptr= safe_mutex_create_root ; ptr ; ptr= ptr->next) { fprintf(file, "\tMutex %s initiated at line %4u in '%s'\n", ptr->name, ptr->init_line, ptr->init_file); (void) fflush(file); } } #endif /* SAFE_MUTEX_DETECT_DESTROY */ } static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex, safe_mutex_deadlock_t *locked_mutex) { /* Add mutex to all parent of the current mutex */ if (!locked_mutex->warning_only) { (void) my_hash_iterate(locked_mutex->mutex->locked_mutex, (my_hash_walk_action) add_to_locked_mutex, used_mutex); /* mark that locked_mutex is locked after used_mutex */ (void) add_to_locked_mutex(locked_mutex, used_mutex); } return 0; } /** register that locked_mutex was locked after current_mutex */ static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex, safe_mutex_t *current_mutex) { DBUG_ENTER("add_to_locked_mutex"); DBUG_PRINT("info", ("inserting 0x%lx into 0x%lx (id: %lu -> %lu)", (ulong) locked_mutex, (long) current_mutex, locked_mutex->id, current_mutex->id)); if (my_hash_insert(current_mutex->locked_mutex, (uchar*) locked_mutex)) { /* Got mutex through two paths; ignore */ DBUG_RETURN(0); } locked_mutex->count++; if (my_hash_insert(locked_mutex->mutex->used_mutex, (uchar*) current_mutex)) { DBUG_ASSERT(0); } DBUG_RETURN(0); } /** Remove mutex from the locked mutex hash @fn remove_from_used_mutex() @param mp Mutex that has delete_mutex in it's locked_mutex hash @param delete_mutex Mutex should be removed from the hash @notes safe_mutex_deadlock_t entries in the locked hash are shared. When counter goes to 0, we delete the safe_mutex_deadlock_t entry. */ static my_bool remove_from_locked_mutex(safe_mutex_t *mp, safe_mutex_t *delete_mutex) { safe_mutex_deadlock_t *found; DBUG_ENTER("remove_from_locked_mutex"); DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)", (ulong) delete_mutex, (ulong) mp, delete_mutex->id, mp->id)); found= (safe_mutex_deadlock_t*) my_hash_search(mp->locked_mutex, (uchar*) &delete_mutex->id, 0); DBUG_ASSERT(found); if (found) { if (my_hash_delete(mp->locked_mutex, (uchar*) found)) { DBUG_ASSERT(0); } if (!--found->count) my_free(found, MYF(0)); } DBUG_RETURN(0); } static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex, safe_mutex_t *mutex) { DBUG_ENTER("remove_from_used_mutex"); DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)", (ulong) mutex, (ulong) locked_mutex, mutex->id, locked_mutex->id)); if (my_hash_delete(locked_mutex->mutex->used_mutex, (uchar*) mutex)) { DBUG_ASSERT(0); } if (!--locked_mutex->count) my_free(locked_mutex, MYF(0)); DBUG_RETURN(0); } static void print_deadlock_warning(safe_mutex_t *new_mutex, safe_mutex_t *parent_mutex) { safe_mutex_t *mutex_root; DBUG_ENTER("print_deadlock_warning"); DBUG_PRINT("enter", ("mutex: %s parent: %s", new_mutex->name, parent_mutex->name)); fprintf(stderr, "safe_mutex: Found wrong usage of mutex " "'%s' and '%s'\n", parent_mutex->name, new_mutex->name); DBUG_PRINT("info", ("safe_mutex: Found wrong usage of mutex " "'%s' and '%s'", parent_mutex->name, new_mutex->name)); fprintf(stderr, "Mutex currently locked (in reverse order):\n"); DBUG_PRINT("info", ("Mutex currently locked (in reverse order):")); fprintf(stderr, "%-32.32s %s line %u\n", new_mutex->name, new_mutex->file, new_mutex->line); DBUG_PRINT("info", ("%-32.32s %s line %u\n", new_mutex->name, new_mutex->file, new_mutex->line)); for (mutex_root= *my_thread_var_mutex_in_use() ; mutex_root; mutex_root= mutex_root->next) { fprintf(stderr, "%-32.32s %s line %u\n", mutex_root->name, mutex_root->file, mutex_root->line); DBUG_PRINT("info", ("%-32.32s %s line %u", mutex_root->name, mutex_root->file, mutex_root->line)); } fflush(stderr); DBUG_VOID_RETURN; } #endif /* THREAD && SAFE_MUTEX */ #if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) #include "mysys_priv.h" #include "my_static.h" #include #include #include #include #include #include #undef pthread_mutex_t #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_trylock #undef pthread_mutex_unlock #undef pthread_mutex_destroy #undef pthread_cond_wait #undef pthread_cond_timedwait ulong mutex_delay(ulong delayloops) { ulong i; volatile ulong j; j = 0; for (i = 0; i < delayloops * 50; i++) j += i; return(j); } #define MY_PTHREAD_FASTMUTEX_SPINS 8 #define MY_PTHREAD_FASTMUTEX_DELAY 4 static int cpu_count= 0; int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, const pthread_mutexattr_t *attr) { if ((cpu_count > 1) && (attr == MY_MUTEX_INIT_FAST)) mp->spins= MY_PTHREAD_FASTMUTEX_SPINS; else mp->spins= 0; mp->rng_state= 1; return pthread_mutex_init(&mp->mutex, attr); } /** Park-Miller random number generator. A simple linear congruential generator that operates in multiplicative group of integers modulo n. x_{k+1} = (x_k g) mod n Popular pair of parameters: n = 2^32 яПНтˆ’ 5 = 4294967291 and g = 279470273. The period of the generator is about 2^31. Largest value that can be returned: 2147483646 (RAND_MAX) Reference: S. K. Park and K. W. Miller "Random number generators: good ones are hard to find" Commun. ACM, October 1988, Volume 31, No 10, pages 1192-1201. */ static double park_rng(my_pthread_fastmutex_t *mp) { mp->rng_state= ((my_ulonglong)mp->rng_state * 279470273U) % 4294967291U; return (mp->rng_state / 2147483647.0); } int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp) { int res; uint i; uint maxdelay= MY_PTHREAD_FASTMUTEX_DELAY; for (i= 0; i < mp->spins; i++) { res= pthread_mutex_trylock(&mp->mutex); if (res == 0) return 0; if (res != EBUSY) return res; mutex_delay(maxdelay); maxdelay += park_rng(mp) * MY_PTHREAD_FASTMUTEX_DELAY + 1; } return pthread_mutex_lock(&mp->mutex); } void fastmutex_global_init(void) { #ifdef _SC_NPROCESSORS_CONF cpu_count= sysconf(_SC_NPROCESSORS_CONF); #endif } #endif /* defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */ mysql-connector-c++-1.1.7/win/Bitmaps/MySQLConnector.ico000644 015771 000012 00000041646 12645244437 023507 0ustar00pb2userwheel000000 000000  ЈF hю  ЈV 00 Ј%ў( @€       #(- 0"4%8(:*;+=,?-A.B0E1 G3!I4"M7#Q:%U<'X?)[A*]C+`E,bF-fI,jM)mO&tUyZ_ ‚a ƒc „c †d ‡e‰fŠfŒg(h0h2“l.”n(•o"–p•q–r—s™tšu›vœxyŸ|ž|Ÿ~#Ё€(Ђ+Ѓƒ*Є„(Ѕ„'Ї…&Ј†%Љ†%Њ‡&Ћˆ(­‰*ЎŠ,Џ‹.АŒ0БŒ1БŒ2АŒ4БŒ5В‹8А9ЏŽ:Џ;Џ=Ў‘=Ў‘=Џ’=А’=Б“=Г”=Е•>Ж•@З•AЙ•BЙ•CЙ”DЙ–FЗ—GЕ—IД•JВ“LЏN­ŒOЏPАSА”TБ˜UБ™WВ›XГœYГZДž[Еž[ЗŸZИ [ЙЁZМЂXНЃWОЄWПЂUРЁTУ UЦVЩ›WЬšXЮ™Yа™Zб˜\б—]г˜^д™^еš`жšbз›dкœeмgнžhоžhоŸiпŸiп jо jоЂlмЅnлЇoиЊoдЌmЯЎiЬЏhЪЏgШЎfЧЎgЦ­gХ­fУЌhСЋiРЋjРЋmРЌoРЎtТЏtФАtХБtЩГuЪДvЫЖwЬЗyЬИzЬЗ{ЬЗ{ЬИ|ЬЙ~ЬЙ€ЭКЬЙ‚ЮЛƒаЛ„аЛ…ЯЛ†ЯЛ‡ЯЛˆЯЛ‰ЯМ‹аОŒЯОаРŽбРвСгТдУŽжУзФиХиЦ’иЧ”иЧ–зЧ™жЧ›жЧœзШзЩžйЪ кЫ лЬЁмЬ мЭ мЭЁнЮ оЮŸрЯ раЁсбЂтвЄугЅфдІудЈсгЊпг­овЏнвАогБпеЕсиЛукРхнФцоХшрЩщтЬыфаьчеяымёэрѓ№хіѓъїѕэџџџ z”ЄЄЅЅЄЃ” |ЅЧиррсрнзЫЅЃ zЄЪмруфхххсрзгЦІЂ zЅжинрухццццфржвФИЂ |КЯгзирсфцчччцфрдЦЛЉ™ |ЅУЮбджзрфхцччцффжвОЗŠ˜ |ЃИРФЧбгезфхчшшшцфждФЙ­Œš ЁБЖЙОФФвдефцщъъъщхждФКЌŒr| |™ЏЎЎЎЎЖЛвефшъыыыъцвПИЋŠu`’  …ŠЎМЪайЪƒЏИРШЭЯЭДВаолаЙ‹^cz |˜xˆЙьњўїѓњљћќќ§§ќњњѓїў§ыЋ`[ž ”ŽjvЎЮ№пѓўўўўўўўўўўўўѓяѕз­`Z‘ ™ubjlli~§§єяЪƒРЧГЪяє§§††Œt`ZsA ›eS]ammЖњіВіѕМъыЬѕіГїњЯ­q^Xdz ›ROSW\^‚їіГѓкƒПСАмєГіїГ‹Œn^Wdz ›RHMVk…~ТРйкТтььтТкйТЪ†ДŠn\Ncz œR;H]ЏбтактГтээээтГтлЯурЛrXNsB œq:H`ŠХрнЦАgw„…†‡‚ЖЯоузЗnNM“  •9;PSSQPUmŒЌЉЇЇКЇЇŠvigjpdNM˜ ŸE:SeluŒ‹‹ŒŠЌЊЉЉЉЉЉЊЎ‹uaL`| œ{7QwvŒ‰Š­ЉЗЙЛЛООЛЙЗЉ­Š‰UI— ŸE:~†ˆЏЎЋЗЙКОПППОКЙЗЋЎuHc”  —;EВВЕЗЙМПУФФХФФУПМЙЏHNž ž7RТТЧЩЫЮЯаааааЯЮЫПKI™”  :RЭккклмнннннмлРHG—•  •F=Гяяяя№№№№№п~;Qœ˜   s=EƒЯяєєоЪyџšzџІ‰/џБœZџЧИˆџТВƒџТВ}џФЕџСГƒџЦЗ‡џКЈmџ­:џЄџЖ„2џа•c‘г—diЗ…BџŽm џЕ›KџЦГyџУАwџ­˜TџОЋmџС­qџАœ[џЧЕ~џШЕ~џРЇ]џyџО‰Aџг—diа•cд˜_џ…h џЁ†3џІŠ6џЉŒ5џБ”>џЖ™DџИIџЖ›IџА”BџЌ‘?џЌ‘=џ”q џж™_џа•cкœg—Ёv-џЄHџИЂ^џПЈcџЦЎkџШБoџЪГrџЩВqџЦЎkџПЈcџЌ‘BџЈz,џкœgšлœh+мfџ’q&џКЊwџЩЙ‹џЭМ‹џЯОŒџбРŽџЯОŒџЭМ‹џОЌtџ–sџмfџлœh.нži^мfџЁ{7џВЃqџзЮВџмгИџмгИџжЬ­џ­š_џЁx-џмfџнži^р j0оŸišв—^џЊ<џЌ‹Oџ­ŒOџЉ|7џв—^џоŸišр j0р jр jxр j™р j™р j{р jрџџРџџ€џџџџџџџџџџџџџџџџџџ€џџ€џџРџџрџџјџџ( @ € %)($ &7GU^cb\RD3"'A^x>-ЁA.АpP5ЧbF/Ц=,Й*Џ™ˆrW;! 6Z\B, ŸrKиб•cјоЇrџоЈsџнЏ{џн­yџоЇrџоЄnџФŒ]ї„^>с2$͘wQ. @vT8šИƒWунЊuџлЙ‡џлЧ™џлЬ џмЬ џмЭ џлЬžџкЪšџиШ–џиОˆџйАxџнЄmџ“iEщ8(Пa7 CЈxOФнІqџйМŠџйЩœџлЬ џнЮЂџоЮЃџоЯЄџоЯЃџоЯЂџнЭ џмЫœџкШ–џзФџгП†џеЎtџоЂjџ„^>р˜h8kM3^ЋzQФй­xџеФ”џиШ™џкЪœџмЬŸџнЮЁџоЯЂџпаЃџраЄџраЃџраЂџоЮŸџмЬšџкШ”џжУ‹џвНџЭДrџкЃiџfDц™c1K5#?А}SПеАzџгСџеФ’џиЧ–џкЩ™џмЫ›џнЭžџоЮŸџраЂџсбЃџсбЃџсбЂџраЁџпЮџнۘџйЦџеР†џЯЙxџШАiџдЂcџgDфW% И„WЖдЊrџЮЛ„џвРŠџеТŽџжХ‘џйЧ“џлЩ–џнЬšџпЮџпЯžџса џсбЁџсб џса џрЮџоЬ™џлЩ“џзУŠџвМ|џЫГmџУЉ\џжŸaџ‰bAм}AЙ„X•зЄlџШДxџЭЙџаМƒџгП‡џеТŠџиФџкЧ’џнЫ–џоݘџрЯџтбŸџт‟у‟твЁџтаžџпЭšџмЪ“џйХ‹џдО€џЭЕoџХЊ]џПŸMџкžcџbF/П`( Y?*&о jџФЊlџЧВsџЫЕwџЮИ{џаЛџгО‚џзТˆџкЧŽџмЪ’џпЭ—џсаœџфгЂџхеЄџцжІџхеЅџфгЂџсЯ›џоЫ”џкЦ‹џеРџЯЗqџЦЋ^џНŸJџП—CџГ€Uь|;Р‰[ŒЭ dџРЉeџТЌhџУЌiџТЌiџУ­jџЦБpџЭИzџзУ‡џмЩ‘џрЭ—џувŸџцжЅџшиЊџщйЋџшйЊџчжІџсаœџжУŠџЯК~џЪДsџХЎgџСІWџМžGџВ’2џв™WџX?*АN0#п jџКžXџНІ^џУ­lџЩЕ|џЭН‹џаТ–џвХ›џЪЛџД cџКІgџЧД{џЫЙџЮНˆџаРџбСџаРџСБzџКЉpџЯТ—џзЫІџеШŸџвТ“џЫЖwџПЂNџГ‘/џЛŽ7џЌ{Qт^%Н‡YGгœbџВ™LџЛЂWџЫЖzџобЉџ№ъжџљї№џцтгџмиХџышнџъциџ№ьрџѓ№хџєёцџѕђчџѕђшџђюуџьшлџыщнџмиХџхтгџћњіџїѓцџуе­џЧЎcџД“2џ­‰$џоŸgџ o- Ю“b‚Ф—Vџ­“BџЕšJџУЌgџгРŒџрдБџеЬЌџркФџћљѕџќњіџќњіџќњіџќњіџќњіџќњіџќњіџќњіџќњіџќњіџќњіџпйФџзЯБџчоСџйЩ—џХЊ\џД“3џЌˆ"џЯ—SџfI0˜2 иšfЎЖŽGџЈŒ6џЏ’:џА“;џА“>џЎ‘?џЌ™TџіђчџїѓщџтлХџеЭВџУИџГЁdџШИџЫЛ‡џКЋsџФЙ‘џеЭВџтлЦџїѓщџіђчџЖЃgџИ VџМЁPџКœDџД“2џЋˆ!џЦ’Eџ‹cBЎ3 мhСЌ‡;џЂ„*џЊ‹.џЏ3џД”9џГ•<џХГyџёыйџшрЦџЗІoџшрШџшоФџЧЕ{џшзІџылЌџЮОŠџшпХџшрШџН­{џщтЩџёыйџаС‘џФЊ`џХЉVџМBџГ‘/џЊ†џП;џЂsLЛ1 мhЦЅ€1џ›|џЃ‚ џЇ‡%џЋ‹+џЋŒ0џГWџытЩџъсЧџЛЌxџцмПџдЧ џВŸ_џЪИ~џЬКџЖЅjџеЩЂџчнРџОЏ~џъсШџытЩџР­rџЛЂUџН LџИ˜<џАŽ+џЈ„џН9џЇwOЙ*мhКЃ|,џ“sџœyџЇ†&џА’;џЗžQџЎ™SџЦЖƒџУДџаУ›џгХžџХЖ„џлЮІџнбЊџобЊџмЯЈџХЖ†џгЦŸџбФ›џХЖ…џЪМџИЄgџУЏnџПЅYџЗ˜=џЎ‹&џІџПŒ;џЈxOЌ!нži˜Љ}0џŠiџ•rџЊ‹-џТЈ`џдТџмЭЄџаТ–џеЦœџлЭЅџО­xџмЯІџргЌџргЌџргЌџргЌџлЮЄџПЏ{џлЭЄџжШџЯС•џнЯІџмЬ џЮИxџК›CџЊ†џЃ~џЧ‘Fџ˜mH‰нžidЙ†Aџ…dџnџЋ2џРІ]џбО…џлЬŸџкЪџЯМ…џСЌkџЅ?џЌ•JџЕžUџЗ ZџИЂ\џЙЃ]џГWџГœUџЦВvџвСŽџкЫžџнЮЃџйШ—џЪГoџЖ—=џІ‚џŸzџг˜XџtS7Wр jд˜^џ‚bџ‹jџŸ$џЂ…*џЃ†-џž'џŸ%џЅˆ+џВ”:џСЃNџЧЋZџЫБdџЮДjџЯЖmџаЗnџЯЖmџЮДjџРІYџДšIџ­‘@џЋ>џ­’AџА•AџА‘6џЂ}џЃ{џж™eы пŸjО–oџ„dџЃ†1џЋŽ7џБ”=џЖ˜CџЛžLџОЂQџОЂOџРЂNџУЇUџФЉWџЦЋZџЩЎ_џЪЏbџЫБeџЪАdџЪБgџЪБiџШЏeџУЉ]џПЃTџЛžKџА3џx џИ‡3џПˆZŸнžiUФMџ`џš}(џЏ•IџДšKџКŸRџНЂVџСЇ]џФЋcџШАjџЫГpџЭЖuџЯЙwџаКzџбК|џаК{џЯЙxџЭЖuџЫГpџШЏiџФЋcџСЇ]џНЃWџІ„џ™tџи›`џ}Y;6пŸjŘpџ„eџЏ˜SџИЂ]џМЅ`џСЉdџФЌhџЧАmџЩВqџЬЕuџЭЗxџЯЙ{џЯК}џЯК}џЯК}џЯЙ{џЭЗxџЬЕuџЩВpџЦАlџФ­iџЕ™Gџ–rџЙ‡7џЩ_ р jKж™`џ†d џ‘tџНЊqџС­qџФАtџЧГuџЪЕzџЬЗ|џЭЙ~џЯЛџаМƒџбН„џбН…џаНƒџаМ‚џЯЛџЭЙ~џЬЗ|џЪЕzџРЉcџ—rџЄyџоŸhџ‚]>оŸi|Ь“Vџ_џœ‚6џЧЗ‡џЩИ‡џЬЛ‡џЮН‰џаП‹џбРџвСŽџгТџдТџгТџдТџгТџвСŽџбРџаП‹џЪЗџ™xџ™qџй›aџЪ`]р jЩ‘Tџ„b џ™€4џЭП—џвХџдЦџеЧџжШžџзЩŸџиЪ џйЪ џиЪŸџйЪ џиЪ џзЩŸџжШžџЩЖ€џ—vџ›sџжš_џг—dyр j~г˜^џkџ‡kџНЌyџкаВџлбВџмбВџнвВџнгВџогВџогВџогВџнгВџиЬЈџА™Rџ‹jџЇ{(џнžfџе˜eeр jZр jУО‰Hџ‰gџŒr џБždџЭСšџлвЕџумХџфмХџзЫЉџШЙ‹џЉ‘Jџ‹lџšrџЮ”VџмhЂе˜e9р jlр jеЭ“WџЌ~6џ‘lџjџ€`џ…d џ‘lџ™qџЖ„=џе™_џпŸjОнžiUр j-р j~р jУр jЬр jір jър jЬр jЗр jlр jџџќј№рРР€€€€РРр№ј?ќџџџРџ(0` €%   (2;BGJJGB<3)  &8J\lx„††…xm]L:( '>Xo‚‘Ѕ0#Ж=+Н=+Н2$ЛЌЉЅ’„qZ@(  8Vs‹+Ћ€\=вДUыиšfќр jџпІqџоЈsџоЈsџпІqџр jџкœg§ЕVю~Z;л.!ПЋ ŽvX: 'Fj ‹wU8ЧУ‹\ёпЅpџнД‚џмР‘џлЪџлЬŸџлЬŸџлЬžџлЫџкЪ›џкЩ™џиЦ”џйМ‰џлБ{џоЅoџЪ`іxV9й ДЁ‹mI)-Pv‚]>ХрЁkџмА~џкУ“џкЫžџлЬ џлЬ џмЬŸџмЬŸџлЬžџмЬžџлЫџлЫœџлЪšџкЩ™џйЧ–џиЦ“џжУŽџжМ…џй­uџпЁkџ~Z<к­™yT/.UwU9ЎПˆZщм­yџйТ“џйЪœџкЪџкЫџлЫџлЪ›џкЪšџкЪšџкЪ™џлЩ™џлژџкژџлЩ—џкЩ—џйШ•џйЦ“џзХџжУŒџгР‡џгЙ~џйЉpџФŒ]єrR6д Y1+U”iFПоЄnџзМ‹џзЧ—џиؘџйШ™џиؘџйЧ–џиЧ•џиЧ“џиЦ’џйЧ’џйЦ’џйЧ’џйЧ’џкЧ’џкЧ’џкЧ’џйЧ‘џйЦ‘џиХџжФŒџеСˆџгОƒџаК}џЯВrџнЂjџ‰bAнЄƒX. %NЃtMЦнІqџдПџеХ”џжХ”џжХ’џжХ‘џжУŽџжУŒџеТ‹џеТ‰џжУŠџзУŠџзФŠџиФŒџиХџйЦџйЦŽџйЦŽџйЦŽџйХџиХŒџзУŠџеТˆџгПƒџбМџЮИwџЫБoџйЄiџ“iEсЄ€R( CЊzQХйЊuџбО‹џгТџдТŽџдСŒџгС‰џгП†џвОƒџвО‚џгОџдП‚џеРƒџеС…џзУ†џзУ‡џиФˆџйФŠџйХŠџйХ‹џйХ‹џйХ‹џиХŠџзУ‰џжТ‡џдРƒџвМ~џЯЙxџЫДqџШЏhџдЄdџ•kGсŸwG2ЊyPКйЇqџЯМ†џаОˆџбО‡џбН…џаМџаЛ~џЯК|џаКzџбКzџвМ{џгН}џеП€џжСџзСƒџзУ…џиУ‡џйФ‡џйФ‰џйХ‰џйХ‰џйХ‰џиФˆџиФ‡џзТ†џеП‚џгН~џаЙxџЭЖqџЩАiџХЊ`џгЂbџ’hEн–h7!ЇwOЁлЃmџЬЗџЭК‚џЮКџЮЙ~џЭИzџЭЗvџЭЖsџЭЖrџЮЖsџаИuџвЛxџгН{џеП~џжСџиТƒџиУ†џйФ‡џкХ‰џкЦŠџлЦ‹џкХŠџкХ‰џйФˆџиУ†џзТ„џжР‚џдО}џбКxџЮЖqџЪБiџЦЋ`џТЅUџжŸbџ‡a@е†S% „^>fоЁjџЪБvџЫЖ{џЫЗ{џЫЖxџЫДsџЪГpџЪВlџЪВkџЫГkџЭЕoџаИsџгЛwџдН{џжПџзС‚џйФ†џлЦˆџмШ‹џнШџнШџнЩŽџмШџмЧ‹џкЦŠџйФ‡џиТ…џжС‚џеО~џвЛxџЮЗqџЪБiџЦЌ`џСІVџПŸMџкŸdџaE.Мp; П‰[СЭЉmџЦВtџШГtџШВrџЧБmџЧЏiџЧЎfџШЎeџШЏeџЫВiџЮЕmџбИsџвМwџеП|џзСџкФ†џмЧŠџоЩŽџпЫ‘џрЬ’џрЬ“џрЬ“џпЫ’џоЪџнШџлЦŠџйФ†џзТƒџеП~џгМyџаЗrџЬВiџЦЌ_џТІTџНžHџСšIџГ€UщˆS#pJoйЁiџСЌkџХЎnџХЏlџХ­hџФЋcџФЋ_џФЊ]џЦЋ^џШЎaџЫВgџЯЖnџвКtџдНzџзР€џйФ…џмЧ‹џоЪџрЭ“џсЮ—џта™џуаšџтаšџсߘџрЮ•џпЫ’џнЩŽџлЦ‰џиУ„џжРџдНyџбЙtџЬГjџЧ­_џТЅTџМžGџЗ—;џг›ZџuS7Уj4Ь’`ЩЦЄdџРЉfџТЋgџТЊcџТЈ^џСІZџТЇXџУЇXџХЊZџШЎ`џЬВgџаЗoџгЛvџеП}џйУ„џмЧŠџпЫџсЮ–џуб›џхгžџцдЁџцеЁџцдЁџхгžџубœџсЯ—џрЬ’џнШџкХ‡џзСџдОzџбКsџЭГkџШ­^џТІSџМžGџЗ–9џЙ‘8џп iџ€EЃtMWе fџКЄ^џНІ`џНЄ\џЛЁVџЗžPџЖšIџГ˜GџГ™FџЖ›KџЙ RџОЅZџЩАhџгМwџзС€џлЦˆџоЪџсЮ–џфвœџцеЁџшзЅџщиЈџщйЉџщиЈџшзЅџцеЁџфвœџнЪ’џЯМџЩЕuџЦВoџФ­hџСЊcџСЈ_џОІWџН MџКœBџЕ•6џЏŒ)џЮ—QџiK2ВU# Э’aБФ]џИ WџМЃZџСЈcџЦАnџЫИ~џбСŽџзЩ џмаЎџогГџпеЖџогВџЪК†џЕŸ\џТ­iџЫЖxџЭК}џЯН„џвС‰џдУŽџжХ‘џзЦ”џзЧ•џзЦ”џжХ‘џеФџЪИџЦЖџодГџхнУџфлСџукПџтиКџнбЋџжХ’џЬЕtџСЄRџЖ–7џАŽ*џЙŽ4џИƒWуc- [A+о iџГ™PџЕœOџК TџУЋgџЮКџкЬŸџчоРџђюоџћњѕџ§§ћџљљѕџшцкџигПџибКџЮФŸџндИџцпЦџчрШџшсЫџщтЬџъуЮџъфЯџъфЯџъфЯџцпЩџдЫЊџеЭБџлзХџплЫџяэхџ§§ћџ§§ћџќћїџє№рџшнМџиЦџЧ­`џИ—:џБ,џЌˆ"џлžcџ'z4Т‹\Sа›`џЏ•HџВ˜HџЗœLџПЇ^џЫЖyџиؘџхкКџёыиџљїюџэыпџеаКџщцйџћљѕџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџ§ќљџѓёъџлзУџхтгџћњѕџњјђџѓэмџчмЙџиХŽџЦ­aџИ˜;џБ-џЌˆ"џЬ•MџyW9І:б•cŠУ–UџЋ@џА”@џГ—DџКŸRџУЋfџЮКџиШ›џсеВџтиНџЪП›џяыоџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџњјёџљїяџиаЖџйвЕџыфЭџцлМџнЮЁџбНџХЉZџЙ˜;џВ-џЌ‰"џОŽ:џЇwOЩ=иšfЎИJџЈŒ9џЋ8џЏ‘7џ­Ž4џЌ1џЋ‹0џЋ2џЋŽ5џЂ‡3џбХœџіђчџіђчџіђчџющкџркФџрйФџеЬ­џаУ›џкЭЈџлЯЊџмб­џнвАџмбЏџЮФŸџпйФџрйФџхпЬџѕ№хџіђчџіђчџђэоџЎ›[џЛЄ]џНЄZџНЄUџН MџКDџЗ—9џБ-џЌˆ"џД‰,џСŠ[п?мhаЌŠ=џЄ‡1џЈŠ0џЋ‹0џ­/џЏŽ/џБ1џЕ”6џИ˜<џЌ‘=џяъжџђэмџђэмџкаЏџШМ–џфнЧџфнШџоеКџП­pџкЩ•џмЬšџпЯŸџрбЂџдХ”џЯјџфнШџфнШџпзПџЦКŽџђэмџђэмџђэмџдЧ›џФ­fџЮЕjџЩЎ_џУІQџНžDџЗ–8џБ,џЋˆ!џЋ… џе˜eѓ>оŸiуЃƒ2џЁƒ*џЄ…(џЈˆ(џЊ‰(џЌ‹(џЏŽ,џГ’2џД”7џГ™OџюцбџюцбџюцбџОЌrџЭП‘џ№щеџ№щеџяшдџТАtџцеЁџшиЇџъкЋџьмЎџкژџнб­џ№щеџ№щеџяшгџЎœ\џчоУџюцбџюцбџлЮЈџРЉ`џЭГhџШЌ\џТЄOџМœBџЖ•6џАŽ*џЊ‡ џЇ‚џмhњ<пŸjюœ}(џœ}"џ  џЄƒ!џЇ…"џЊˆ$џ­‹(џБ.џГ“4џ­’CџърЦџърЦџърЦџЦЕџЩЙŠџьфЭџьфЭџщрЦџУАsџфвœџцеЁџшзЅџщиЈџйЩ–џиЫЂџьфЭџьфЭџърШџЏ`џшнТџърЦџърЦџеЦ™џРЈ^џЬВeџЦЊXџРЂKџК›?џД“3џЏŒ(џЉ†џЄ€џп iџ 9пŸjхšy#џ—wџœ{џ ~џЄџІƒџЉ‡!џЌŠ(џБ/џЄ‡.џиЩžџцлЛџцлЛџдЦ›џЮС›џщпФџщпФџЬП”џ­šWџСЎpџТАtџФВvџХВyџНЌpџИЇqџкЯЏџщпФџтиКџСГ‚џхкКџцлЛџцлЛџПЌmџТЊ_џХЊ\џСЅQџМŸFџЗ—;џГ‘/џ­Š%џЈ„џЃ~џр jџ0 пŸjй›v!џ“rџ—vџœzџЁ~џЄƒ!џЇ‡*џЉŒ3џ­‘>џЈŽ?џЌ–RџвТ•џЧЗ…џУЕˆџма­џцлМџжЪЅџХЕƒџтеБџтеБџтеБџтеБџтеБџтеБџйЬЃџТД‡џхкКџцлМџгЧЁџСВџЯП’џЩЙ‡џА›XџМІbџЛЄ[џК RџИ›FџЕ•8џБ+џЋˆ!џІ‚џЅџмhѕ( пŸjИЁy'џm џ’p џ™wџЇ†&џЕ™CџУЋdџаМƒџкЫџсеЏџиЫЅџЪН’џгЦžџрдАџузДџйЬІџОЏ}џйЪŸџпбЉџпбЉџпбЉџпбЉџпбЉџпбЉџпбЉџХЕ‚џаФ›џузДџузДџмЯЊџЮС—џаФ›џов­џтжВџнЮЂџдСˆџШАhџЛEџЏ)џЉ†џЄ€џЋџг—dтр j“Њ|/џ‡fџjџ”qџЃџГ•>џСЈ^џЮЙ}џиЧ–џпбЈџсг­џсг­џсг­џсг­џсгЌџЛЋwџЭНŠџнЮЃџнЮЃџнЮЃџнЮЃџнЮЃџнЮЃџнЮЃџнЮЃџмЭЁџМЋsџйЫЃџсг­џсг­џсг­џсг­џсг­џрвЋџлЪ›џвНџЦЌaџИ™@џ­Š$џЇƒџЂ~џЕ†,џШ_Мр j`ЛˆBџ„cџŠgџ‘oџЂ‚џВ•?џПЅ[џЬЖwџжФџнЭЂџпаЇџпаЇџпаЇџлЫŸџЩЕ{џЌ”FџА—LџДRџЖŸVџЗ YџИЂ\џЙЃ^џЙЃ_џЙЄ_џЙЃ_џИЂ]џЖ ZџТ­nџжХ•џпаЇџпаЇџпаЇџпаЇџоЯЅџйЧ•џЯЙ{џУЈ\џЕ–:џЊ†џЄ€џ {џРŒ<џМ†Y р jд˜^џaџ‡eџiџžџЃ„'џЈŠ0џЈ‹3џЇ‹3џІŠ4џЈ9џЋ>џЎ”DџЈ‹4џГ—BџСЅSџЩ­^џЬВfџЮЕjџаЗnџбЙrџвКtџгЛuџгЛvџгЛuџвКtџбЙrџЦЎdџЙЁUџЖŸUџИ YџЖžTџГ›OџВ™JџГšJџЕ™HџД™DџБ4џІ‚џЂ}џžy џв—VџœpJIр jЯ‘lџ„cџŠgџ~џЃƒ&џЇ‡*џЊ‹.џ­3џЏ‘8џА4џА1џА0џИ˜;џМCџРЂKџФЇSџЧЋZџЩЎ`џЬВeџЭГhџЮЕjџЯЕlџЯЖlџЯЕlџЮЕjџЭГhџЬВeџЩЎ`џФЉXџРЄRџПЃQџОЃSџПЃTџМ LџЙœFџЗ—?џА’5џЃџŸzџЂzџпŸiџ(р joДƒ<џaџ‡eџ›|!џЅˆ/џЊŒ2џЎ7џВ“;џЕ—@џИ›EџЛŸLџОЁOџО MџО JџО IџПЁHџСЄNџФЇSџЦЊXџШЌ\џЩЎ_џЪЏ`џЪЏaџЪЏ`џЩЎ_џЪЏaџЩЏaџЪАeџЫВjџЪВiџШЎdџХЊ]џТІXџПЃQџЛŸLџИšDџЏ1џ {џœw џЙˆ4џЮ“a“р j лeџˆf џƒcџ‘rџЈŒ:џЌ;џЏ“>џД—CџЗšGџЙKџМ PџПЄUџСЇZџФЊ^џЧ­dџЩБiџЩАhџЪВiџЫВkџЪАgџЬГjџЯЗsџЯЗsџбЛzџбЛyџаЙxџЮЗtџЭЖrџЬГnџЩБiџЧЎeџХЊ_џТЇ[џПЃTџМ PџЙJџЈ†"џx џ›u џй›`џЄuN)р j{Ж„>џ€`џ…eџІ‹=џЎ”GџВ—HџЕ›KџИžOџЛ SџНЃVџРІZџТЈ^џХЌcџЧЏhџЩАjџЪГnџЬЕrџЭЗuџЯИwџЯЙxџЯКzџаКzџаКzџЯЙxџЯИwџЭЗuџЬЕrџЫГoџЩАjџЧЎgџХЋbџУЉ_џРІZџОЄWџЗ›Hџy џ™tџК‡5џв–c“р jпŸiџŠgџaџ‘rџВšUџДUџИ VџЛЂYџОЅ\џРЇ_џТЊbџФЌeџЦЎhџШАlџЩВoџЫДrџЬЖtџЭЗwџЮИyџЯЙzџЯК{џаК{џЯК{џЯЙzџЮИyџЭЗwџЬЖtџЫДrџЩВoџШАlџЦЎhџФЌeџТЊbџРЇ_џЈ‡'џ™tџ›u џмžeџГ€Uр jrФŽMџ}_џ‚bџЃŠ>џИЃcџКЄbџНІcџРЉfџТЋhџФЎlџЦЏnџЧБpџЩГrџЪЕuџЬЖwџЭЗyџЮИ{џЮЙ|џЯК}џЯКџаЛџЯК~џЯК~џЯК}џЮЙ{џЭЗzџЬЖwџЪЕtџЩГrџЧБpџЦЏmџФЎlџЕšHџ˜sџ”oџТŒBџзšfƒр j–Ў7џ~_џ„dџВ\џОЊpџРЌpџТЎqџХАrџЦВtџЩДwџЪЕyџЫЗzџЬИ|џЭЙ}џЮКџЯЛџЯМ‚џаМƒџаМƒџаНƒџаМƒџаМƒџЯМ‚џЯЛџЮКџЭЙ}џЬИ|џЫЗzџЪЕxџЩДwџОЇaџšv џ“oџБ-џкœgšр jр jЅžt%џ~_џˆj џМЉrџФВ~џЦД~џЧЕ~џЩЗџЫИџЬКƒџЮЛ„џЯМ„џЯН‡џаОˆџбП‰џбП‰џвРŠџвРŠџвР‹џвРŠџвРŠџбП‰џбП‰џаН‡џЯН‡џЯМ…џЮЛ„џЭК„џФЎoџ™v џ‘mџЄyџпŸiџе˜e,р j<мžfџ’mџ}_џ‹mџО­xџЪЛџЫЛŒџЬНŒџЮОŒџЯПџбРџбСџгТ‘џгУ‘џдФ“џдУ“џеФ“џеФ“џеФ”џеФ“џеФ“џдУ“џдФ“џгУ‘џгТ‘џбСџбРŽџХВvџ˜wџlџ›sџлdџнžiRр jWнžhџЁv)џ|^џ…g џМЋuџаУ›џбУ›џвФ›џгХ›џдЦ›џеЧœџжШџзШџзШžџиЩžџиЩŸџиЩžџиЩžџиЪŸџиЩŸџиЩžџзШžџзШџжШџеЧœџНЇdџ‘oџiџІz#џнžfџоŸijр j3р jœДƒ=џ|^џ`џЉ“QџгЧЄџжЪЈџзЫЈџиЬЈџиЭЈџйЭЈџкЭЈџкЮЈџкЮЉџлЮЉџлЯЉџлЯЉџлЯЉџлЮЉџкЮЉџкЮЈџкЭЈџбТ–џЊ@џŒiџŠgџВ3џпŸjЌмhCр jр j“Ъ‘Tџ’mџ|^џŠmџИІoџзЬЌџмвЕџнгЖџнгЕџнгЕџогЕџодЕџодЕџодЕџодЕџодЕџодЕџодЕџиЬЈџБ™Sџkџˆfџ˜pџЩ‘Pџр j–р jр jWр jРСŒKџŠgџ|^џ‚cџŸ‡>џУГ„џзЭ­џткТџткТџткСџукТџукТџукТџйЮ­џМЉpџЁ†7џ†eџ…dџ‘lџР‹Fџр jЬр jcр jlр jеЦPџЉ|2џ‡fџ|^џ~_џ`џŽsџ•z)џ–{)џŽqџ‚bџ‚bџ‚bџŒh џЋ}/џЦMџр jлр jrр j?р j‡р jоб–[џЛˆEџЗ…@џЈ{/џЃx*џЄx*џЈ{.џИ†@џМˆCџб–Zџр jср jр jEр j$р jZр jfр jр j™р j™р jр jfр j]р j'џџџџџџџјџџџџрџџџџРџџџџџџџўџџќ?џџјџџјџџ№џџрџџрџџРџџРџџРџџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџ€џџРџџРџџРџџрџџрџџ№џџј?џџјџџќџџџўџџџџџџџџ€џџџџрџџџџјџџџџўџџџџџџРџџџџmysql-connector-c++-1.1.7/win/Bitmaps/New.ico000644 015771 000012 00000000476 12645244437 021414 0ustar00pb2userwheel000000 000000 (( €€€€€€€€€€РРР€€€џџџџџџџџџџџџЛЛЛЛАЛЛЛЛАЛЛЛЛАЛЛЛЛАЛЛЛЛАЛЛЛЛА ЛАџџ€€€€€ € €€РзсЋџ}џяџџџяџџmysql-connector-c++-1.1.7/win/Bitmaps/Up.ico000644 015771 000012 00000000476 12645244437 021247 0ustar00pb2userwheel000000 000000 (( €€€€€€€€€€РРР€€€џџџџџџџџџџџџЛЛЛЛЛЛАЛЛЛЛЛЛАЛЛЛАЛЛ ЛЛЛАЛЛ ЛЛЛАЛ ЛЛАЛАЛЛЛАЛЛ ЛЛЛАЛЛЛЛЛЛА ЛЛџџ€€€€€€€€€€€Ррџџџџџmysql-connector-c++-1.1.7/win/Bitmaps/bannrbmp.bmp000644 015771 000012 00000247610 12645244437 022471 0ustar00pb2userwheel000000 000000 BMˆO6(э:RO  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsМЉpЛЈoКЈmЙЅkЗЄgЕЂeЖЁcЕ bГŸ^Г\Б›ZЏ™WА™UЎ—SЌ–O­”N­“MЊ‘IЉHЈEІCЄŒ@Ѕ‹?Ѓ‰<Ђˆ;Ё‡:Ÿ†6Ÿ„4žƒ2Ÿƒ/-œ€,›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsМЉpЛЈoКЈmЙЅkЗЄgЕЂeЖЁcЕ bГŸ^Г\Б›ZЏ™WА™UЎ—SЌ–O­”N­“MЊ‘IЉHЈEІCЄŒ@Ѕ‹?Ѓ‰<Ђˆ;Ё‡:Ÿ†6Ÿ„4žƒ2Ÿƒ/-œ€,›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsЛЇnЛЇnЛЇpЗІnГЂiЕЂiЗЁgЖžbЖ]Еœ\ГšZБ˜XА˜VЌ—SІ”MЅ“LЈŽLІŒIЄŠGЃ‰CЃ‹CЄB Œ?‰<Ѕ…<†;™‡:ƒ7Ѕ3Ј‚0žƒ,“„(›},š|+™{*˜z'–y$“w ’w’w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsС­vЛЇpИЅlЙЅkЙЄgЙЂdИЂaИŸ_Гž`­›\Љ—VЄ“PЁLž‡Iž‚Fœ}FŽ|A}B}@’~=–;™9Ÿ‚8Єƒ:Є†9Ё…8›„4„4žƒ2ž€/ž€- ‚/›}*š|)˜z'—z%–z#•y"–x–y”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsЖЄoЛЇpОЋnЛІhЙЃbКЄbИЂaВ›]Ѕ•ZŒT—„Q|M‰tGnA|k:ud1n^4n]2p]0t`0xc/{g.€l2‡r5‹v+”€3—€2›€0Ђ1Ђ1 ‚1—|,œ*›~)™|'—{$–z#•z –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsО­uКЇnИЅhКЅgИЃeАœbЇ“\žŒW”R‡sD{g8m]/`Q*UJ*ME.C=*MB"M@ P?S@UCYG"]N'_S+n`&zh-€l+Žx1—3˜}-ž€/Ђ‚/š~)™~'˜}&—|"—|"–{!•w“u”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsЛЈoНЊqЛЈoЖЃjЋ›fžŽ_‹~R|pHe]5YR+MI&IB!J?^J'vY2‚`5|X4wZ5gT/MD9640 ;5C:?@VJ"kP${\'†k+Šu*“}+–}'™})™}(˜}&—|"–{!–{!—y"•w ”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsОЊqКЇnБŸjЂ“b”„Y‚qJm[6aN+cG)}Z8ЅxRЪ“hлŸqтЈwуЎ|с­~пБпЎ~сЈ{пЃyж›sМ‰a‘hAmM$C.C1G9SCgNz^!…o'ˆy*–{+—|+™}(–|"•z •z —y •w ”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsНЉrЏŸjЁ‘b€Uwd>iO*z]6›zSдЅmзАyоПŒнЩ™лЬžиЫкЫлЫиЫ“иЭ”жЭ”жЪ”кХ‘пОŒпБлЅvЩ’g…a9I>45?:WGoUƒe*Žq'“w*–{*–{$•z ”y–x”v”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊs­hЂ“bˆxMsb;~gAЄ†]ЯІyшК‹дШ зЩŸкЩžмЩœмЪ›мЫšиЪ™иЪ™зШšиШšйטкЦ–лЦ“зЦŽвФŠЮТˆзП}лВ{бšsfFH955G@eMd‹n$’w'–z%—|"–{!–x”v”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЬВ„ОЕƒСГЩБ}ПЏzМЎyРЉwДmІexGqe; xUвЄtеП‹вЪ›лЫ–нЩ™сЫ›лФžиХŸлЪ‘рЧлУ•еШ”зРšиЧвС‚кЦкХ’дУ‹гШŒЭУ‡еСˆЭР|гН{дЋlгЂjŒj/B*@:WOq`!‡j •w&–z#y!˜vŒ{”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ХЕ†ХБСГСЕТ­yТЉwЕЄs—’aƒpO›wGзŸnлВиЫ“лФ—нПœаЫšдУйХŽеХŠЛГxДЋrМЋrЫЗ~вР‹йТŠЙЇrТЕ­ЄkНЏuжУŠдПˆеР‰ЯЛзСгД‡гЕ~жАyЮЄoŽhJH4>8 ^Gw]!ƒj •v!‘zzšs”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ОЗ…ЫД„УВНВ~Ф­{НІvŸ•eƒ|KЁxQйЂoмД€зЩ•ЯРˆфЪ›лУ•иТˆдФгЛ…ЧГ|кбЌќѓцџѕеАЁcеУ‚ЩЖkйХІџњћџџѓЩМЯЙмО‡иЗ‰ЪИ{вСxаЗ…ЭЙxЭГqв­qЬІl—wBcH&D2 \It[„o{ ”ys ”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡МЕƒХЖ…ФА€ФЎ~ПЋ{Ѓ™i”„UЄSи oдН…аЦ—ЯПеУ„аМ{ФЌvКІmУГqгПxАžcіынќѓџџўўЭУ›ЗЉoЖЈmіядџџўўўђЪИФВqЯМqЖЉ]Ю˘ЉЁfКБnаНrгЙsЪЏoЪЌeЮЊ^ЮžtjT+G6cNu`‡m—t•w ”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЦЕ„ПД‚ТБ€ЦЏБЂq™ˆW­†YиЃxгНЫО†аМŒдЙ†ЮЛwЎЂhобБ№ывБЁfРВ_ГЈ^№юајў§љћќђьсфкТрмПџџјђј§џџћЬЦ›ИЏkКЏuчоМџ§ўјюмЙЎrЬВoаДtЩГrЧ­kЫЋ`Э \гЄnnQ%L<jNŠi#‰o‘x”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЮД…ПД‚РД„ЗЉyЅ”cЕ‹\дžoоЙ…ЫК‡жНзП…ЫГ}СЇqпгБћ§їјќ§іфгСВ„пдЈў§щђќ№ќџћџ§ќў§ѓ§љўј§ћјџќќљћџњјђтерзЪџў§яћ§џљіПЋrЩГqЪЙpЧВgЦ­gСЋcЩЉPЯUгЁlgHO=pZ ‚h‘x”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЫГ…УГ„КГ‚ЌžmЏ^аŸmкГ|ЧИzнЗ}ЫМwУГqЭАwЙЅkУБŒџќєяњј§їќџќќџѕѕўљћќќќџњїџќїѕќѕџџ№ѕљюњћљўќќџљєџ§ђџ§ѕїјііџћєчзЕ bвМtУЕiИЅbУЎ]УЌ^ХЊSТЂOЫšVšn9G7VI}c‰m”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ХГ„РВ‚ДЊz­–fП‘bЭЉsХИzСИuХГxУЋiВšXПЈ\ЩАTЎ”Nџїміќїюўэѓїјњљћљњі§јїџїѓўјѓђіћ§іѓџљњњіѕњќ№њўђѕіђћљљњљѕјѓєјюжНЋlРЅbПЈpтЬЈБŸRШ XМІXКLǘIТŸ_Šl=K; eVŠk”u“t’s‘rqppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ХД‰КАЎЂ~Р’bбЅeЦГoЦЕlШЎxЧЁ`МВvэхЧСБ‚ŸKйаЎієь§ћѓѓјяіњюћћэњјюўїєџїїїђяўћѓўњљљєёћѕюџњё§ћёњј№іјђєјѓќѕјќєєљђсмкМѕјшіњѕчсФЇ•NФЈQЕЂ?КœCК”<м`gG#XI|`‹m”s•t“sqqqoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЦД…СА}Ћ™pбŸkШЊiЫБoМ­dУЊlДЁdјяхѓїђ§єъџ№хџїъўћїљђяћјѓ§љјїђёќљёњјэјјъ§ћѓієѓђѓщњћёћњ№їѕэљѕ№њѕђљєѓћѕієљ№ѕїёјіы§ћщїіђјѕїјэЯА™NТЁ\С JГ›AД‘7Ц•E”r=J@p\‡jr”s“sqqpoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЩДНЌtК”dбЄkОЈfХЋiПЋ^ОЇ\Є•Lщуа№њэњ§юќѕђѕѕщјћьќїюќѓяљђяњѕђјіюљќэђѕцљњёїѓђљћяіїэѕіэіі№јѕ№јєяћђюќѓяёїцѕјяќњђїёъњєѕј№щНЊ}ТЅJФЂ\ЫЃK­•5З4В+ЭЃ\]J^M€eŒo”r“sqŒpp‘oŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЪГ…ЕЈpк lСЅeОЃ`ЗЃ\ЧЈYЛЇPО›EЉ—\ѓьйњїщјѕчєѓяѓєъјѓъљђщќљыљјъђђціђэњѓ№ћѓьќєчјђчїђщјіьјіюїіьјіыћјъњѕцџљьѕяшј№щ§ёыџїяёцаЇ•ZЭАNНЁLЙ™@ЛŸ:Л‘0Ќ…"У<ŸtCZEx`‰l’s“rqŒpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡УВ‡Б mзœdД›UПЃ\ЙЂVОœPБ›IРš: Š<љцбљыьћєыѕ№эјіьќњтїішѕєцєѓхўјэљ№чџїщыоФчлЗцйПщнХђщењѓтїєхєѓхіѕчѕєцњ№цљђщљєыўѕыљѓцјѓоЫР”­•SИІeЌ^Ќ0Г‘-Љ†$А„%н `[Bs[…jr”sqŽoppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡М­СŸqТšYМœQИЃRГ•HЋ”VВŸbЏ›ZЦЖ‹ћєлі№ыїёъѕёпњёчјёнђђцєёщїюхјылпвВОБ…ЬОгХ‘вФ”гЦšЧЛ“ЫР ъуЪљђсёяхђяъі№хѓѓхёєхёяфяэхэ№чїєцџёоњђсщхЩЁ„:Б˜0Љ+ЂƒЮ—F~]/kVgr”s’qŽopnŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ОЌwб pВ—M˘HГ—BЉCпжЋўёзїюрњюьіђч№эхђьчї№сљьъљыёѕ№чїюрѕчаСГ‰ЬН…фж›эрЈълЊэтАюрЏєхДфдІЭ͘нвЖїёоє№хѕђуёєфюяпїёцљєыщэтёђщіычяээќёеЛžYЎ+Ќ'Є„ ИŒ3Њ{GfS}dŒo”s’qppnŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡Х­qб˜d­’BĘCО—B•‡;ђэд№ышю№нђёмяьођёнѓёйї№міђкёьуїэуѓшЬКЏ{аУък˜чжžчжЋылЖысЙ№уЗіфЕќщЖянЎеЧиЯ­іђеіяряэлјётњъоњылјємѓёйљяньяпЮЙ‚Ћ‹?Н“0ВŒ&Џƒ$Ѕƒ&д–ZaOzc‹n“r’qppnŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ХЂvУ›PДŽ<Љ’DІ”7Ј‹0М dъсМђьйі№нєэмѓьлєэмѓьлєэмѓьлћэкРВ‚гТфЪŽыбЃшвЉъмЌьсЏэоЗѓчПђцО№фМютИшлЏаС“№рБѕэмђънђьсѓэтэыйє№нђюлєэмИЈmŘCС–?Е“5ЇŽ&ЄˆЂ~в ^uVz`Šo‘q”po’roŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЯЂvН”EАŒ4ЇŒ<Ћ‘7Б‘.Њ‹.”…)црЭ№ъзѓэкѓэкђыкёъйѓьлѓьлчиИОА|лШ…цЮ”шаЂшеЈщлЋэпЏясЗ№тИяуЙ№фКьоДюоГмЬžаР‘ђызєьлђънёыояый№ьйёыиђыкРЏpВœDИ–9И•.В'Ћ‚ЏЮ“Ma(~a‹p‘q’po‘qŒnŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ж qЗ@Ѕƒ/Ѕ‡6Ў1ЌŒ(І,Ÿ{/чтЭяъе№ъзящж№ъз№ъзёыиящжаПŽХГxпЪŒхЭ—сЭциЄшйЈьлАяпДьпГюсЕ№уЗшлЏьнЏшиЉЧЖ…чрХђызючж№щиюъзяъеящжђъйсгЃЗЋiЋ•NЅ†+В%­ƒЋ|Ы‘Fl4c‹p‘r’p’qpoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡нЄpЋ†6€%Їˆ+œ‚˜‡ Ѕ‘CЬГsючгёъжючгэцвяшдяшдяшеэцгТАoаНzрЩ‹пЩ•мЬ—узциЃыи­ыл­эоАэоАьнЏын­чиЇъйІбПŠигДёъЯэцвэшгяыгэщбяшдёщиђшж№ьгѕчЫЕ›XІ‰ Ї‰Ÿ~Р?˜v;c‹p‘r’p“rpŽpŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡д dЂ…*›ƒŸz&”q-мЩžєшжэфжыхЮюшбэчаюшбюшбъуЯьхбэцвКІ_йУ|оХ‡мЧмЭ•пд–хжžъдЊъйЈълЊъкЋчзЈьнЌчжЃфвгПˆбЫЈёщЬяшЯэчающаьчЮяцвюфвьукхтгєцгА™[‚Ѓ‰Ђ„КŒ8žy?‚cq’sp”sopŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡лЉo›}$•|ž~‘uиЫ“ьшЯтфаэцЭючЮьхЬэцЭюцЯьфЭэхЮюцЯЙЃaдОwлУпЧпЬ“нб‘уг˜щгЃшеЂчжЃъйІхдЁцеЂцдŸфб˜аМƒгЪЈюцЩяхЭэхЮэцЭэцЭ№хЯюуЯђхЫщпАйХŒЅ‰5ЉŠ#Іƒ yУ:Ÿz>…fŽrsp’qonŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡дŸlŸy+–v›{”wЛЂXжТ™№оПщтЧэцЭъуЪщтЩыфЫьхЬьхЬътЫУЏuШВpкР}оХ‡нЧнЬрЮ‘уЮšта›хгžцдŸфвпݘуа—уЯ•ЫЕ{нвВюуЧьсЫэтЬыфЫэфЩяхЭятЬЭНˆ ‹:Ј…/Љ‡#Ћˆ Є}Њ}ЧAžv;‰httoponŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡пЄvЅy,‘o •tšw —s’rw мгИщрХюхЪьтЪърШърШьтЪърШеРТЌkзОxлПйС…мЪ‹мЪпЬ“рЬ•уߘмЪ•сЯšоЭ•пЬ“лЧПЊmшнПяфЩьпЩьсЫысЩытЧытЧьпЩПВnЉŒ1Л2­†#Є‡Ѕ‚ЄwЧŽIœt9‹jttop‘q‘oŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЮЎsБ‚1—h Žo›xšƒ'Ў‡•~ШМ’№тОясФэсХшоРьфЦътФчпТюкЗЏbЧЖeоШvдИwнФŒжФ‰дЬ†йЫ‰мЩтЪ–пФ‹уЬˆмШЩЖyдПŒытЧыоФюрФырТъуТчтСшнСђтЫиЫŸЊQ­”DРGВŒ,Ѓ|Ёvв”Xop’r‘r‘t“s‘qŽmŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡Э­xН‡@eŠgБ˜BЖЁLЖ™OРЎsчтУыфЩэхЮткУшсЦшрТфмПьсЦюлЦаП”ЖЅbЪГhнР}иКиО‚еС€оХ‡кП†тФоТ…нШ„ШЖwИІwэйКхнРъпФыоФъсЦснСупЦящвщоЪюцеєщЩбПŠОЅ_ОžKž~œv зž`lp’r‘r‘s’r‘qoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЬАеœ_‡cˆeЌœPДžVеТ—яфжьщдюъищхгэщжъцЭчсФшнТъоЦфйУцлЕШКЛЊaЮЗiгЙmеМtлТzйНvоФ~иОxйФyПБeВЈhкЮЄщмТшрУцнТырЪшсЮычдыъжчфЯѓэжъцляфмЬИˣkЙPš}Ї€Ю–UŒlp“s’sr‘q‘q‘pŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЫЗˆгŸj•i †fЊ˜KЖŸaгУžьчо№щађызъфбђэиычЯёьгіыеђфвьщЭыфУёхЛгУŽАž]ЙІbЪЕqЪДrбМxЩГqХБpКЉjСЖxскЈюшУщтЩьчЮёщвёшд№шзьчиёыи№щЮодВшпЙълСКЌxФЏkЛF•qО7МCp‘s“s’srppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡УГ„ЯЊvГ|7bЉ8К dХВплИфгЌнЮ­єщЭёъб№ъгяыг№щжёцияыгёщиєчйїчжїцЫщйЕзШЁаСšШЛйЪЃоЯЎъмРїъаєщг№цдячжэщжѓьи№ще№щжючдёчЯчйЕХГ„СБvУБ|ОЌkЭГgЌŽ)ŸwШ“PЈt1’t’t“t‘rq‘qpoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ФЖ†ЫГ}ХŒX}^{ЦЌjЛЉjЖЋmСЌuЛЉzоЯЎѓщбєэйюшеючжёълђэдючдьтиђчпђщмяхгђывєэвѓ№быцЭяшеёшк№чк№чйяшеѓьиьцйьцгящвяшдѓьйєшаоЬЇЧБЮКƒШЖ{ЬК{ЯЖf“u šrЧ›\n“u’t’sqq“s‘qoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЗ‰ХД{йЌs˜n!aМЁWУВyЩГrШЖwРЏ~гФЃёцвяшзяыйяыи№ъзющаёьгѓязьщдюъзђьйэшгђье№ьг№ьгђюжэшг№ъзѕям№ъг№ыв№цмѓьйёьгєякычеяшеђчЩЭН“ЮКŠЦЕ|ЯК}Б–?–s ОAЎ„?y“v’u’sqq’q‘qpŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ФА‡ЧЙбЏmТŽL|a”{+ЛЎ‚бГ|ЧИyЩЛ‹ѓшЪєьлящмюъиёьзёэеђчпёъйёэдюэгящж№шлєшоѓчнёчнѓъм№ъзђэиђыкэцз№чкѓънїщнђще№ывюэищщлыъмяшдхлНЭЙ‚гС†ЩАp“uЂtн ^Ÿq$“w’u’u“t‘rp‘ppoŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡УИ†ФДЬАzеЎp•o}aДŸTЪЗŒФИ‚сдДїяияъеђэо№ънђюмяыиюъиѓъміынђщлюъзёэкѓьлѓъмѓьлёыиђыиєэй№ъзёъй№ымящмєъй№ънэъеыфУовКіърїыйгХ›ЦН’лРŽЇ&™mРŽBГ‰B’t—y"”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЦЕ„УЕЧГƒЪЉwЧZ†a €eЩЗvЫЛ—ЦП”чпТѓшдмвАЭФŸэхЮёэлѓянёъйѓшкѕьоѓянюькюъиєынђюмєэмєюлѓэкёыиђыкѓьл№ымѓщпѓянупУЭСжШžЪӘеЮЃгХ›йХ•ГœFŽjЏ|&Ц”R›t)—z’v”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЭЖ†СВРГ‡Ц­ƒеЋvД‡>~[—'ЭЙ–ЭС™ЭЧœЭУ›жУеУšжЬЊђюляыйєэміюнѓьляьнюымёьнї№сяьнђэођэоёэлѕюнѕямєюлєэк№шсё№мхрПзЩŸкЧšйЭжЪšгФ“ФЇ\sšs ݘUАƒ?•v!”y–{”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЮЖˆУГ„ИЎСЎƒЯ­вІiЄy*€[™9еУ”бЩЁЮЦ—лЩ оЫІмбБє№нє№оі№ніялђьйѓ№сяюр№эоєэмёюп№эо№эођэоїѓсєюл№ъгёъбѕђжёюрєьпзЪЊсЯІйШЁсЬŸФЌp“p ’kФ“EРŽL{"”y‘s –{”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ФВƒУДƒЧЙ…НЏ{ПЈvЮЌwгЇhЂo&bЃŠ@лЩЄйЮАвЩлаЊяубђэојђпхпШмеМтлЧєярєёуѓ№сїёоіђпє№оіётѕятѕюптлЧзаЗзЯВєыаїђущфеиЭВтаБтЬЈЪБs†j ’hК‰;СŽOŸx)—|•{!‘s ”x”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡УЖ‚ЧЕ†УА}ТДzХЖ~РЉwЫЃrбЁgsa‹u.жХšргГиЭБибИщфЯэцвлдЙгЫ­ибИюъиѕёцѕ№сыцбожПрйХ№щијѓфљђстлЧлвЗмгВлаЕнзРзбКтгГуЯŸАT~e”oЛŒ;ПLЂz/˜{ •z ™|'–x–v”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ХКТ„ѡХЖ~Л­sЦА€ХЉzЧЇrгЇjЁx/ƒbˆmаЙŒрбАнзВндЙлгМмдЖукИткНяшзљѓцї№пслФреЙсзПђшжљђујёрцоЧткНукИумЕтйОфгИцۘœƒ'‚kjЪ”GМ•G z2—y&”{–{$”u ›|!”t”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЙ~ТБ†СА‰НЏ{УВyПЊwОЊzЛ­sЪЄtвЅhН‹?†_t_œPдШІцйПфкТфлКщрЛуйЛчрЭюцй№щискСьпПхйНырЬътбыувриСулНцнЛуиТпеГ­[Šm Žfšjвœ[ЩŽH#™{,”z.”~&”{™{"—v šx”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsНЉoУЇkЮЇiЧ—U s*|V|bГЃJфвЛьрШунЦпоЩсрЫпнХуоХщрХъмЩчнЫхпЬтоЬрмЩфоЧщоУшкОРЈf‡p…g–jК:ж›iИŒMŸ€+›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsИЋsЙЈoПЇkЦЅfЫЃbС—P•l#€V wbˆ6ЧВ{шгЗюнащнгътбцпЫяхЭщрЬцпЮцрЭтйИЭМ‰ЅŽCeŠa …\­€/аЃZО’RІ: ƒ2™„(›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsГЅpЕЇrИЉqИЄjОЂeЬЇiЬ_Ц‘Rv'†byZza€k˜ƒ1АTЈ•RА–Z­“QЇˆ=–t „b^ˆfŽlЙ„4аœUР“PЋ‡AЂ‡6–€(—)™/›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsФЌxЛІoЖЂkЗІmЗЃiЙЁeРЁdТžbеЁeиЂeФNА~6Ѓu'ha~a~c€dˆi’pЂz(ЙˆBЬ–Zд›gО’S­†BЄ„8 ‡1š…*ž†.Ё‚3ž{1›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsКІmПЈpОЈnНЇmИЅhВŸbВ cВЁbВ›cИ›bΘaЧšaЯcжŸfлЂkкЁjсЁgрŸhн hеœeЩ—]Н’SБGЈ‡> ˆ<Ђˆ;Є‰8 ‚3Ђ‚7Ђ‚7›z+ €-›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsДЊnКЌqКЈkКЂfМЄhЗЂdГЁbЏž_АZЕ \В›WБ—TДšXЏ—UЇ‘PЇ’TŸ’TЁNІHЊDЉŽ>ЃŒ>Ÿ‹>š‡< 6 ˆ6Ђ„7Є8Ђ52š‚0—‚-›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsЖЋqЗЉoИЈmЗЃiМЇjКЂfИ dЗ bЎ ^ЉœXЎŸZЎžYЈ•QЋ•S­—VЉ“RА‘LЉIІIЁGŸCЂBІŒ@Ј‰>Ёˆ8Ё…8Ђ„5Ѓ†5Ÿƒ/„.…3”{+›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўў§ўќќ§ћ§ћњ§ћњќњљћњіњљѕћјєњїђљіёјіюїѕэієьієъѕѓщєђшђ№цёяфђюуёюр№эпюынэъмэшйьчиыцзьхдъувщтбчсЮчрЭхоЪфнЩфмХумУскСтиРрзМпжЛпдЙнвЖмвДмбГкЯЏиЭ­зЭЋеЫЉеЩЇгЧЃдЦЂвХŸаУЯУ›ЯС—ЮР–ЬО”ЬМ‘ЫМŽЪКŒШИ‰ЦЖ‡ЧЖ…ХДƒУВСА}ТА{РЎyРЌuОЊsРЈrЛІoНЉrЖЃjЕЃhД fЕ cЕaЖ ^Дž]А™[А—YБ˜X˜RА–JА—GЏ•H­“GЋFЊŽGЇŠEЈŠCІ‰>Єˆ; ‡?ž‡9Ÿ‰7›†1›ƒ1ž‚.ž*Ѓ„)›}*š|)™|'—z%–z#—y –x•w”u“t’s‘rqpppŽnmmmysql-connector-c++-1.1.7/win/Bitmaps/dlgbmp.bmp000644 015771 000012 00001605770 12645244437 022145 0ustar00pb2userwheel000000 000000 BMј 6(э8Т   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўџџџ§ќўџўџџџџџџџџџџџџџџџџџџџџџџџџџќўџџўџџўџ§ќўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ§ўџўџћ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњњњ§§§џџџџџџџџџ§§§ўўў§џќ§џќ§џќ§џќ§џќ§џќ§џќ§џќўџ§џџўџџўџџўџў§џ§ќџџћџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћ§ўџўџћ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџџќќќџџџџџџ§§§§§§ўўўџџџќ§џќ§џќ§џќ§џќ§џќ§џќ§џќ§џџ§џўћ§џќўџўџџўџџўџџўџџ§џўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџћ§ўџўџћ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў§§§џџџџџџ§§§ќќќџџџџџўџџўџўџџўџџўџџўџџўџџўџџўџџўџџџџўўўўўўўўўўўўџўџџўџ§ќўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџћќ§џўџћ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў§§§џџџќќќќќќџџўџџў§ўќќ§ћџџљџџљџџљџџљџџљџџљџџљџџљ§џїўџј§џљћџљљ§їњўјњџњњџњўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџћќ§џўџћ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџўўџџџўќќџўўџџў§ћњў§љџџќњўџњўџњўџњўџњўџњўџњўџњўџўќћџў§ўўўџџџџўџ§џџћ§ўћ§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџўњќ§џ§ўњ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§њќўќќџ§§џџўўќћў§љџџќќћїџќ§џќ§џќ§џќ§џќ§џќ§џќ§џќ§џќќџќќџљљџћќџўџџќўџњќџўџ§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§џўњќ§џ§ўњ­“Pџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќџќўўќќџ§§џў§ќњљџџќћњірплшпЫшпЫшпЫшпЫшпЫшпЫшпЫшпЫцрЩшсЭфпЪфоЫфрЭтоЬыщзџџюќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќџўњќ§џ§ўњЌ’Oџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ўќ§ўќ§ўќ§ўќ§ўќ§ўќ§ўќ§ўќџ§ўєџєћўџўњљўўўџ§ѕџњџјћљџџќ§ќјўџ§њ§ћўџ§џџў§љјџў§џјџќџ§їџјџўўќљћјџќјўљџџњ§§§ўћ§џќћўўјњџћѕќџіљ§ўџ§ќ§џќњњћџџћўќјџћєџѕћџўšq ŠkŒiiee‘gŽf’j‰k‹hb“hŒe‹g‹e—nД—RнЦІџњѓќўџѓњџџќ§џ§ѓћџљљўќњџ§љўќј§ћј§ћљўќљўќј§ћџ§§џќ§џћќџќћџћќџћќџќўџ§џџўіџџћџ§§џћќџ§ўџћќћњќќ§џџљќџџџњћљљў§іћќљќџў§џџќћ№љќџўџўќќђўјіџљџњњџљџјљџ§ќџџџѕ§џћћ§§џ§јћћћћўџџ§ѓ§ўќњўљѕќїєџњѕџљїќћџўџџћџћ§§ћ§§ћ§§ћ§§ћ§§ћ§§ћ§§ћ§§іќџљўќќџі§ўњџџўџ§њџќїџ§ќўўўџјџџќџџџљі§іџћџџњџџўњ§ўќ§ўќ§ўќ§ўќ§ўќ§ўќ§ўќ§ўќўўј§ќўќ§љЌ’Oџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћџњћћџљњљ§џџќіљ§§џќ§јџљџў§ћћўќћўџ§§ўњќ§љ§ћњўќћўќќџ§џєјљћ§§џњ§џќџњќ§јќ§џњџќћ§§ќџџќџџ§§ќ§ћ§џљџџіўџєџџћџ§њ§њќџњћ§њќ§њќњљ§•n hd‘g“if‘fea…eŒg’hŽgŠfŽki“l‹kƒe œ‚@ћ№аѕћњћџџџџќ№ѕўџћќџќ§џќ§џћќџћќџќ§џќ§џћќћџљњўјљ§їќўј§џљўџњћџњњўљљћћј§ќљџ§јџњјќі§џљџџќўќћџўћџќїџџљџџћўћїџћјџ§љџџћљўџџњћџ§ќўўўњџўќџ§ўўјћџєџњџџњџјїћџџњ§ќјћўџіњџ§џќџј§џ§џџ§ќџ§јџџњўўјћќјњ§ћўќќўќќўќќўќќўќќўќќўќќўќќњўљћџњјўљј§ћјћљњўљљў§іџџ§џљџџўљ§їџјјћџћџ§џљ§ї§ўєќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћўўј§ќўќ§љЌ’Oџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћџ§§њћїџ§ќџќѕќќќњќіџ§њў§ѓќўџўўўћќњў§љ§ќјў§љџџўјњњћќѓћџџїўї§џѓўќћљќњ§џќџњ§ќџєњ§єћќњџќўџћќџњњџќћџ§§їћѕџў§§ќџџџћџњњџњњќџіŸ„KЈ…<Ј…;Ђ…4Ђˆ4ЁŠ4œ‡2œ…5ž‡9­ƒBЊ€;Ќƒ:Ѕ~4Ћ…=Ѕ1‘gŽdj“je˜9џџ№ёљјјљѕћџџ§ћњўќћўќћўќћўќћўќћўќћўќћјњћќћ§§ќў§ќўќћ§ћњќћњќќћ§џ§ўџќћќљѕќќіџџћ§ћњћјњџћџњўџљ§ўіћњљљљџћњџў§ќњњїќћџ§§§њѕўџіџњїџїњџњ§§ўѕќџѓ§§яјћљ§џўўќђџџњљјќѕњћёџћљџњјћљўљњџјћџљќџџўџџћїћѕњўљњўљњўљњўљњўљњўљњўљњўљџљњџїџўіџџњџ§њќџўџљћќљјњџ§љі§њњіћџўџѓјћєћјџџћљџїќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћќ§ћўўјќћ§ќ§љЌ’Oџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўќћўќћўќћўќћўќћўќћўќћўќћћћћ§ћњџњљџ§љїњўњўџњњњўќќјљ§њљћ§ћњџџќќќіњћїљќњѕњљљџњіџђњћїџњќџўњїіјћќџљџю§љјўџћћўќљјњ§љјџ§јџўњіјљџўњњјјўћ§јџіќћїџ§џю§љџџяјіќќўџњ§ћјћљ§ћћџњ§џћ§џїљњњњќ§єќџє§џјіњѕ§ўѕјїнŸ›r‹he›i†d кеЎќћ§џљњџќёќњљ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњўўј§§ї§ќјћњіћњі§њѕџќїџўіњљћџўџџўўџљћџј§ќј§њљћќќќїћіџ§ќџќћџќќџќљџќјћћћјњћїќњџќљџ§љџћјџ§§ќўџ§љџџїўџјџvДъŒц#Šы%…т5“п‹Сфў§љџљў§њќ§џўјџњіўїјџјљ§јў§љљ§јљ§јљ§јљ§јљ§јљ§јљ§јљ§јўџіџ§ќўќќџџўћљјќќќџћњџ§љџџєќџѕџљџљџѓћўџџћјџєџќњњўќћўќћўќћўќћўќћўќћўќћўќћўўјќћ§ќ§љЌ’Oџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњњ§ћќњљ§ћћўћ§ќћїўџ§ќњњџљќџџўўќћћњіў§љ§ќјўџћќ§ћћўќџїџџјњџўѓџџі§іљџќџџјѕџџљџћўўќћјќїќџњ§џќ§ћћўќќўўў§ћњўљњџџљњџѕџџљџѕјџ§ќџњќџў§њњєќџі§џќјћљїјіџџіџџђњћџќ§љ§џљіјјїљџ§ћџџџјѓыд‰hŠd “eŒiЫОџљњџњџџќљџћќџћќџћќџћќџћќџћќџћќџћќ§ћњњћљњњњќќќџџџџџўџўњџћієџќѓљєљњі§§§јљ§іњћћџљ§џёќџї§њіџіљџќџ§ќјїљѓџџћџћј№џѕњ§ћјљ§ѓџџђџїќћёџџћ№їњa­т+Œф‰фо+оЄШюџјіќћ§ўќєџџїџћі§јѕџўњўўјјњєќџјџћќџћќџћќџћќџћќџћќџћќџћќњћљ§љјќљѕ§ћњњ§ћћџњ§ўѕџўєќњљѕїџћњџќ§єјќ№џў§џјџїќ§§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§§їќћ§ќ§љЌ’Oџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњћ§їџ§ќјћџєіџ§ўюџџїїќњ§џџћљюџџљџќїќњљљњј§ўќќћї§ќјіљ§џџќі№нтпаъушџњљћџјыљџџ§њџ§љћќђїџѓѓњїіѕўџ§§џўъћљџџќџџњ№чљјєџџћќњі§јёћѕіќїћџїћџѓљљѓџќўџ§џќњњ§ўѕќћїџўіўќєў§љў§џќљћџњіїыпŽbi hŒfЯПџџіљњјїќћћџњљ§јљ§јљ§јљ§јљ§јљ§јљ§јњћљћћћњќ§їњўїљњљљљўћїџ§јњўљџџјџџёў§ѓ§џўїќ§јљїџџїќ§эџџћјјў№ѕўђўўя§їїџјљњіјїљџќџ§њќћќѓџњюџќџвчџ^Їй$‹ч.о"ˆс<ŽчЌЯћёљџћџџњњєїќ§ѕњћїћќљ§ўјњћљњў§ўџїї§ћќјћќјћќјћќјћќјћќјћќјћќјњљ§џў§ћџџёјћћћћџ§єџџїюњўїўљмэіђѕѓѕ§§џџэљџњћџѓ№ўњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§ћњ§§їќћ§ћќјЌ’Oџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ќј§ќј§ќј§ќј§ќј§ќј§ќј§ќјќ§ћљїяџќћљшл…fc”e ’`ЭШГўљъџ§ѕўўўїљњљљљџ§љџљђсиЗ’€-Žf Ž_ “l˜{ пЭЈўџіњљћџљџџњћњўѓњџўўћ§бТЂ{fŽmŠeŒf№ыЪќќюџњї§јџїќ§њіџџќѕїэЯЯМИkБYЂ‚AЂƒ8Ÿ‡5Ÿ‚1ЋŠ;Ѕ†7›}0Іˆ;Є…6 }-”f‡a™oŠbжФ•ќ§ѓѕљєјџі*Žц(Œф&Šт&Šт'‹у'‹у'‹у'‹у.н.Žс,Žт*‹т)‹п2уAьOЇѓЉЪыйэџћџџџњѓўњѕћњќљјќ§њќџџїм№ћ бїeЋчL›ф6р&‡с#Œэ/“с*ˆс$†ф&ш*н7•о7œчŒн/р„щ:˜сНоэџџѕџ§іўіїџњџџќѕџўћїјќлъњЈЫьuБхQЃъ+Œм'‹у'‹у'‹у'‹у'‹у'‹у'‹у'‹у Žц л"Žж<“еЌвєћљљіљ§Жиі]АчrЕь}Еф€Оюшёџіјљџџёџњњ§ќј§ќј§ќј§ќј§ќј§ќј§ќј§ќј§§їћњќћќјЋ‘Nџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќћїќћїќћїќћїќћїќћїќћїќћїџњљџ§ѓљћќѕщп‚h’iŒgkЬУЈџџяќњђјњњљњўњњњўњѕяцнˆo Žf™kdgŒkƒfќлЫїџєџјћџњњџўєѕљњџіўуШœŒmŽlf’e чобњљћџљњџјџњ§эјрМЂŠN€f ‡ji‘j‹iŠk…fjŠ`“jŽiŠgŒihŽj‡eghЧД‡џїџќѓџџ§є,’х)т&Œп'р(Žс'р'р'р$о#р"Œу"Œф"Œу%р*н-л$‹чQ›лЎаэј§џџ§јќљєћџљѕ§ѓЎеџR˜д&мŒц%‰т2Œр,Žм"н(Šт'ц#фŒс#Žп%Žп'‹у*Šш%‹ф,х&‰пiАщнёіџ§ѕіњћљћѕџњїоёџ|Ет2Žец‹ц#Œу/Žо%Œт%Œт%Œт%Œт%Œт%Œт%Œт%Œт.ˆц(уŽф+ŒмЊгњќјїжшѓiЏхŸЧуљёџЧъ”Чя‘Уэџњѓіџѕѓљџќћїќћїќћїќћїќћїќћїќћїќћї§§їћњќћќјЋ‘Nџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќњљќњљќњљќњљќњљќњљќњљќњљћњіўњљњќіьщкh‘gŒiŽfлЧЄљјњїџєџјћџј§џїїј§ўД–G‰iaf’j‹g—eh ­Aџіџўџяіњћџќѕџ§ќєћјмЦЃ‰gi‘hˆfшнЯџџђџњїєїџђиЉ„m …a œnŽc„h ‡j‹d‰l‘g‘gg‘hg’h”keŒhgffЧЖƒїњјўњѕњћї5у0т)Šс%‰с#Œу$ф"т"ŒпŽф)‰ц%‹ф*и(Žс‡ч(о&Žс%‹о.Žт+х“вюџљ№џ§ќўљіЭхљ%к'Žн$ŽсŒос'т)Œр'Žф#т"Œу$Žу+Žр(у&ф!‹р'ц&Šт!‹т,‘ч‰цYЇтэћџџќѕј§єјљїXІэ%Žн2Šш%„ыŽт ф,й%Œу%Œу%Œу%Œу%Œу%Œу%Œу%Œу!п2Šф)ŒрŽшДбьјќ§|ЛюЮцђyКцЛиѓ›ЦэіјџcЄщџќєѕўєќњњќњљќњљќњљќњљќњљќњљќњљќњљўћіљљљњћїЋ‘NџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќњљќњљќњљќњљќњљќњљќњљќњљћњіўњљљћѕьщкŽg‘gŒiŽfеУž§ўњњјїјџђўїќџњћъфЭ‡iŒf”l†` …5‹g “fd „g ъоЦљћѕјћљўћїјіѕљљљжЧ Žghg†eщсаћћэџўїђії•{5Ži™k `šw3кЯГџќяџњќіјјћљјљљљјјјњљћјјјњјјњјїѕђюŒhgffЧЖƒїњјўњѕњћїїћѕі§ії§јіћљїћіћћѕ§ћѓџ§ѓ§ќјўіієїћќћїќїљуъљЪя Šт%ф!‰т!‰т@›оџњќ§іћќћїdЋф+с)†с&ˆь‹уeЈсРеєќїџјќ№џњљџўєІЭѓ*Žч#‰т*‹т4‹чDœшpАч ‰к'р%Šц4кКкэџљ№ў§љ­дє.‹р‹н&Žч'ŒлoЗйАвяпъџћњіћњіћњіћњіћњіћњіћњіћњіћњ№іћљїўёэњјџћђіљ§ЕуйшјxЙь–ЫьnЋщфьыTЂя§§яїіјџћјќњљќњљќњљќњљќњљќњљќњљќњљ§њѕљљљљњіЋ‘NџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћњіћњіћњіћњіћњіћњіћњіћњіћњіўњљљћѕьщкŽg‘gŒiŽfзШЁњљѕџїјїџёњјј§јїГЁbŠgŽc‘j•x'єфЧ‰l“g”e…gЌ™Vўљјљќњљљљўћїџќ§ЮШ›‘ed”i‡gштЯљћяџћђіјь€dkc Šb ХЌtџџѓљќњјєњєљќќќіћњіљњіћќњљњіћњіњњєѓёщŒhgffЦЕ‚їњјўњѕљњі§њіћљјјјјјїћљї§љї§ћіџћї§џјєџ§№§ўѕјўѓєјђџћїєії„Мы"Œс&‘ц"Œф!Šхёыі§ѕќѕњј&’у%†ч*‘ш%‰т4“ибфѓњўј§љєјџ№ќњњЂХ№3’с!Šх‰х'Šоa­нуѓњпяџ;šф%Œл,х!‰ц›Эёџќѓ§јїrЗщ$‹т$“с ŠсE—прёєџ§ѕџћїўњљўњљўњљўњљўњљўњљўњљўњљџјћєїќќљё§јљџїїєііЖиі™УюwЖщ€МъiЏъПльnВчѓїёџў§џѕѕћњіћњіћњіћњіћњіћњіћњіћњі§њѕљљљљњіЋ‘NџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћњіћњіћњіћњіћњіћњіћњіћњіћњіўњљљћѕьщкŽg‘gŒiŽfдЧЁўѕјџ§ѕѓњѓєљјњ№пo’h–jŒgФЏ|џќ§ЎšYf”jl‡m ічдјњћѕјіўњѕ§јївЩž‘e’f e‡hфоЫ§џљџљєєётn‘d` gбЖ„џќёїјяџџјўўђќљєњњєњљѕќћїћњі§њѕќљєєёщŒhgfeЦЕ‚їњј§љєљњі§њі§њіќљѕњњєћћѕћќѓ§ќђ§ќђќўђћўѕѕѕћўљјїћіџњѕџјѕЄЭю(у(л%Œу+ссшїћјњѓћњ'м"ŠчŽп ˆс=™рќѕјџџѕљёћњїџƒОь'Œт+Œф#м"фlЕщ№ёѕљџєџ§іPЂщ*п)‹пŠъФяўњѕўљјaЌф*у*Žр&ˆрSœьџўџџћђшљѕіњѕіњѕіњѕіњѕіњѕіњѕіњѕіњѕџњѓўћѓџќїјњњј§єџ§ьюѕў‚ЛшЛяЙоєЈЩъhАрпъўѕ§ђџљєќљћћњіћњіћњіћњіћњіћњіћњіћњі§њѕљљљљњіЋ‘Nџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћњіћњіћњіћњіћњіћњіћњіћњіњљѕ§љјјњєышйŽg‘gŒiŽfЯТЂџјњљ§ђљїіјљ§ШЖ‹h”cŽfnљыхіњєэпЭ„gfhŒkТЉqќј§ћ§їџњѓіѕёкЪЅe’hŒbmумЭїљљ§іљі№хf”mf„dЦГ€њ§ћђјїћіјіјјўјѓќїєќїє§јїќїєўљіџљєїяшŒhgfeЦЕ‚їњј§љєљњіќљє§њѕўћіћћѕјћђїњёѕљѓѓњѓќјѓћљљїѓўўљћіћљўќєћћѕŸЯы)ц'‹й(Šт'пмэіњ§єљњё/Œл.о+Œж4‹ч;ыїјіћўяћіјы№яІЮъАЯшЂЯфЊЭяЏЯѓь№ћќ§єџє§ўїю[Іы0ф%‹о"х”Хэџљњ§ќјbЊц+‰ш'‡с&уCъьѕјњѕђўџћ§њі§њі§њі§њі§њі§њі§њі§њіёљљ№љіѕїјћљјєћюўќђўљіыћњкшюАЬыМзђђїјѕїџїїїќџѕїјєћњіћњіћњіћњіћњіћњіћњіћњі§њѕјјјљњіЋ‘Nџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕ§љјјњєышйŽg‘g‹hŽfбУЇџјєєїѕ§љєќ№юŽs‹g›hŽkД™`њіќѕјяџћ§Ј’@‡g’gi’pјясќ§ѓџќѕјњєйФЄff“jŽkхмЮѕїїћєљљѓь‘f‡gŠkˆnХГ~љљѓљћѕџљђўћѓћћѕљћѕјљѕїћіјљѕљћѕњћђђ№шŒhgfeЦЕ‚іљї§љєјљѕћљјћїіћіѓ§їђџљєџњїџњїџљљћѕњџњѕјћљєћєђі№џћѓћїіСщ#Šч$Žу+х‡спёђћћяџњя)ŒшŽм‘о(Šт8•ф§ќјњџєїіњјєњђњњѕїёџњјћіїџќјџљѕџїњєїѕљњі[Єш+Šс!‹р&рœЦщ§їјєі№m­ф'ц"Œу&“нFчњїљџјјќєэњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕўћѓўќъџћђџјјџћіѕіђќїіџћёѕѕћѕјяџјћєіїџљљћєхќїєю§ѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕќљєјјјљњіЊMџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕљјєќјїјњєышйf‘g‹hŽfгУŸљњ№їіјљіёиС›i‡f“c…f ъмЦўџїєєєјљїлЧЈˆh ŽdhŽdЮКŠѕіьћјѓќљёвТžŒg‰g”j‰cщмЮќўјќљѕђ№цe•d’d‘jбД‡ћєїіііџјјјіѕ§љєўњѕќљѕќљѕћјє§љєџљђѕяшŒhgfeЦЕ‚іљї§љєјљѕћљјќљѕќљѕќљѕќљѕљїіїїїѕїјљ§ђћљяѕјіџ§ѓџјіѕюћДвѕ<•э$‹чп)Œт:•рђљіћіэўќќ Šт0ˆт ‹ц$ŠъF“яњєљђїюјљ№џћїѓјїўњљђїѕћіїјііїњјчіђѕќљљћѕUЄч*у%ц$‹сœЧшўњѕљњіm­у‹нп,”лQщџѕі§њієћєіљїіљїіљїіљїіљїіљїіљїіљїќљѕћћѕўљњє№ћјїљіїюћўџїђєќѕђџџљ§ќюџє№ќ§ѓџћћћј№єћєњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕќљєјјјјљѕЊMџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕљјєќјїјњєышйff‹hŽfиЩ›ѓћёћїіњќќ›}.”g…j’gЈˆ<ўћѓѕљцћќјєєєџљїЁ})jŽe ’ev)љњёјљѕџї№вЪЂŽf‰jfgяраіњюљћяяђтh‘e g…fЫД‚ћњієћєћќђєќђјїѓњљѕјљїјљїїјіћњіќљѕђяъŒhgfeЦЕ‚іљї§љєјљѕџљюќќіэјќЬцїœЩъqАтWЄуKЁчPЅуYЁчPЂъLЃм<™ф"‹ц'м‹н&‹с'”о#‰мЪђјєѓџљїыєџ+“ж,н!с#нC˜тѓљєџўєї§ђыљѕџњёћљяќњљїјєўњяјњєјљѕџќщўњяPІш#т&Šш!ˆш™ЩыћљюјљїbЌюŒф$Žц$ŒйFžыџњѓїљэћќђ§јѕ§јѕ§јѕ§јѕ§јѕ§јѕ§јѕ§јѕќќ№ѓіўўєєџћђќќ№ќ§єьєєџў№§љєђѕњѓ§эџџэёїђіѕўљњёџіђњљѕњљѕњљѕњљѕњљѕњљѕњљѕњљѕќљєјјјјљѕЊMџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћјєћјєћјєћјєћјєћјєћјєћјєћјѓ§јїљњёьчиf“gŒiŽfнСžєјђћјџмЬЇ–ff„o“cЮЦЉїјюљћѕўћэ§њіѕѕѕЫП•…i‰kc “eиЮŸћљёєјђдЧЁeŒhŠišhфмЫњїѓіѕїєѕѓ‘eŽe™d”jУВ‡ієєњіѕўїєўџяљјєјјђњїђћјѓњїђќљєћјѓёяч‹fŽb•k‰gЩГƒћіѕ№єѕћ§ёњњшЬсџ_Ћц.ˆн(ц&‰н#Šы,ˆч%Œу%Œу$‹т'Œт)Žф)Œр(‹п,сŒрTžрБЯђёєќљњёљћяёў№*с"‹т&Œп&‘лB›оўљјѕѕяёќєџііўќёњљяњј№љљѓљјєљљѓњћђљњёћљљQЄш Œо(Žс2ŽсЂЦъїђя§§яd­ч%Œт'‹у)‹уFЂућіѓћјѓћјѓћјєћјєћјєћјєћјєћјєћјєћјєјїѓњљѕњљѕљјєјїѓљјєљјєјїѓїњёћѓ§њіќѕћ№јќ№џєђџіњїљѓћјєћјєћјєћјєћјєћјєћјєћјєќљёљїїїљѓЌ“Mџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћјєћјєћјєћјєћјєћјєћјєћјєћјѓ§јїљњёьчиf“gŒiŽfнЧЃѕљэѓђіЋ‰GŽh’eŽj˜w(џћъљљѓјљѕќїюїђѓќћџџїй‹r"‹k•f ‘gœ„8јњєќћїЯУ™hf‹i“bумЩћљёљјєїљэf†f“h‰gРГ…ќњљњјїўііјјьљјєјјђњїђћјѓњїђћјѓњїђ№юц‹n‰dj‰kЫЖ‚џњѓїљѓњњъЩцєIšо‰о*ŽцŽр)й-л3™сMЃхNЄцPЄхNЂуNЁпOЂрVЉцcДёКиырьјќјїџљьўњя§њѕѓіє*†х,‹ш%Žщ‡т7”щјїљіњєёљђіјђћіѓќїіќїјћіїњѕіњѕіћїіљіђџѕђVЇф%‘т%Šц&…т”ХэѓјїјјђcЌц%Œт'‹у)‹уFЂућіѓћјѓћјѓћјєћјєћјєћјєћјєћјєћјєћјєњњєљљѓјјђјјђјјђњњєњњєњњєљњ№їјєћјѓњѕїїѕєџљєў§яюєѓћјєћјєћјєћјєћјєћјєћјєћјєќљёљїїіјђЌ“Mџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћјєћјєћјєћјєћјєћјєћјєћјєњїђќїіјљ№ьчиf“gŒiŽfЮҘјќіфмХ•iˆg‘g–fТГ…ќіёѕіђјњє§їђўљћ№№іџ§ьМЈyi’dg‰gпиПјєњж֘Œh el•eчсЮїјюљјю§ќчŒgŠi˜n‰hУДƒ§ќђѕє№ќѕјњњєјїѓјјђњїђћјѓњїђњїђљіё№юцh‘f ‘gˆf ЩА†ўєєїѓљќєѕnЊц-†о2“у&‡п+ŠсАЯіуюь§ћёјііљїїљїїќјїћїіњѕєћіѓўљіёѕі§ћћўљіћїђћѕіќѕњіјј+‹х)‰н$с%‰с=˜эјєѓћњ№џї№џћюєјђѕљєѕљєѕіђіїѓїљѓїљѓїњёџѕѓVІу$о%‰ч+‹щ”ХыѓњїѓїђcЌц%Œт'‹у)‹уFЂућіѓњїђћјѓћјєћјєћјєћјєћјєћјєћјєћјєќљєњїђљіёњїђћјѓћјѓћјѓћјѓіїѓќњ№љђяћћыќўђ№єљюѓёџџєћјєћјєћјєћјєћјєћјєћјєћјєћј№љїїіјђЋ’Lџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњїђњїђњїђњїђњїђњїђњїђњїђњїђќїіјљ№ыцзf“gŒieЮШ›њљћЎ˜W—k‘gŠf–jююоћіјѓїђїјюўјѓљєіђєѕќњђјькi‘g“g‹iЉPјѓќмЧš…efŠgaфрЭєїюњј№ѕям‚c‰de†dЦВ‚џњэњј№љѕњєїѕїіђјјђњїђћјѓњїђњїђљіёёячŽf“i ‹d†eЫЕ‹џљ№їјєњіѕ?—ф ‰ф"Žп%ц^Љюєюљњїшџїјјњєѕїёєі№іљ№њћђњћђїјюіїэќљёїѕэђѕьљќѓќїє§ѓѓєљ№'Žн&Žс)к0м>šщ§ѓѓљіђњѕіќїюњїѓњїѓљєёћєёўјѓўјѓ§ї№§ї№јїљYЈы(Œо#ˆо,у™УцјїѓјќёcЌц%Œт'‹у)‹уEЁтњѕђњїђњїђњїђњїђњїђњїђњїђњїђњїђњїђњїђљіёљіёњїђћјѓњїђљіёљіёљєѕ§ї№іњюћ§їћѓьѕџюь№ћџљыњїђњїђњїђњїђњїђњїђњїђњїђћј№јіііјђЋ’Lџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљіёљіёљіёљіёљіёљіёљіёљіёљіёћіѕїјяыцзf“gŒieЯУŸътбŒk”i”f‰gЙŸ\ћќјјѕїєїюїљэ§њђїє№њўљѓѕяћіѓНŸhj‘hŽhm эрвгР›m—kŽidснЪєѕёњѕєїэцИŸmКŸfНžgИЂhмЮБ§јяјљ№јііїјяїіђљљѓњїђњїђњїђљіёњїђѕѓыЛЁ_ЛЃiЗ bЕЁhмаДћњ№ѓљюњїђE—фŽчŠо-лoДлўћѓћћэяїэћіѕњѕєњѕєњѕєњѕєњѕєќїі§јї§ѓѓћњіыљючјыђљђћіѓєїю*н"‹ц,Šу,х5—хџљіћј№эјі№њњєііѕѕѕјіѕћїіќјїњіѕієѓїѕєћіэZЇц+Žт'Šр)Œр”ФшљјєќљъcЌц%Œт'‹у)‹уEЁтњѕђљіёљіёљіёљіёљіёљіёљіёљіёљіёљіёјѕ№љіёњїђњїђњїђљіёљіёњїђќћэѓѕѕѕјіљяяћ№кџіјіњюіі№љіёљіёљіёљіёљіёљіёљіёљіёњїяїѕѕѕїёЋ’Lџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљіёљіёљіёљіёљіёљіёљіёљіёљіёњѕєіїюыцзf“gŒieзФЃНЊm‹h˜g‹fˆhьуШіїэїіђќ§єїјюїѕэњј№јљ№єєюњјїясЪ‡d…c’g‹fК jжХž‘kcjf тнШљјєњѓіџљћџїрљїьџї№§љчћїђјіѕіїэљіђ§њьїіђјјђљіёљіёљіёљіёњїђјіюўјёјѕёќћэ§јщљєѓѕјіѕјяџііE˜ц,Žт&у-чiЎчђѓ§ѓѓѓћіѕњїяњїяќљёќљёњїяљіюњїяњїяљѓєјіѕѕљѓ№јюієѓћєї№ѕѓ%‹ф!‹о.Šщ"Œф4•пћљёџњщљјфіі№іњяєјэњљяћћяљљэіїэіљ№ѕњёџќђQЃн$о-ъ&‰хЦэёієџіьcЌц%Œт'‹у)‹уEЁтњѕђљіёљіёљіёљіёљіёљіёљіёљіёљіёљіёјѕ№њїђњїђљіёјѕ№љіёњїђњїђїњё№іыџючЖЂiяцнієєќѕђђіёљіёљіёљіёљіёљіёљіёљіёљіёњїяїѕѕѕїёЊ‘Kўџ§ћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљіёљіёљіёљіёљіёљіёљіёљіёљіёњѕєіїюъхжf“gŒieзМ‰q„b•g‹gЃ‰C§ѕѕѕіьљјюѕђюѕё№їїёћљёіѓыњїђєѓяљіёЋM‹i”iŽf“uЯН‚ŽeeŽhdфнТљњ№їѓђѕя№њћёяѓєђєќєјѓѕѓђѕє№јљяњіѕћїьіѕёјјђјѕ№љіёљіёјѕ№њїђљїяђѕѓъђђяї№њћёїѕєёїьѕљцўѕь:ч*‰рн&‰нmЎсјљ№џљшљ№ѓјљяѕіьѕіьѕіьѕіьїјюјљяїјюџћьћєхџљьџљяџѓёџѓѓѓіэ0“у)’м*ŠчŒм2”рНпяїђћџљюћѕ№њїђљію§ї№ўіяљѓьњїѓїјіяёёШсћ;šу"‹м&Šш#‡пЁЯчїіьњѕїbЋх%Œт'‹у)‹уEЁтљєёљіёјѕ№љіёљіёљіёљіёљіёљіёљіёљіёјѕ№њїђљіёјѕ№јѕ№њїђљіёѕђэћїхђсЧ},щЮДљњ№ьјьјѕ№ћєїљіёљіёљіёљіёљіёљіёљіёљіёљіюїѕѕєі№Њ‘Kўџ§ћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№њѕєіїюъхжf“gŒieЁ„9ŒeŽh‹egмЬЈ§ёёїіђјіыњѕєњєљієѓјіюћѕ№ќѕђїїёяєѕпЯЊ’lŠe–i‚e›ƒ/Žc f fŽeцсТїјшњј№їіђыію§јщњѕђњїщўїюћљяіјьієєљіёѕє№јјђјѕ№јѕ№јѕ№їєяљіёјіюџіьџњїљїяјђэњѓіѕіђѕіэџђњgЏх/‹ф&х+‰шŒц|НъРиъЭрэасюЯрэар№ЯтёЭряЮс№Юс№ЬпюШпяЫп№Юс№Ыпъуюіјіѕџћц^Ћщ&Šт&‡щ#р"‰цCœйŽЗіТк№ЮсюЬтюЪрьЮтэасюЬпюЪтєСмёЌЫтRšт‡ц+Žт#Šц.оЫущџњчщёўbЋх$‹с'‹у)‹уEЁтљєёјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№їѕэљїяљїяїѕэјіюњј№ѕѓыюьфНЄl‚gраЅѕљюјѕёњћыёћыјєяјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№љіюієєєі№Њ‘Kўџ§ћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№§ѓѓїњё№№№џїл{e‘l‘b‹f †m‹f–j‰i|5џіуљѓєѕіэјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№ѓђћџљу˜…<„imŒfŒfŒl˜f•m{c ѓшЬњѓњњѓ№ўћэѓѕяјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№ЧоєB—еˆч'Žы%Šй‘ру,Œр%‹ф%‹ф%‹ф%‹ф%‹ф%‹ф%‹ф%‹ф)Œр(г&улРзэіњчјѕ№дщъ.’ф(‹п&‹с*Œф(Šт)‹у'Žх"Œс$Šу$Šу$Šу$Šу$Šу$Šу$Šу$ŠуŠм"‹ьˆя,н€МрыѕѕџѕыњіёdЋф#ŽпŽт*‰№FЂзљїэќєэњј№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№љёјњѕьћљяёєђєєњёшкУЌtŽj‡c жǘџѓёѓћёюђьїѓђњљяѕїыјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№ћѕюјѕ№іїюЊOџўџ§џўџў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№џљьѓєъіѕљљюр ‹GŒf–f’g‘` ˜e‘e‚bпЬІџіьѓѓэљћяјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№№єя§їьъжГ‚af “b˜f’c”eŒgš„=ўјхюѓієїюјјъ№ёэјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№єјэФмђ[Ён%ˆо+ы$Œщ"Žц+‰т%Žп%Žп%Žп%Žп%Žп%Žп%Žп%Žп‰ю%с'‰ч&ŒпПвѓљіюџѓё№ђѓШпѕvАс)лŠф'Žф0Œн+Šс"‰щ%Žп%Žп%Žп%Žп%Žп%Žп%Žп%Žп6’с"м8•вЇЬшљєіћѕюїїёљѓюfЇы+Œф‰с,„№MЄфіѕљџєђњёшјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№їњыѕіьѕѕщџєђЫЖƒ‘vŒlnмвЃќѓхћїіюёшћјѓ§ї№ѕѓщѕѓђјѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№јѕ№ћѕюјѕ№ѕіэЊOџўџ§џўџў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїєяїєяїєяїєяїєяїєяїєяїєяљђщїђѓєёњќїєіьЪЋ—Vˆl†d j ˆkŒsвР‘џљшѕіэєѓяјёєїєяїєяїєяїєяїєяїєяїєяїєяѓїьњїѓ§ёхпЪt ‰j„g„m…jЏ•SїчУћљяыёьѕњыїїыјііїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяїєяѕљэљічіїѕТ幓КчƒДцcЄлLЁхSЁфSЁфSЁфSЁфSЁфSЁфSЁфSЁфGœъSІоXЂтVЈтЦияэєэїђяђљђљњъьєэЪцэ™ЫчfАрNЄрOЃфSЂсSЁфSЁфSЁфSЁфSЁфSЁфSЁфSЁф‚КуЖжэщяіѕѓѓёѕяяљщѓљюєєє‚ЗщYЅрTЄлZœуkДрщюяђєєђі№їєяїєяїєяїєяїєяїєяїєяїєяђљьєєтџшмДŽN“a–l›z5њмЩѕїыѕѕяѕѕяјіюїѓюљєыћіэјёєїєяїєяїєяїєяїєяїєяїєяїєяњєэїєяѕіэЊOџўџ§џўџџўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэњњшњіёѕѕяюёшєі№ііцџњпђсЬсвВсгЖўёу§ѓљђђђэітњќщќ№юїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїіьєёэњєѕџѕяџ№пькУсвИэрЦњљнўїшќѓ№іююћљяќљъѕяшї№ѓїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэљёћђђцџјчњѓ№щёёѓјяљѕъђѓяїѓюїѓюїѓюїѓюїѓюїѓюїѓюїѓюљѓє§ѕшїѓюряђџѓэўљъњѓъ№єшџьєїя№№єюёіэіѓюњѓ№јєѓяёёїѓюїѓюїѓюїѓюїѓюїѓюїѓюїѓюѓђюћѕ№їїыъѕхѓјя§№ђ§№юѓѕщџїэ№ѓъњќщѕѓѓфђ№џћыњѓ№ѓєђїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэ№ѕѓёхй”y/`“qШН‹їѕыїђєїѓюќїюћїьѕђъђёэѕѕяњѕьњ№щїѕэїѕэїѕэїѕэїѕэїѕэїѕэїѕэњєэїєяѕіэЉŽNџўџ§џўџџўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџієьієьієьієьієьієьієьієьэёыїђєїєьјјь№ђѓяєѓэѓшієє№їшѕїёѓяѕѓюїѕѓђјїэјђыњяђієьієьієьієьієьієьієьієьѕѕяѕђъјіьїѕэ№єююіьяђщіїюь№ё№ѓјђёѕњѕђјѓъјђыќіёћѕ№ієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьієьїѕыџћёієъѓђю§єёєђъєјьќіыѓє№ѓє№ѓє№ѓє№ѓє№ѓє№ѓє№ѓє№ї№ї§ѓьџє№ёѕіњёюієьїєьјјьџќщієъђ№яєѕѓїѕэєђчєђъѕѓђѓє№ѓє№ѓє№ѓє№ѓє№ѓє№ѓє№ѓє№іѓяіђёћѕ№њєщїѕъєѕьњєэџєы№ѓјьёђљїь§ђюёѓэџђхљёъјѕэієьієьієьієьієьієьієьієьџёхˆ7fœ} япТ№єю№ѕь§єъіё№јђэљѓьљїяіјђёђ№ѓ№ьќљыієьієьієьієьієьієьієьієьљѓьіѓюєѕьЉŽNў§џ§џўџџўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїєьїєьїєьїєьїєьїєьїєьїєьяќц№єшјѕцњѕцјэяћѓєє№ыљёђѕїыѓёщўњяјєтњѕцњѕьѕѓщљљщїєьїєьїєьїєьїєьїєьїєьїєьѓє№§ћёѕ№чїѓюєі№юѓъієѓљьєџљ№ё№ціњяёђщђёэђѕѓёєыїєцїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьїєьѓѓѓ№ъя№ђђыјъђјхўјэјяьѓ№ьѕєъѕєъѕєъѕєъѕєъѕєъѕєъѕєъіѕч§љцќѕфѕѕщїєьёђююяэїєя№ёчіішћјъ§ђюўюѕўёљјѕё№єшіѕыіѕыіѕыіѕыіѕыіѕыіѕыіѕыњђђѕяъћєёќєѕіэъјїщ№їъщђяљєхіѕчјјшѕѓщяѓэњѕьїіьєїшїєьїєьїєьїєьїєьїєьїєьїєьаϘˆcnДYижИјіыњєэіёюјѕёѕѓыєђъєђъѕєъїє№єђёѓѕщїєьїєьїєьїєьїєьїєьїєьїєьљѓьіѓюєѕьЉŽNў§џ§џўџџўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыѕєъѕђюієьєђшј№щўѕыўїцљєхњэяќђђѕяшњіыћѕ№ѕьяјѓђђѓщіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыѓяюієъљїьёьщјѓ№їѓш§іэќяёџяц§њыёєфїіьююшяіяяѕъќіыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыїїхїѕыћёъњєщєіъљяшњэыьљёѕђэѕђэѕђэѕђэѕђэѕђэѕђэѕђэђђьїєяїѓюїёъ§ѕюњѓ№њёю§№ю№ѕѓђѕьѕѕхѓєф№єшюѓъѕєъќіщѕђэѕђэѕђэѕђэѕђэѕђэѕђэѕђэљѕтіљ№чьыіѓюјёшћѕ№єёщюымњёшїѓюѕѓђіё№іююћђяћѓьњєчіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыкК‰’j”e“n‡g…d ‚/ЕœTПЇ}лбЁїѕзќіяїёъћєыјѓ№ѕѕяіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыјђыѕђэѓєыЈMў§џ§џўџџўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыў№ъјђэь№ъ№јю№іыёђшѓѓэѓё№ћєыієьђѕььёшёєыієьієьѕєъіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыќюђїѕъёєфњїѓјэяљђщѕѕуѓљшњяїэюъѕїы§ђъџєьѓѓчђѓщћяэіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыьѕшјіьіђэєёэњёюњёюієьєђчієъієъієъієъієъієъієъієъїіь№ёэѕє№ѕѓщѓѓчёђшѕљюђѓъљю№љ№ьњєщћѕшњѕьјђэѕђъѕѕщієъієъієъієъієъієъієъієъѓё№јђыјєщєіъїїщћѕтжЩГцйУііъёєыюђэїіьћђшљѓьђѓъюіьіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыѓђюёѕъойКЪЉ{БŠEЁ€0Љ‡.a™c‚eЕЊqїэц§ѓѓљёфўєэіююіѓыіѓыіѓыіѓыіѓыіѓыіѓыіѓыјђыѕђэѓєыЈMў§џ§џўџџўџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыюѕшњяёђђьіѓяѕѕщюёяїѕујёюјѓъюѓъќєэїєьќђыкЦлЭАѓєыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕїсёічэѕы№ѕьєѓщњѕьњђыљѓюьѕыѕє№ѕяшјіьє№ы§ѕюћ№тюфвœ|œ„Hў№оѕюѓјђѓіђчљљы№єщѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыѕѓыєѓщіѓыѕѓщЅM§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъёђшћѕюџ№ъђячёїцђѕьъєшњюъѓ№шѕђюёєфџяшДЊjМЎŠўєъїѕыѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъљяѕїыёћяяќѓъієъ№яыюёяьєъ§ёыѕђфїѕъїѓшіѓюѓыьиТŸŽn “|>љъУџћьяэьѕёьіђчёяфѓѓэѕђъѕђъѕђъѕђъѕђъѕђъѕђъѕђъєѓщіѓыѕѓщЅM§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщјєсюъяњђыќёлвОБЁ\рйХјђэіёюєђчќїшВ—dœŒ?їєпљяяѓ№шєёщєёщєёщєёщєёщєёщєёщєёщѓёчљђяєющѕђфё№тјѕёєёэѓѓхјыэієъьѕш№юэїтЬ­‘=~eД™aњьйџћщыяуяѓшёёхќіыїёъєёэєёщєёщєёщєёщєёщєёщєёщєёщѓђшѕђъєђшЅM§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщєёщјѕчюђэёяфЌ”La’g‹lцуеєёэѕђуЦБ~ŒoънНёєоўяэяђщєёщєёщєёщєёщєёщєёщєёщєёщѕїфююш№яыѕѕхњіујяхњђыѓђфюђэь№ёѕяшоЧ•o ŠmЬЙ€љ№уіюя№эшђіъ№ѓфієщѕэцѓяъђяъєёщєёщєёщєёщєёщєёщєёщєёщѓђшѕђъєђшЅM§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшь№ыёёхШЖ{ˆhЏˆQЁ|"•mЮП‘эящйЪЉ‰iбЕяъыјєтњюъэітєђшєђшєђшєђшєђшєђшєђшєђшёёуїєьіючћђшї№чѓыьєьэїёьіњзлЦ ВŠI‰f–…/мдЗїяяќѕфјёюђячђёуїѓшј№щєющѓ№шёѓчєђшєђшєђшєђшєђшєђшєђшєђшђёчєёщѓёчЄŽL§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшєђшё№тѕэж“v Š8ћђщЏ˜T‡dПЊfѓюх—'™sњэпъющџя№ђ№шёѕмєђшєђшєђшєђшєђшєђшєђшєђшѓђфієтѕђфёющѓђюљѓрщжАРЁl—tdi ЕЁjюшсѕієєђчїюъїёці№ућѕшѓьуѕэцњєяяэуєєцєђшєђшєђшєђшєђшєђшєђшєђшђёчѓ№шѓёчЄŽL§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчќѓщШЖyƒ`лбЉцьыПЈxŠj­‘JЯЙ…jкН–юёшііцљыёяѓшѓѓуѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчњюь№юцыђыююшцлЛ—‚7~`‘k”e Ж XщсУљёъјёшэщф№ьыє№хѕѓшђэфїђщїђщѕѓшяэтѕѓщѓюхѓёчѓёчѓёчѓёчѓёчѓёчѓёчѓёчё№цѓ№шђ№цЄŽL§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцєяцъьэЋ‰=™wџюхђѓщдМ†˜f˜r œw"Ё}1љёрэѓшєёмђэъђэъёюъєяцєяцєяцєяцєяцєяцєяцєяцћэчюђчщюхџёр­F‘`™wПЋqччзєѓхяясђѓщѓыыљюъјђхђёчююшєёь№эшяюфёђтђѓуіёшјьъєяцєяцєяцєяцєяцєяцєяцєяцё№цѓ№шђ№цЄŽL§џџџџўџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№ц№№ф”q К•[ёяч№ёчозФeiˆeаЛœёьыіѓхѓьу№ѕцыям§эюђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цїёъёыфёїоЭЖˆ›eŠj щуа№эщђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђ№цђёуєяцёяфІM§ўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяффоЧˆdаЖ€їђщёяфіяоЁ5ˆe˜{&њщЯєёэёюпјёшыэс№єсљьъёяфёяфёяфёяфёяфёяфёяфёяфѕяфѓёщѕыс‹s‘eЫЌwїёфяюрёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфђёуєяцёяфІM§ўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфовАŠfЯТ”ѓьуєьпїєхйЩŸ€bХБwћѓтюёшёянљяшюьф№ѓуѕыфёяфёяфёяфёяфёяфёяфёяфёяфєьхя№чбО“Že‹n љуияюкѓёцёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфёяфё№тѓюхёяфІM§ўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфпб­‰bЯЦ ѕ№чєысєысѕёоУЎzъсРыщпыяфѓёпєъуѓяъяясѓэтѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѕяъєэо•y"šk ДЂaїьшєюсюяхѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфѓяфё№тѓюх№юуЅŒL§ўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюупбЕ‹dеХ ђ№шяъсћэчэ№сќѓияьоёёыэяуђ№оѓыфђьч№юуђясђюуђюуђюуђюуђюуђюуђюуђюуђюужУe‰hэтЬэьоќю№чяођюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюуђюу№ясђэф№юуЅŒL§ўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтцлЧ‰fгЙŠшщп№яхјщц№ёсюьсюьфёячяэтёюпѓьу№ъуђюуђюуёэтёэтёэтёэтёэтёэтёэтёэтљэлž6fГœXєяюяюрєыоъэфёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтяюрђэфяэтЅŒL§ўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтѕый‡hФЃd№ясєђчюхсђярььрёяхычмёырёэт№ьсђясђьпђэфёэтёэтёэтёэтёэтёэтёэтёэтуЭЉ‰fŠj юнУыцуэътђѓйђъуёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтёэтяюрёьуяэтЄ‹Kќ§џџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрјялŸƒ<Іƒ9іяоюыняэхєюуяяпяырј№уїэующр№ясёюпѓэрєэфёюрёюрёюрёюрёюрёюрёюрёюрЃŠJŽdØNёыијёшюъхыьтќёлёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюрёюряюрёьуяэтЄ‹Kќ§џџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эпюяпьынђюу№ьсящоєюсяьняэлєытЫЌo„eьсЫяэуэьичѓсјхш№эп№эп№эп№эп№эп№эп№эп№эпѓчсёёуюьтяьохюкяьшњшсукЏ–h‡f сжИхцфєэфѕьоэюкящф№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№эп№ьсёэлюьсЂ‹Mћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояюрёюрюынюынёэтёюряьоѓ№тђьсзЩЅgСЋ{ъщлјёошюнѓчуяьояьояьояьояьояьояьояьоёъсюымюъпєэмяюйщъшєысВ e“j:їыйёющьщкѓюпяьоёъсяьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьо№ьсёэлэырЂ‹Mћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьоюшнђьпёыояьоёюрэъмэщоющряьоцхаŸuЌ‹E№эојылээпђьпяьояьояьояьояьояьояьояьо№ясёъйєэођыиїёоучтэщЭŠj‹hЭКђытящо№ялььк№ыт№шляьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояырёэлэырЂ‹Mћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьођщпђънёыоэъльщкюынђэфюшсђюмкбІ‹dЇŒLяълјэпьыньькяьояьояьояьояьояьояьояьоыэкѓыоѕэм№ымышрђёнДЅg•jŒpюуЭыър№чйєётхшиђъуђыкяьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояьояыр№ькэырЂ‹Mћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ънїэу№чнёыоышйюымюынящм№чн№хЧ‘s"oржДёъс№ымъъоэый№ън№ън№ън№ън№ън№ън№ън№ънщыиэшпђыкшчнчшцхиЌn’dЩА~яьны№лѓыкыхощьнящоѓьй№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ън№ънюъп№ькьъпЁŠLћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмђщмёщмђьпьщлёюрэшйёщиіькЛЃmŽfиЦ‘эьтэцныылщшоёэлящмящмящмящмящмящмящмящмюымышрэълююрѓэкЊŽGˆaЂ€4§ъеььмхыдђымьфн№юуъчйђьйящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмящмюъпяыйьъпЁŠLћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъл№щк№ънюъпщчнюын№щиљђйчмР‰dЅEїьиэысёырэьиёыц№ыжяъляъляъляъляъляъляъляълђщмюъпщщлѓюегК‚†a‡iсЯЊ№чнюъишцлёюпѕюлящоъщлђэояъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляълэщояыйыщоЁŠLћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъл№ькэъмщчньщсьшнђыиѓыЮЎЄ‚”iомДътуіэйышйэщжяусђьеяъляъляъляъляъляъляъляълђцмяълцшммаЌ•jeРЎsыършчнѓыкюццчшияыЮячкээсьцйяъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляъляълэщоюъиыщоЁŠLћџўџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкяыияцтёунььмьызюэиятк”r›€0ішеѓщиъяашѓгђъг№цмђщрїъдыщзььоьцлёцо№ъпышйьъитюа№чу№зЭ•tk ‡?ђыиыщзющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкющкюшл№щиычмЃŠLћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшй№чйыхиэълчче№щиышйгЦІgШГuшфпюшнцозщщйёххьшн№ъгфъз№цмѕумыхихшиччзђымѓшкшчйънЭЋŠ;cœ€,чпШячкэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэчкяшзычмЃŠLћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшй№цеяълфъзььдяшз№хнЈ–WŠhтдТхщньцйђщхюъбьоШюфнюэгшхрєъйєцг№ымшшиюэйъцдьцпђтвЇŠ5f”tидМєэмъхжьърэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэшйэчкяшзычмЃŠLћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиєшжэщофчияывшхжњчкŽmЁ‡-ьъишшиэувэюдітзЋMЮТ’щызэхЮёъйюхл№фкьчвшьЯьыбьоЬ 6ŒbsееЗьщдььдёцащхкьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьцйяшзъцлЃŠLћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиіынсмгьщкѓшкчуинФšfЦВƒюфвэце№чйыьЬфЩЇ„bТБyыхоюэгъфйёчрщужъщлюъишеЈz*Œc˜}#мзЖяшешхж№угыьиѕщзьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьчиьцйючжъцлЂ‰Kћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеьукьъиэцеѓунѓхЮ™~.“qшкЮњулщцзчуиюуе‚o&ЉŒAѓтЯянмшфйяыйствфшняшзЫА„‘i–lЂˆBщрПѓшдысзѕртэщоёскхубэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеыхиэцещхкЂ‰Kћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэчкщхвьхжђфвФЈkdУВэуйѓчЫъчпфуеъснџ№ЫјцЧччеєфзюцештЯђьйэпТЉMŠeˆeД–_щуающдэцгѕфлщцсыпйющашхнэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеэцеыхиэцещхкЂ‰Kћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдшщЯячжштнЯЧЂfЎŽ-цсоюъЮчшдшчгыъЮучлуугъчинфн№чгыужёфдПІz•m•i•sЯО‹яыЯцфмщчечфеъчйыхЮфьЭхщж№фвьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдьхдъфзэцещхкЂ‰Kћџўўџ§џўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгѕфзтхЫзйУ‘r™kчлПффвящЬьхЬюцйэфзѕчбётЯютмъсдоеГДІ^’r–heЉ”WупТыщзэубщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгщхгъцг№хбчфжˆJџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгътешшжЈ‘FcкЩžтсгјфйъпзмцйщфЯвР›­˜[­–FЁ‡)•sˆdŒcŒd Ё~5жТ“ящжптйррвьшЯыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгъцг№хбчфжˆJџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгѓчецЩЎeʘVшцЮшыв№улшхашфЬВ_j ŒfˆeˆeˆcЊˆBХЋƒщжГ№чЬъшачцбщуЬёцаёфЮыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгыфгщхвяфацуеˆJџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувтчЪЬЏƒ‡hиЪЎптгцфЦцсвОД„Ђs”gŠfПЅcтаЋйЫЎ№тЫяпвёцвшсвщхкцреэувєщешсаттдъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувъувшфбяфацуеˆJџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбошбЭО‹dЗ“SдЦ’РЇ_“ni”i˜z'зЦ›юсбцрехчгпуЪцхб№чЬыуЬъувъфзчсжфрефтзфтзщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбщтбчуаюуЯцуеˆJџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуашсвщоШЈ„6’d…d‘i•gšxЧД‡чуЧссгьхвёхЩюцЩъцЭъцЮопеццжщхЭчуЪщхЭщфЯяубётЯщуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуащуачуаэтЮхтдˆJџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯчубцхбфпОУВyЌ˜^Р­tиХ чфжэнаъфзуцжлоШэшгьпбяпвыоЮрсЭчтЭэхЮьсЭэубыхвхрЫъцЮштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯштЯцтЯэтЮхтдœ‡Iџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщуацоЭчсдэхШчпвцчЭ№рЯспдцчЭъсЭщпЮшфбфсЬщтЮшсарудьтбысащтЯштЯчтЭшуЮчуацтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯщтЯцтЯэтЮхтдœ‡Iџџџџџў§ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮштЫъсЭшсЮœˆO§џќџ§џљџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮшсЮчсЪъсЭшсЮ›‡N§џќџ§џљџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчрЬчсЪщрЬчрЭ›‡N§џќџ§џљџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫчсЪщрЬчрЭ›‡N§џќџ§џљџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцрЩшпЫцпЬš†Mќџћџ§џњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцпЫцрЩчоЪхоЫš†Mќџћџ§џњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪчоЪхпШчоЪхоЫ™…Lќџћџ§џњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩцнЩхпШчоЪхоЫ™…Lќџћџ§џњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦхнЦупУцмФ”…MџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦунЦхнЦупУцмФ”…MџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХупУцмФ”…MџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХфмХтоТхлУ”…MџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФулФснСхлУ”…MџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУумУткУснСфкТ“„LџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТсйТрмРфкТ“„LџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТтлТсйТрмРфкТ“„LџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРтйОркНфиР•„LџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРтйОркНфиР”ƒKџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРрйРтйОркНузП”ƒKџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсзПсиНпйМузП”ƒKџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМоиЛтжО”ƒKџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМрзМоиЛтжО“‚JџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛнзКсеН“‚JџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛпжЛнзКсеН“‚JџџўџџџћџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКоеКтжКмзИреК‘ƒIџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИсеЙмзИреК‘ƒIџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИнеИсеЙлжЗпдЙ‘ƒIџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗрдИкеЖпдЙ‚Hџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗогЗпгЗйдЕогИ‚Hџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖнвЖовЖигДнвЗGџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕмбЕнбЕзвГмбЖGџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГлбГнбЕзвГмбЖGџџўџўџ§џўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДлаДобБлаДлаВ‘JџўџџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВобБлаДлаВ‘JџўџџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВкаВнаАкЯГлаВ‘JџўџџџўћџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБйЯБмаЎйЮВкЯЏ‘JџўџџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏкЯЏлЯ­иЭБкЯЏ~IџўџџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎйЮЎкЮЌиЭБйЮЎGџўџџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџиЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­иЭ­кЮЌзЬАйЮЎGџўџџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋзЭЋйЭЋзЭЏйЮЎGџўџџџќћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЬЌзЮЈйЬЌлЬЋ~FџџџџџћџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊзЮЈиЫЋлЬЋ~FџџџџџћџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЬЊжЭЇиЫЋкЫЊ~FџџџџџћџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉжЭЇзЪЊкЫЊ~FџџџџџќџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉзЫЉеЬІжЩЉйЪЉŒ}EџџџџџќџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈжЪЈдЫЅеШЈиЩЈŒ}EџџџџџќџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇеЩЇгЪЄеШЈиЩЈŒ}EџџџџџќџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄгЪЄдЧЇиЩЈŒ}EџџџџџќџўџќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄдШЄжЪ дХЄдЦЂŠ}Eќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃгЧЃеЩŸдХЄдЦЂŠ}Eќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁвЧЁеЩŸдХЄдЦЂŠ}Eќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдЧЁдШžгФЃдЦЂŠ}Eќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџгЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЧвУЂгХЁŠ}Eќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџгЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ гЦ вЦœвУЂгХЁ‰|Dќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвХŸвЦœбТЁгХЁ‰|Dќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбФžбХ›бТЁвФ ‰|Dќўџџџўџўџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœбХ›гФвУœŠ|Hџ§џџџњџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœаФœбХ›вУœвУœ‰{Gџ§џџџњџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›аФšвУœвУœ‰{Gџ§џџџњџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ›ЯУ™бТ›бТ›‰{Gџ§џџџћџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšаСšЮҘаСšаСšˆzFџ§џџџћџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЯС—ЭС—ЯР™ЯР™ˆzFџ§џџџћџџўќўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЬР–ЮϘЯР™ˆzFџ§џџџћџџўќўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЮР–ЬР–ЮϘЮϘ‡yEџ§џџџћџџўќўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•аР•ЯП•ЭТ‡xG§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЭП•ЯП”ЮО”ЭТ‡xG§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЬП“ЮО“ЮО”ЭТ‡xG§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЭН’ЮО“ЭН“ЬС†wF§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЭН’ЬМ’ЫРŽ†wF§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЬМ‘ЫЛ‘ЪП†wF§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЪКЪП…vE§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЫЛЪКЪКЩОŒ…vE§џџџўџџџќџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЛЪЙŽЫЛŒЩЛ‹…uG§џўџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЩКŒЪЙŽЫЛŒЩЛ‹„tF§џўџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ЩИЪК‹ШКŠ„tF§џўџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЙ‹ШЗŒЩЙŠШКŠ„tF§џўџўџџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧИŠЧЖ‹ЩЙŠЧЙ‰„tF§џўџўџџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ШИ‰ЦЕŠШИ‰ЧЙ‰„tF§џўџўџџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЧЗˆЦЕŠЧЗˆЧЙ‰„tF§џўџўџџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ЦЖ‡ХД‰ЧЗˆЦИˆƒsE§џўџўџџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ШЖ‡ШЗ„ХЖ…†sFџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ХЕ†ЧЕ†ШЗ„ФЕ„†sFџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ФЕ„ЦД…ЧЖƒФЕ„†sFџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒУДƒЦД…ЦЕ‚УДƒ…rEџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХДƒХГ„ХДТГ‚…rEџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФГ‚ФВƒФГ€СВ…rEџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУБ‚УВСВ„qDџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВУВТАУВРБ€„qDџџўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ЦБ~ФВ}РВ~„qD§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ТБ~ХА}ФВ}ПБ}„qD§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџСА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}СА}ХА}УБ|ПБ}„qD§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ТЏ|ФЏ|ТА{ОА|ƒpC§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџСЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{СЎ{УЎ{СЏzОА|ƒpC§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzСЏzТ­zРЎyНЏ{ƒpC§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyТ­zРЎyМЎzƒpC§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyРЎyСЌyП­xМЎz‚oB§џўџўџў§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uП­xПЎvО­uПЎvПЎvПЎvО­uПЎvР­zНЊwР­zОЋxОЌwРЎyМЊuП­xС­vС­vС­vПЎvРЏwПЎvПЎvРЏwО­tО­tО­uО­uО­uПЎvПЎvПЎvПЎvПЎvПЎvП­xП­xН­xН­xН­xОЎyОЎyОЎyРЎyП­xП­xП­xП­xПЎvПЎvНЌtСАxО­uРЏwО­tСАwПЎvПЎvПЎvН­xМЌwМЌwН­xНЌyПЎvПЎvПЎvПЎvПЎvС­vТЎwТ­yО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uСЌuСЎuМЌw‚oB§џџџќџџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uПЎvПЎvПЎvПЎvОЉuСЌxОЌwМЊuКЈsИЅrЖЅrГЂoЖЃpЖЃpЗЄqКЈsНЋvОЌwНЋvНЋvОЌwП­xП­xП­xСЌxСЌxСЌxСЌxНЌtНЌtО­uО­uНЌtНЌtНЋvОЌwНЌtО­uО­uНЌtНЌtНЌtНЋvНЋvП­xОЌwМЊuП­xОЌwРЎyМЊuЛЊrО­uО­uО­uО­uО­uОЌwОЌwОЌwО­uО­uО­uО­uО­uРЌuРЌuРЌuО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uО­uСЌuСЎuМЌw‚oB§џџџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtО­uО­uО­uР­tТЎwКІoЕЃnВŸlЋši­œkІ—fЈ–gЊ˜i­›lЏžmВžnД pЙІsМЉvЛЈuМЉvПЊwПЊwПЊvПЊvПЊvРЋwРЌuРЌuРЌuРЌuРЌuРЌuРЌuПЋtР­tРЌuРЌuРЌuРЌuРЌuРЌuРЌuНЋvОЌwМЊuНЋvЛЉtНЋvНЋvОЌwРЌuРЌuРЌuРЌuРЌuРЌuРЌuРЌuО­uО­uНЌtО­uО­uРЌuРЌuРЌuНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtНЌtРЋtР­tЛЋv‚oB§џџџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtМЋsНЌtМЋsМЋsМЋsМЋsМЋsМЋsМЉpМЈqЕЃnАŸlЇ—hš‹]”„YŽ€V‘W’‚X•…ZœŒ^Ё‘bІ–gЋšiЋšiГ mЕЂoИЅrКЇtМЇsНЈtОЊsПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtОЊsПЌsПЌsПЌsПЋtПЋtПЋtОЉuОЉuЛЉtЛЉtКЈsЙЇrЗЅpЖЄoЗЄqЙІsЛІrЛІrЛІrМЇsНЉrОЊsОЊsОЊsНЌtНЌtНЌtНЌtНЌtПЋtРЌuПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЋtПЊsПЌsЛЋv‚oB§џџџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsМЋrМЋsМЋsЛЊrЛЊrМЊuМЊuКЈsЙЅnВ kЉ˜gšŠ\U‚uOthFpeEoeCqhCynHuM…yO€T–‡YšŒ\ aЄ•dЈ™h­œiА kДЃkЖЅmИЇoЙЇrКЈsКЈsНЉrНЉrНЉrНЉrНЉrОЋrОЋrНЉrНЉrМЇsЙЇrЗЅpЖЄoВЂmЏŸj­hЎžiЎjЋšgЉ˜eЊ™fЌ›jЌ›jАœlБžkГ mЖЄoЙЄpКІoМЊuЛЉtЛЉtЛЊrЛЊrОЊsОЊsОЋrОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЊsОЉrОЋrКЊunA§џџџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqНЊqЛЊqМЋrМЋsЛЊrМЋsМЊuЙЇrЕЃnЏžmЃ“d—‡\‚uOshHe]@QI2LE1KE.KE.UN3`X;f]ncCvlJ~rN†zRŒ€V”‡[˜‹_Ÿ_Ђ“bЇ˜g­œiЏžkДЂmЖЄoЙЄpЙЅnЖЄoДЂmЏžkЋšgЄ•džŽ_šŠ[’ƒ\€YŒ}V†vQ‡wR…uQ†vR‚rNƒvP…xRŠ{TŽ€V”„Yš‹]Ё‘bЅ•fЎœgБŸjЕЃnИЇoКЉqМЉpНЊqОЋrМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpНЈqМЉpИЈs€m@§џџџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpЙЈoКЉpКЉpЙЈpИЇoДЂmЋ™dЂ\Y}pJcX8RI.712.#trjФУПєѓїгавЇЂЃupmHA81)5,?7&J@(OE-ZO4aV:h]=qeCzlHrLŠ|LQ–†Wœ\Ё]Ї”aЊ˜cЌše­›fЌšeЉ–cЃ’_œ\•…VŒ~NˆyK{lKvgGsdDrbE€pS„sX}lQm\Al`>nb@rfBylF~rH†yM€T”…WЃ]Ї•`ЎœgГЂjЖЅmКЇnЛЈoМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЉpМЇpМЉpИЈs€m@§џџџ§џџўџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoМЅsЗЈjКЎnЗІnЕŸoЏ™ižŽ_Š~VxkEaX7HC.--!01-   вЯбЧХХ№№іьыѕ№юњёюїюэярркЎЏІ}}wNQA//0+B:)H<*NC-YQ4\T6i_=md?pnFuMŒxO‘~QšƒUއV˜‡T‘†T‘„VŠwQ‚qPvjNvfO’wcбфЄЃјИИ§ППњООјОПќТУўХЦїЩШиЏЌК›’ŽwgjZCl^AwhG‚rN‹O’„TЂ“bІ•bЎ›hЖЄoИЇoЖЅmЛЇmЛЉnКЇnЛЇpМЈqМЈqЛЇpМЈqЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoЛЈoОІpЙЊkМЉp~nCџўџћџџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnНЇsЛЌnЗЈiЕЄlДžnЇ“c“„V{nHbW7H?$1-JH@ЛМКгвджгеЧТУьяѓђёѕѓяѕёыіѓяћёьћѓъїєыѕђюѓчсцНЗИ†ƒ[SL:2%:3"<6#E=&OH/bQ7[W:a\;s`?phCxjFlmCyiDr_>h^@ŠpXЯ„љЋЄјЗЏфКЕхНИцНКфОКфПЛхТПфУРфУРщСУьФХѓЭЩѕбЩыЮРТЌš‚t^aW?uhB€tLŒSšŠ[Є“`ЌšeГЂjМЈqКЈmЛЉnЛЈoЛЈoМЉpЛЈoКЇnЛЈoКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnОІpЙЊkЛЈo}mBџўџћџџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnЖ lНЋnЗЈiЕЄl­˜e‰Y†yMf[;G@,5.omcбаЬавгЮЭЯевдЪХЧя№єє№ѕёэђыъюь№ѕфэ№ш№№ъ№яєыј№ъѕяыёьшэїѕѕьъщИДГ“ŽabXH903*85&F<+KA/NI4KF1XG2LJ2jYFЫŽ„ќВЎщВ­хЖВёЕЕќДД§ЕЕ§ЗЗџЛМџПРџТФџФЦџХЦќЦЫџЭбёЩЪюЬЬхЪЦэзбѓрйШЕ­qdNh[AuiG„vL“…TЄ”_Ї–^ВŸfЗЅjЙЇlКЈmКЈmКЈmКЈmЙЇlЛЉnКЇnКЇnКЇnКЇnКЇnКЇnКЇnКЇnНЅoИЉjЛЈo}mBџўџћџџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlМЇpЛЉlЕІhЕЁjЈ“`š‰XznFXN6D?6š’гбадгеЬЭбЪЩЭЭЪЬЫЦШѓяє№ыєѕяњђьїѕяєѓьяѓьёёщ№ючъѓюя№ююьэычщщыъьёэђяшяяъыхшцЬЫЧЉ–“jb[:9/4%&*@,!ЗzvѕЇЈ№АЏшЏЎјЋЏџАЖљЌАћГГћЕЕ§КЙўМНќООћППќТУџЦЧјЩЫџЯбџЯгџгжџкмѓжйцдеъооѕчсВЄ˜fYCncCƒwM€OЃ“^Љ˜`ВŸfЖЃjИІkИІkЙЇjЙЇjЙЇlКЈmЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlЙЇlМЄnЗЈiКЇn}mBџўџћџџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlКІlИЄkЗЅhЙЇjЕЁjЇ’^’ƒRj`>nfUКЖЕеггЯЮвЪЪаЙЙПДГЗбЬЮЪХЧїяњщщяы№ѓъюяёю№єэ№ыыыы№юі№ёѓэюёэьёяюэыъыщшѓюяяъыѓыьфщшчуттнмкевЩЦСЄЂš˜urя“˜юЎЎчБАєЋ­џЋА§Љ­јЉЌџЌАџГДџГДџЗЗџЛЛџОПџССџУХџШЩћЫЩџаЯџЯЮџжз§икњпт§ьяяфццикіщчЩНБk`Jk`@€tJPžZЊ˜cВžgЗЄkИІiЙЇjКЇjЙЅkКІlКІlКІlКІlКІlКІlКІlКІlКІlЛЃmЖЇhЙІm|lAџўџћџџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkИЄkКЇjИІiБœeЅ‘ZNrhJД­ЄзгиЮЭбХУЩИЖМЛЙПРМСйджУОПщшђь№ёэєяы№яъч№єэњэшёюэёэыёычэёъёючь№ъыєяюьшуюыуячч№ццтонжзгЭЪХАБЈЖ ›яЂЅмДЏщЌЊљІЈўЅЈўІІџЉЉџЊЊљЎЌќВАќДДўИИўНМўРРћТС§ХФўШЧџЮЫџЬЪџиејздјпнџюэўщыўьэќэёужиэспчнгk`Lk`B}nG“„VЂŽ^Ћ™dД iЖЄiИІiЙІiИЄjЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkЙЅkКЂlЕІgИЅl|lAџўџћџџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjЙЅkЙІiЗЃiВfЈ”]‹}Ld^AЕЎЋЭЩЮОКРМИОЖЕЙЧЦЪбЮагавЮЩЪыѓѓёэђёфьєэ№йнзтыс№юэїщяоятэѕюыьъяшыєшюђчъђэььщфєцчфснлкжзШХДБЉМЃŸёЄЇ№ЎЏќЉЈџЅЅџЄІџЄЇџЃЃџЈІў­Њў­ЊџВАџДВџИИџККќММњООўХФџЩШјЪЩџбаџдгџийџтсџшц§юьўђ№њьэўёѓщорчннюул|q]g\<€sM–‚SЁ]Ќ›cГЁfЖЄgИЅhИЄjИЄkИЄjИЄjИЄjИЄjИЄjИЄjИЄjИЄjЙЁkЕІgИЅl{k@џўџћџџџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiКЄjЗЄgЗЃiВfЃW‰~LjcHДЏЎЛЗМЖВЗСНТаЬбевдбЮагббЦФФшяъѕщѕ§ьљрікSЂK„/%UЏL•ИŒГЭЉмчгёэшђчъѓчэючьышъчфрфливЯЫЙЛЕЯІЄїЅЊѕБВчЎ­ќЄЄќЉЈѕЅЄѕЅЄћЈІўЉЇџЋЉџЋЉўЎ­џВАџЖЖџККџПОџУУџЦХџЧЦџЭаџЯбќжжњонћцхџэьџяюџяю§ёэњююћ№ѓыпхыппчлЯrgLnb@ŒwJ™…VЅ“^ЏœcДЂgЗЃiЗЃjКЂlЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЗЃiЙЁkДЅfЗЄk{k@џўџћџџџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgКЄjКЄjКЄjЙЃiЙЃiЙЃiЙЃiЙЃiЗІgЗІgЖЅfЗЅfИІgИЅhИЅhЗЄgЖЄiЖЄgЖЄgЖЄgЖЄgЖЄgЖЄgЗЅhИЅhИЅhЗЄgЗЄgИЅhИЅhЗЄgЗЃiЗЅhМЃkКЅhЏŸd ^}Nkb@ДБЌОКПШЧЫвбевбгЦХЧЛИКвЭЯЪУЦёэђъэђёыьѓюэJІG ˆ ˆ Œ ‰ ‡ˆ+–"SЉK~ЙuЉЫЂЧнСсмймкЯЪСН­ЊІљЇЌфБИюЋВџЎЃўІІўІІџІІџІЅџІЅўЇЅўЉЇџЋЉўЎЏќЏВўЕЗџЙКџНОџСТўТУџЩЪ§ЯЮќаЯџккџстџччџѓєљыэ§№ђћяэќђђљю№љю№цмм№хсдЪРZQCrfBŠ}Q™‹WЎ›bБdИЁiКЅhИІgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЗЄgЙЂjЗЅdИЁixlBџўџў§џџўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЗЁgЗЁgИЂhИЂhИЂhИЂhИЂhИЂhЗЄgЖЃfЖЃfЖЃfЗЃiЗЃiЖЂhЖЂhЖЂhЖЂhЖЂhЖЂhЖЂhЖЂhЗЃiЗЃiЗЃiЗЃiЖЂhЖЂhЗЃiЗЃiЗЃiЖЂhЕЄeКЁiИЃe­ž`ŸŽ]Œ|Mka?ЕБЌбЭведиаЯбОНПЕДЖМЙЛдЯбЧРУђьёщь№ёыьёьыJІG ˆ ˆ ‰ Œ • ˜ —“”)‘4M˜B^WеЎ ђЏЌ№ВВ§ЉЎџЊЈ§ЇЇўІІџІІџІІџЅЄ§ІЄўЇЅўЉЇџЊ­џЏАўЖЖўИИџМНџТТћХФјЭЪџбаўегјддџццџэьњъы§яёќю№§ёяіььљю№љёђіюярздђъуЉ –h[;~rJ’ƒR WЎšaЙЂjЗЂeЕЃdЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЙЂjЖЄcИЂhxlBџўџў§џџўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЗЂeЗЂeИЃfИЃfИЃfИЃfИЃfЗЂeЖЃfЖЂhЖЂhЖЂhЖЂhЖЂhЖЂhЖЂhЗЁgЗЁgЖ fЖ fЖ fЖ fЗЁgЗЁgЗЁgЗЁgЖ fЗЁgЗЁgЗЁgЗЁgЗЁgЖЄcКЂhКЃe­ž`ŸŽ[Ž|Mj`>ДЏЌжвзХФЦЙИКЖЕЗСРТЯЬЮйджЦПТёьюъыяёьы№ыъLЈI‹ Œ ’“–—šœš˜ ‹i‹UђАБяВЖјВВџЏБјЎЎџЊЊџЈЈџЇЇџІІџЅЄџЅЄўЇЅџЈІџЋЌџЏЎўДВјИДќПНџХУўЦХ§ЪШџЯбўдеўпоџъщџђѓџёђў№ђ§ьяљэыћёёїя№ѓьяїёђђэьпкзёыцtiNocA‡xJœŒWЌ—`ВžeВœbИІgЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfЖЃfИЂhЖЄcЗЁgwl@џўџў§џџўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeИЃfИЃfЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂdЗЂdЗЂeЗЂeДЁdД fД fД fЗЂeЖЁdЕŸeЕŸeЕŸeЕŸeЕŸeЕŸeЕŸeЕŸeЕŸeЕŸeЕŸeЖ fЖЁdЖЁdДЄbЙЁgЗЂdЌ_Ё]{Ll`>ЗА­ТПСЕДЖЛКМШЧЩгвдзджзвгЩУФёыьъьэёьыяъщNЌN’ ’™šœŸ"!Ѓ'"Ѓ*  )˜&&‚3ж­žэИСљДОќБГќБЏї­Ћџ­ЌџЊЊџЉЉџЇЇџІІџЅЄџІЅџЈІћЈІџЎЋџВБџЗЕўЛКўОНџУУџЬЫџбгќжжџъъњыщїээјююњьэџяђћяэљяяњђѓёьюѕ№ђђяёхрсщхфХЛЉdY=znFPЅ\Ќ˜_ГŸeДЂcЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЁgЕЃbЗЁgwl@џўџў§џџўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЖЁdЖЁdЖЁdЖЁdЖЁdЖЁdЖЁdЖЁdЖЂaЖЂaЕЁ`В aВ aБžaА`Џ`Ўœ_­›^Ћ™\Њ˜[Њ˜]Њ˜]Њ˜]Њ˜]Ћ—]Ћ—]Ћ—]Ћ—]Ќ™\­š]Ў›^Ў›^Ќ_В›cГžaЊš_ž\{Lj`>ЙВЏКЗЙПОРЯЮадгееджзеежбвЩУФѓыыьььёьыющшQАU™™ ЂЄ Ј%Љ)Ќ-Ў0­/Љ+ ™+|—eќТНхЛДўЖЏџДЕџБЕџДГџЏЎџ­ЌўЋЊџЈЈџЇЇџЅЅ§ЅЅўЇЅџЈЉћЋЊїА­џЗЗџМПџРТќШШёаЭџеи§лмџшшџђ№ћѓѓїяяћяяўюяћёёѓыыјђѓѓю№ђяёэъьѕђєевдњёшtjXpfD‡xJ›ˆUЉ”]ЖЂhВ_ЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЗЂeЖ fДЂaЖ fwl@џўџўўўџўџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁdЖЁdЖЁdЖЁdЖЁdЖЁdЖЁdЖЁdГЁbВ aАž_­›^Ќš_Њ˜]І•\Ѕ”[Ђ‘XЁWŸŽUŒTŒTœŠUœŠU›‰TœŠUœŠU‹VŒTžUŸŽUЁWЂ‘XЃ•[Њ“aЋ—^Ѓ•[šˆY‡wHh^<ИДЏЫШЪЯЮаеджедждддкиийдеЩУФѓьщыьъ№ышэшчVЕZ !Ё'Ї'#Ћ+$Ћ-&­3)Ў9,Џ@.ЏD.ЋE*ІB&—?фГЃлЛМўСЗћНВџЛОџВЙ§ЕЕ§БВ§ЏАўЌЋўЋЊўЈЈўІІ§ЅЅ§ЅЅџЇЊўЊЌј­ЏэЗЗсРНмРПфТУ№УЦјжзџрсџяёўђђєььљёёљяяњююїя№ѕя№ѓюяѓюяюььѕђєьчщщфцхннЙБЄ`U9ƒvJ“‚OІ’[Ўš`Е bЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЖЁcЕŸeДЂaЖ fwl@џўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ cЕ cЕ cЕ cДŸbВ`Бœ_А›^Ћ—^Ј•\Ѕ’YЂŽWžŒW›‰T–…R“‚OPN‹}M‰{KˆyKˆyK‡xJ†vK‡vKˆxJ‰yKŠzL‹{LŒ|MŽNP“…Qœ…WˆT•‡RŽ~P€pAbY7ЖВ­иезизйзжииииееежддзвгЫХЦєычыъцёъчьчш\Мb'Њ+$Њ2&Б2)Ў6(Б8)Ж=*ЛA,МE/ЛI,ЖG(ЌAS™dџПЧрЛХџФФћРОѕЙПќИЙјЛЗџЖЖџГДўАБџЎ­џЌЋўЈЈќІІћЅЅі ІіРРямйюъхяусъджшЭбфЫЯбДЗфЬЮћцшџіїіььњђђєььїяяі№ёєюяёьэѓюя№ьыяъы№ъыђьэибиёщтdZBuiAŽ}LЃXЈ”ZДŸaЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕ bЕŸeГЂ_Ж fwl@џўџџџџџџўћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaГžaГžaГžaБœ_Џš]Ќ—ZЉ”WЇ’U ‹WˆU—„Q“OŽ|MŠxI„tFqCzlBxj@ug=sd=sd=rb=qaxh>zj@|lBsCŠtJŒyF‡zFƒtFwh:^V1ГБЉзджйикеджзззжжжлййкежШТУѓъцъщхёъчьчшaСg-В4-В=-Й<3ЙH1НH1СJ0УK0СN5ПP6ЕO/ЈF•БƒъФПџУЩіСОџТЧјПТџУОџЛЙџККџЗЗџГДџБАџЏЎўЋЊќЉЈ§ЇЇьегјчфљ№эёэьхуупжйрЯгпЧЯпЧЩкФЦЭЛМїщъњ№№іююїђёєяюіяђђэюђэюђюэ№ьыёьыѓыы№шшнзтыфсŒ„mmc;‰zI›‡PЌ˜^В`ДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДždГЂ_Е cwl@џўџџџџџџўћџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaДŸaЖŸaЖŸaЕž`Еž`Еž`ЖŸaЖŸaЖŸaДŸbДŸbДŸaГž`ЕŸ^ЖŸaЕž`Дœ`Вš^Б™]Џ™_Љ•\ŸŽV›ŒT–‰Q„KŠ|L„uG€pE|kDvd?q^=oZ;lV:cT3bS2_S1\P.YO-YN.VK+VM,RJ3RJ3VL4UM0ZP2ZO/^T2`W2aW9n`C>G?"E= H?$I?'MB,NC-MF-SJ)VO(VS-SP*OI$??'ЊВЋекйиииликизйжийеззмизЬФФэъхёшх№чфёщтgЩu/ПN7ФK6ФS8ХV0ХW=ЫT:ЬV8Щ\<ШV4ОN@ЋTюШЦяЦФљЫЪќЩЧџШЧџШЧџШЧџЧЦџУТўСХџОСљПЙџЙЖѕВЗјХЬњщцќэъџяёфЦЫ{|–so”pj–pnЃzЫЉЏйСЩлЦЯлУЫвСФѕё№№ёя№ъыёэьяыъюъщющш№шшёччяххюффэуургезЪТaV6~rB•ƒNЅ‘XБš\Гž`Гž`Гž`Гž`Гž`Гž`Гž`Гž`Еž`ГŸ^Дž\wkCџџўџ§џџўћћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџВ_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_В_Д_Д_Д_Д_Д_Д_Д_Д_Г\Г\Б\Аœ[Џš\Ў™\Ћ•[Ј’X›Rš‰P•€LwG„oBwg=j_9d]6\O5UH.OD)NB*J@(E=&@:#=7 :6:673:48260:471;0;0;3909293 ;5"73 ?< D<I=%G;)F8%F7:2ЎАЄжлкййймйлйикзйкжиинйиЭХХэщф№чу№чфёщтlЮ|3ХU<ЪS9ЩY=Ъ]7Ы_?б[;г\=аb?Ъ[<ОYXЏkіаЮюЧХњЬЫџЬЬџЬЬџЪЩџЫЪўШЧџШХњШЪџФХќФПџСРпЖНџч№џђєљюъзЙИЁpr mkЌƒzТ “І}tЃqk–rlЧЈЋтЧаоФбжУЬящъыщщѓюэёщщ№шш№ццёххёуфђтуђрсёпрёпррЭађрйgYndвhFеb@жl@жl=жoCвu@ЮkBРg†НŒ№ЮЮѕЯЯўдеџавџгвџаЯўаЯџвбџгЯјабџЮбџЬЫљЪЭйблњ№џџьћЬЌ­’okШЈ›ђкЦъпФфмОъмПЩБ“ {a˜olФЄЅуЩлтЯрЫЛМ№кпєтлёкиђйзёижђжеѓедѓдгєввіввєвгыЪЮьЯЪ‡tYyj<Š|HŸŽUЉ—VГ\Г\Г\Г\Г\Г\Г\Г\Гœ^Б\Г[vjBџџўџ§џџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџВœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Г\Вœ[Вœ[Вœ[Вœ[Вœ[Б›ZБ›Z­˜ZЊ•XЃU™ˆO‘€M†vG{kAqb;g[3[O-O@&K<)I8%B1M<iX1К{OЪbиЃxнА„оЙпТ•пШ›оЫžмЫ лЪŸзЧ™иШšжЦ—дЦ–кЬœзЩ™йЬ”иЫ“йЪ’еЦŽжЦ‘иЦ‘йЧ’зХлК‰сЗ‚сЎ|Э›qЊzVvP0B0ЋЋЋинмлллолнмлнкмнйллплкЮЦЦяшпёхпёцтъфнsиŠ?еkDзg?зnGйiCкsBкqAмsGйs@зjBЧf“Х№баѕгг§зз§гдџжзџежќег§ждџжвївдџбеџгвќажуншљяџџёџП‘˜pkэбРэмСтзЙьпП№пОЩЕ’Ђ~`˜mjǘ•шатуасдММєблёдЭєввіввіввїббїббјабїЯаљЯајабэШЬ№бЮ‹v[zj?Œ{H TЇ–SВœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Гœ^Б\ВœZuiAџџўџ§џџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџВœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Б›ZБ›ZВœ[Б›ZЎ˜WЌ–UЈ’XЁT˜„MŠyFpBte>eY5]P0KE GB!@:B7bM1šwUЭsчЏ€аМŒкЦ–оЬкЪœйЩžжЩвЦœаФšеХ—дФ–дФ•зХ–иЧ–зЦ•жХ’гТеП•жР–иУ–зУ”мЦ–кХ’кХ’иУкШ‹йФ†жР†ЯЛ‹ПЉЄ‹cvaFЧЛЏинммммпмонмолнокммплкЯЧЧюшн№хнёцтщумuлBкqGмnCлwKлtHн{FрwGфuNоwDлtBФw–ОЅяггѓгд§ллџййџллџкк§ййњииџкжјийџилџкиўйнсйфљы§џэџИА•ojыЭКђмРђмРюиМьеЕЬЖ’›|]˜lkО ›цатцаткЛИћЭйіЯЧњЮЭњЮЭњЮЭњЮЭњЮЭњЮЭњЮЭњЮЭљЯаюЦЫђбЮŠrZzi>|IŸ‹QЉ–SВœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[Вœ[В›]Аœ[ВœZuiAџџўџ§џџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZВœ[Б›ZБ›ZБ›ZБ›ZЏ™XЌ–UЈ’QœˆO•JˆvAyj9m`4_S/SH(J?#?5+M8#ˆb?Х–cлЌtсЛ…пЩ™дШžйЪœиШšжЦ—иЧ”иШ“еФŒвСˆеХŠвСˆбР‡гС†аОƒбОвП‚аОдПаС‚ЮПЯР‚аОƒгР‡бО…дПˆеР‰ЪОŽдТиУŒЮЛˆМЈyЋ—n€uZПНЕйоннннрнпонплнокммрмлаШШэчм№хнёцтщуоwнEнtJоrGп{Mо{Iр€JхzLщzQр}Eй…AМ˜БХ№жжѓдеўопџооџммџммџппўпоџрл§ссџоуџсо§мржЬиєфіѓрёПЂЅŽqjЬЏšѓжЛђзМёйНђлЛЩГ—y\›rpШЋЄчдуъефкЗГјУаќЮЧњЪЩњЪЩћЫЪћЫЪћЫЪљЫЪњЬЫњЬЫљЭЬюХЪьЩЦ‹s[yh=}JžŠP­—UБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZБ›ZВ›]Аœ[Б›YuiAџџўџ§џџџќћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›YБ›ZБ›ZАšYАšXАšXБ›YВœZВœZЕ›UЕžZЏœXАšXЏ–XЌ’VЃS”†K}HqCsa#Ÿn@ЫЁtжГ‡нТ–пЪйЩšжШ—еЧ–иОšжС”аТˆгС„ЯМжО‚аЛ}ЫКwЯЗ{ЯК|ЭИtЯЙqбЗuЯЕyЮЙ|ТЕqЪЕxбД{ЯЗ{ЧЙwЩИyзКгЙ}ЧПyзЛЯН~гМ„ЪИ{ЗЉuЊ”j†wPНМИплръофрнпкммулмсмнмооЮШЩъхміурёхсццжZе›FцtRп~IсWч~Iц~IьyRъ€OгЊAЏйP›пyЇжімжњбиџохўттџрнџсоўттџуцџфчћссџъщјыщќєѕЯТЪшгтэахоРЭ•qwšskуРЌэеЗэйКювКОšˆ oeЁvyюгуьйъѕнхбГВђЧФџУХџЧЦџЧЦћШЦљЧЧњШШњШШ§ЩЩџЩЩќЪФчХЦіЫШviI„n>“}IЃVЊ”RАšXАšXАšXАšXАšXАšXАšXАšXВ›WА™[АœUuhB§џџ§џџџ§ў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXАšXЌœYЌ–TА•UГšZЅ“Tš‹M—„Ky@wj>l\1^T,JH&C?&XE*ŽhEеЄvгБƒхטр֘мШ™зЦ•гТвР‹ЯО†еС€ЬК{ЬЙ|ЭЖ~ЬВ|Ч­wШАvУЎpУЎjТ­iЦАiЭЕmФЊdЧЌiХЌfШГhФВeЪВfЦАbХЕhФБhаЏpЯБvФГtаЖtЪЗtЯЗ{ШДsДЄoЇc…tMОНЙзппрпспненцунотооойопеЩУэшйѕхйяхлчфе\еЃJчTх‚Nы}Sх†Gп”GЯЕNЙлK­ѓ@ЈяGžмdеќупыезћтцџхшўчх§ъч§ыьџю№џѓѓџљљџљїџўўџњћцлунЫиуЧкиЧдТЃЌЁsrriАД›‡Ќ‹|œodœpiгЧЧьшѓ№ф№ьейђТСџССќУЦџУУўХФ§ХФњЧХњЦЦњЦЦ§ЧЧ§ЧЧћШЦчТФѓЩФi\<…p=•€IЂŽTЌ–TАšXАšXАšXАšXАšXАšXАšXАšXВ›WА™[АœUuhB§џџ§џџџ§ў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЈ™ZЌš[Ќ“SЄOœŠM’ƒK†uBzf6jZ6VM+EB#J=‰bBжœxхЖŠнХ‘мؘйШ—гТ‘аТŽЮП‡бО…вН€аЙ{ЭЗpЪБkЫГkУ­_ЧГ^ФЏZЧБ_ТЋ[РЋZХЎ`СІ\РЄ]ШЋ`ЩЌ[ШЋZЦЉXХЈ]ЫЋ`ЬЌcУЇ`Ю­gЯЊ`ЪЊ^ЩБeЪЎgФБfЫБnУЏhА eЂ‹[‚pGСОЙнфплпрфхлзссзкпфрпкнсмЪУэщзёсльпнъфбbкЄIщ…SхKуKФЦBГыDЈџIЈїEЊѕ>Ѓџ>˜ьK—Ыњщьмзд§я№џэёўѕђљїіўјљџћћ§џџ§§§џџўћќњџџџџўџФЕНоХгхХжыЭкеВМЂv|›fiЂnn—liЇ„жлвџ§§џћџєёѓЬГБљМКџКНџМТўРРџССўТТќУТћТУќУФ§ФХўХЦљФЧхОРоЙБiX7‰tA—ƒJЄR­—UЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WЏ™WБšVЏ˜ZЏ›TtgA§џџ§џџџ§ў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜V­”TЈ–UЂ“T›ŒN”€I†rCqc9`W1TF)I?!qU6И~ZхЊ|хЧдЧ“гФ–жХ”ЯО‹ЬМ‡ЬЛ‚ЩЗxЩГqШЏiЦ­eУЉcЧЊeЪЉcФІWФЈSПЃOСЁUЩЂ^УЋQОЃLЦЈWФЄYТЅTТЈNТІOШЇWТЋUНЉQНЉTРЋYСЋYЦЌXХ­[СЊ^ЧЋ^УЎ]ХЌbСЋ]Џ\ ˆT‚oBТРИчфрунотттзнтхсчщстцстиЦХэфж№тжюуеюцЯfЬРEЦУLЕсDЈіCЅљ>ЃџAЃџDЁќBЃњ=Єњ;›ю;лкрэонйџњіџјћџ§ќњџўћўџџџўњџџњўџќўў§џўїќћџџџљяѕаОХйЬктгсъйцьлцсайзШЬьсуџ§§јўљњџўїљљшЬЬљИЗџЙЖљИЗџЛПўМНџНОџРРўРРќРР§СТќТУ§УФїСШщРОМ›‹vc>ŒyFš†LІ’QЌ–TЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VЎ˜VА™UЎ—YЏ›TtgA§џџ§џџџ§ў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА™UА™UА™UА˜VА˜VА˜VЏ—UЏ—UД—TЄŽL˜‰JŒ}E~l=s`:dU4OE'K=!›nLйЂuоПŠаЦбФжУЮТŒвК„ЯЖ~ЬДxЧБoЦАiХЌbТЈ[СЇZСЉWПЁRПœRХЃWРЃRПЃNРЂKШЃNЗœKРЂIХЂLФ RРЂQСЉOПЇOУЃXЫЁTЦІZЕ›OНЅSЛŸJХЉTШЉZШЅ\ЧЊYТ­XХЉ\ПЇUА›WŸ…Om>ТРЖррц№ухонпручурщезсррржЪШюти№угюуеђнпhЕю<Єї@žџ<џ@Ѓѓ=Ѓѕ@ЃїDЃњAЁћ?Ÿќ<œ№7’нŸСпєюѓ§ђюћџџџџўџџџјўџџўўџўџўћ§џџџџџџ§џџћ§§џўџђщьжОЪшдсьпэщрээщєёяѕќћ§ўўўџџќџќјфТТјВГџДВџИДџИИўЗКўКЛџЛМџНОџОПџПП§ППќРР§СТѓНФѓЧР’y_ƒmDŽ|GŸŠLЊ”RЌ–TА˜VА˜VА˜VА˜VА˜VА˜VА˜VА˜VА™U­–XЎšStgA§џџ§џџџ§ў§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ™RЏ˜TЏ˜TЏ˜TЏ—UЏ—U­•SЌ“SЃŒH ‡G”}E‚q@nb8[P*\H%oS4ЇxLЬЎвФ“ЬСЮУЮТŒаОƒаДxбВsЭЏnШЋfУІ[УЇZПЄSОЂNНЁMЙ JО GСЂGИCЊ–AЃ•BЅ”>Ÿ‹4ВžeЋ‘DШЈOХ NХЇVИЂJОЇQТЁ[аЊJГ–LЮЙ‚ЬИМЈg FЉ•@МЅBФЇVУЋWЦЈYПЅQЏ™RžƒK}l;СРЖзрэъфщцуорцскоунчюлутжаХярз№хЯючЬѓсаiДш5і8љ7žћ>žќ<Ÿћ< ј>Єї>Ѓђ>Ђ№=žю7–цcЁзѕјџьхтіџџџџќџџўіќџџўџўљњџўџџўџўќќћ§§§џџџџџџўџџєљЮРЦкжмщчэычьљђѕџ§ќџџќёрнпЉЉџЌЎћЈЇќВЎџЕДџЕЖљЗИўИИџЙЙџЛМџМНўМНўООќООћППяМРьПБzgB†oAFЃMЋ”P­—VЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜T­–X­™RtgA§џџ§џџџўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ˜TЏ™RЎ˜QЎ—SЏ˜TЏ—U­•SЊ’PЇŽN›ˆK‘|Em>m_5[P*ZG!†f;ЪŸtлЛ€лХ‘аТ’ЬНŒбР‡ЫЙxЩБoЬАpЦЋaТЈ\СІVОЂNПЂMНžIОŸJК›FИšGП EЛœ?ЇBФЖ…иЯДњ№пџџђџџьВЁhКЁKСŸKУЅTУЋSТЉSЦЅ\ЙЊNЌЃxџќјќћ§џџџџ§§љђсМВƒРЂUУЋYШЊ]СЅQЏ™R‚I|k:СРЖсцхиоыщчнпцуъфпєцаущшзЫСёсдэсеьпзѓкжjАь0˜ѕ3œї4›ќ8œѕ8œњ4œљ4 ј7Ёі;ѕ:šє4•э@ŽкЩтішщчёіљџџћџџќњ§џџўџ§џўџџўџќћџџџ§џџњџўќќќџўџџђёџлнћХЪцЎГкЋ­иЌЋчВЏцЅЄэЅЅјІЅљЌЉџЏЌџБВџЊ­њДДџЗЗќЖЖ§ЗЗџЙЙџКЛџЛМќММњММіНМяНПט‚wi9uA–†KЄ‘M­”N­—VЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЌ•W­™Rsf@§џџ§џџџўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ˜QЎ˜QЎ˜QЎ—SЎ–TЋ“QЇMЃŠJ”|H|mОG̘DМ›EН›>Й›DНЇmџџ№§§џѕїџњ§џџќџрйЎЉ—DЪЋVЦЅVШ­VЦЊSЭЈ^ЗœKрбБџўџўџњћџїџўџџћїдРЁОŸTФЋ[ЪЌ_УЇSАšR‚Izk:СУЗіъиетјъчпнфч№жХиІrцрсрЬЫ№сбьуЯытЮєнЮjАь-•њ/™і.˜ѕ0•ј3œї-›ѕ*™ћ/™ў5™ї9œђ1–ь3‰уОжыієшчыџџј§џљћ§џџќ§јџќљџњ§џўћ§§ћџџћџџџџџ§јљњцсљаЮџМНџЎАџЉЉѓœšўЁžџ џЃЄџІЂўЇЃџЌЊљЋЌњ­АџЖЗўБЏћЕЕўЖЖџЗЗџЗЙ§ЙКћЛЛіККєЛК№ООžoTzp:—~FšOЄ‘MЎ•OЎ•WЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЎ—SЌ•WЌ˜Qsf@§џџ§џџџўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­•MЏ•RЎ•UЌ”RЋ•NЉ“LŸ‰H—Exo=w_;^L/QE!’s@йЎuнО‰ЯП‘ЮЛˆЭИ„ЯЗ}ЭАmЩЏcРЉ^ЙЁYЙŸSЗœKЖšFИšGЙœ9И—6Нš@Йš=Жœ>Џ›DЛJГš>П­rџњўњќџјџѕџџјџџўџјђЌeПЌIЬБVЧЇ^СЌ[НЕXЈ—^џія§џљџћњџџџѕ§ќџ§џлЯЅФ RЩЎWЧАZУЈ^ȘWœ„HuoBТФАофыєшфыиУѓЎWѕ‚№рушкЭЫьташпе№уУпне]Њя4‘ј4˜ё%”ќ*˜ј)—ї(•ї+–ј/˜љ1˜љ0–і0”ђ"Žѓ6‹Щфюџхыц§ђѕџўџћўџќўџњџџџџџџ§џџ§џќўџќўўџњњџэяџзжџЩШўЛКџЏЎџЃЄќ›§œžў ЁџЃЂџЄЃџЇЇџЉЉџЊЊџ­ЌџАЏџБАўЖЊўДВџВЙџЖМџЙЙ§ИЕџКМыЙНСЇ‰f>‰s?™‡HЁLЉ“QЌ–O­—O­–R­–R­–R­–R­–R­–R­–R­–R­—OВ”SЋ˜Oof@џўџў§џџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–R­–RЌ–NБ—T­“QЊ’PЇ“LŸŒI“E†q=wc4XT+\I&œrOаЌ|гП†ЯЛ„гКˆЫЕ{ЩДvУ­fТЉ_НЃWИœOРЂKМš<Ϙ<Й”8­‘%В?К•CК™<МBИ›@КЁ?М›EЗ›DЪИ}џџјљўџћџћџјџїќћџќџубВЕžSЫЊ[еЎjгЎjУЃZЮП‘џ§ј§џљџќ§џ§џѕўћџ§џсзЕИŸYЧДiУАeПЅ_ЙœWЁ‹Ija6ЪЧИёнв№ЂUс‚ф}ш~ъ… хцтрЯМ№пЬѕрбњтФткгgЋц3’я-•ю%“љ.‘ѓ/“ѓ2“є3”ѕ0“ѕ.“ѕ.“і.“љ-Žш7‰тrАдќїљэшпџћџўќћџџјњџџџџџџ§џџўџ§џџџџџџѕіќттџвб§ХФ§ЗЗџЎ­џЂЃќœœ§œžў ЁўЂЁџЄЃџІІџЈЈџЉЉџЌЋџЎ­џАЏ§А­џДЕџГЖџДЗќЖЖџИИпЙЕћКМŒrNj=•H‰HЇ‘O­•SЎ—SЎ–N­–R­–R­–R­–R­–R­–R­–R­–R­—OВ”SЊ—Nof@џўџў§џџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЎ˜PЌ–OЉ’NЋ”PЁŽK“D†uBvg9eX,_N#švNдЈдК‹ЮП‡аМ‚ЩДwЭГmФЋaКЅSЗЂMЛ PН›GЙ–4Пœ5Г.Ÿ…1гКŽИЄcЈ‹@˘>Л™<Р MТœJЪЁXЗ—LФБ~џ§іљў§љ§јџљџјџіџўџџѕу­ЂfГЂQЕ NЙЂRЖžRѓъЯџџўјџіџ§џџќўјџјў§џътЫИŸYШВjЩАjЬАiЛЁU˜…Bmd?бЬЩыУ“ь‚ ђ€ѓ‡ѓ…ђщцтзЮбямдьндясХџшШдеЬВФе}ДпMЂъ!љ"њ#’њ#’ј#’і%“ѓ&”ѓ(•ё*ˆџ2†х!†тКмєщьущъюіџџњџјћџџџџџџџџџџџњќќўљјџюэ§лмџЫЫћППўДДџЋЋџЃЂўœœџœžџž џЂЁџЃЂџЅЅџЇЇўЈЈўЋЊџ­ЌџЎ­џЏДџБВџАВџДЕќБГчПКёКГЛ‹€g;yE›‰JŸŒIЉ”PЈNЌ•QЏ–PЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ•QЌ–NБ“RЊ—Nof@џўџџўџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­”N­”N­”N­”N­”N­”N­”N­”NЎ•OЎ•OЎ•OЎ•OЎ•OЎ•OЎ•OЎ•O­—PЈ’KЉ’NЅM—…FŒ{Cyj~n9nX.†i=ЦŸkпГvХЖxЮЕwСЋjТЈeХЂXɘHГ›CЎ”:­’0ИŽ5Д‘*Ћ”.АŽ5М”.Ѕ‹1гЧЅќ§ћќўјіјјїјќќќќћљјўћі§їќњљ§њћїњќіћћћїћіќџѕљњ№џўњ§јљўўђџќїќј§џўњїјєќћ§їќѓџќїўљј§љјј§єіўєќњљўњљќќі§§ёџљњџј§љіёрукУХХŸž евЮёЩ•№}і~юƒіƒь„цыьъаФѓрНтмХюлЦщмТёйУюмПікМцзФьлКюлИялИюкЗ№кЗяиИяиИэиЙьдИјжВэжЉцеДхЮЈтЯЄкКгОЈјѓєэшщчпрѕуфџстџдеўШЧњУРџКЛ§ГГќЌЋўЇЅ§Ё §ўžžўžžўžžџ  џЁЂџЃЄџЅЅўІІўЈЈ§ЊЉщБЖѕЎБз™‘“mMn9’‚?šƒE†NІMЉLЉ‘I­•MЈŽKЈŽKА–PЋ’HЋ’LЋ’LЋ’LЋ’LЋ’LЋ’LЋ’LЋ’LЈ’JЎOЈ•Lne?џўџџўџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЌ“KЌ’LЋ’JЋ’JЊ“HЇEЄ‹E•=„u=n^3wZ-сЁkЮЏrРВ}Ч­wСЏhНІZШЂZН—IГ›AЂ.Ќ‘6Г/Џ-­“/Ў,И•.З–/Ў’=З bџ§јћјѓќљѕўќћћљљћљљ§ћћћљљќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїќћїўћїќћїћћѕєєюутоШЦХЁŸžвввѕСŒъч|э§‡х}ѕюымбЭєлСѕоОцлРуиФъиСшЯЕщдЙщжБюдЖяеЗэеЗяеЗѓзИѓзЕєзВїзГьеЛщдЕъдАэгЎяЯЌюЫЉчЧЃлС™ФКЂёфдћэчъезщЪЭљЬЯџЧЯџЙЦ§ЛЖќГЏў­ЊџЇЁќЁšџŸ™џ›œџœЃ§ž›џЃ џЃ џЃЂњЅЃђЊЊьААхВАяВЄРŒu“oG‰r:“„?š‹B DІŽFЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЊ’JЈ’JЌIІ•Fne@џ§џўџ§џџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЊ’JЉ‘IЋ’JЋ’JЊ‘IЊ‘IЈHЃE›†Bx:vf1gX*­|NЬЅnЯГvУЏuЦЊmПЉaЛЄXЕ–Gʘ?Д’8В“6Ќ'Г-Џ)А+Й‘8З4Е’0Д—5Ѕ‹1юэуџџјўћіњїѓћњіњљѕќћїћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіћњіўћї§њіњњєєєюутоШЧУЁŸžдввђСіƒђ‚ъ}ш‚ іГdэяїнгЬємРэнЦємИьгБшЫІѓЯЁђХˆъЩ—ъЬЃчЫЂшЮІшЮЉцЮЊыгЏюжВъаЌюдЌьеЈъжЇъжЇъвЈшЯЇтЬЂоЪ›пјаЖ’нФЊімаѓедчТФьТНэСД§ЗИџ­ВџІЌџЂІ§Ђžћ ›§ž›џœŸџžŸ§ŸЃяŸЄъІ­я­ВєЎЏѓЃЂъ–‘ tO”nDŽr<”Aœ‰E DІŽFЎ‘LЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЈ’JЌIІ•Fne@џ§џўџ§џџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЈHЊ‘IЊ‘IЉHЈHІGŸ‰B”€?ˆt=p_.šyHаŸmТАuЪЎqФЌjТІ_ЙžTЕKЏ—=Е”7БŠ'А‹)Ÿ‚'Ї…(В’)Г”'Б’+Г–4Зš8К—=З=ЮЮТјјьў§ѓќњђ§§їјјђћќѓќ§єќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕќљѕ§њі§њіќљєєєюуунШЧУЁŸžдввѓСŒяƒюњЂ8іпЩјііѓыфоеЬтйЫцдНыеМђЮ фСкЎnеЉjлЅ^нЎjуИuцН~хР†щЧ’чШ•хЧ–щЭžєЬ›єЯёаžюаЁэаЄьЯЃьЮэЮ™ыЪ™шШ—жЙŒЭЏŒмДЁёРИћТРќНЙыЗЗщЖКцБКшЌДыЈ­ъІЇщЈЊхЊЎкЋЎшЌВѕЈЏћІЊёЁšа”~Ї^„pAŽy;“>œ†DЁŒHЄŽGІŒFЊHЏKЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЉ‘IЇ‘IЌIІ•Fne@џ§џўџ§џџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈHЈHЈHЈHЈHЈHЈHЈHЉ‘IЈHЊ‘IЉHЈGЇŽHЁŠFš…AŒv†q:n_.ЂzJжЅmМЎlСЈjТЈeКЃSДMЕ—@Д’5ЌŒ-ЊŒ'˜ЪЛƒџќєўєњїьжТБxЇ9Јˆ)І9ЬУ‘њњьќљєјѕ№љіђњіѕќјї§њіњїѓїїёћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓћјѓњїђєёьурлЧЦТЁŸžеггэрањэпэ№ѕюэяэ№јщьєяээыиУёйЏідІъТ’аЌ~ёѕяя§ќьїћѕїјхјџьјўэьтьиЙфО„вšIЯ‡"м‹в•8к@пЃIпЉVоАcоДmтЙpщПtцФxцФ~фС‚уПƒуПƒсНнЖмБ€жАzЮ­|ХЅ|ЩŸzжЁ|зžwЭœvЎŠbk],|j5Šr8”x8˜|;˜€>—†C—‰GŸŒCЃFЇJЉŽKЉŽKЉ‘IІ‘FЃ‘DЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHЈHІHЊŽGЄ“Dmd?џ§џџџўџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЇEЇEЇEЇEЇEЇEЇEЇEЇGЈEЉFЈEІŽFЂ‹G™ƒBx:{e5Žp?Э›gХЌlФЊhПЅbЛІ[КœIЎšCЏ‘2ЕŠ3АŠ,š†ГЄfџія№јїџјћїѓђџћєњщмаИœзХ џќуїћѕњіёћіѓ§љјљѕєљѕєћїіјѕёџќїњј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њј№њїђњїђњїђѓёщурлШХСЁŸžегвѓёёшюљ№ююћѕ№гжоЖЖМяьюфдФфбАыЪœйВ~ячжёїіъјўѕћіюјџ№љ§ьѕљэїўѓќџ№љ§ёјћђїіщюэшиСтОŽлšIж„иƒ мŽн–'нš3пžIфЈOъВYыДcшДmцГtуЕuцЛxмЖvмДyлЏyй­wнБvкБsдАtВUsa&€l2‹s9”w>›~AŸƒCЄ‰FІEЇŒIІ‹HЇŒIЇŒIІGЄŽFЃEЅ“FЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЅGЊŽGЄ“Dmd?џ§џџџўџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЇEЇEЇEЇEЇEЇEЇEЇEЇŽFЇŽDЈDЇCЄŒDŸˆD”~=†q4y_1Г‹VбЈiО­jФЄbМЅZДMЙ—DЏ”:Б3Ў†&Ј†"Š9њ№ићї§ѓіэўєэўќђєјѓѕіњљєѕ§іэџљђќёєћј№§љєћїђїє№њїѓќљєїѕэјіюљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљіёљіёљїяѓёщтпкШХСЃŸžждгїѓђљ№ьєърСТЦЏГОЙИМщхъкЯЫяЯЄрЛ‡маДіњѕ№њџѓњ§шјџщјћѓјљѕ§§№љќъѕљюљ§яњўэјќюїћэћїьііыѓњьђ§ъэёчиШоЕŽе—aсˆЮwалŽм“'оš5уЄBуІDыЋVцВ_сЖgрДgцГjцГmлИvЈ“U^S'mc4yn<ƒv>~A™„@Ѓ‹?Ј?ЋŽIЈGЈGЈ‘FЉ’GЈ‘FЈEЇŽDЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЇEЅGЉFЃ’Cmd?џ§џџџўџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІDІDІDІDІDІDІDІDЇŽFЇŽDЇCІŽBЂŠBœ…AŽy;k1”qFЯЂiУЊdУЁ_ЛЄ`ДžPИšGГ@АŽ4Љ„/В!ŸƒФ­€ќѕђљїяџјыљїіїїщњњшљјъјїэћћэїїыћіѓљїэњјюљіюћљёљїяїіьћћяјјьљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљїяљѕ№љіёљїяѓёщтпкШХРЃ œидгшыѓгЯЮДДКВДОЪСОцооє№ѕргЫіЬ—дЭКыјіђќќєљќэіџюїњяќњьјјьјњэљћэњќыїљъііэјіюіѕфѓќьђљєѓѕёѓѓцђђуѓђчєђыёьрэѕцщючдЯмД—ж›]б‡)бyмл†мн—%пž2шЄCъ­WхГkЏ‰II=_Q'q`-…p2•~:…=ЃŠBЅŒFІŽBІCІBЅAЄŽ@ЈŽBЊŒEЎ‹GІDІDІDІDІDІDІDІDІDІDІDІDІDІDІDІDЄŽFЉFЃ’Cmd?џ§џџџўџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЉŒBЅŒB “GЉ‰@Ј†@’>…q7xa/ϘZУ aФІeОЅ_З TВšHБ•>А‘6Ѕ)Б‰#Г‚&Љ†“{#ыЯАџєьѓќшљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљїьјіьњїяњіёїєяѕѕяѕјяєјэєі№іїюіїэјјьјјьљјъљїьљїьіљщїљэѕіэіѓяјѕёїєяїіьјјьїѕэљіюњїяђячрнеФСМŸžšгдвЛКОЕЖКРКПмвиѓ№ђщяюјљїобЯйЭСѓіэшљіщќџьіџѓѕџёїќэљљюѕјяіљяіљьѕјъіјъѕљшєјчѓїцёѕчђіщђішёѕч№ѓщ№ѓчюёхьяшщэшьэфььръъфьыхччыцчйбвкВŸа›iв†4иwл{лŽмЂ;Ў{5;&QE!_Y$ti/‡s9˜A†BЁŽCІCІCІCІCІCІCІCІCЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDЇŽDІŽBЊCЂŽ@md?џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІCІCІCІCІCІCІCІCЉŽDЇŒBЁŒAЅŽCЃ‚<‘{9q6–sAЧЂdЦЃcНЂ_ЖžVБšLА—AЏ’7­Œ/ЈŠ!Њ†"Ј‡ЇŠ!œƒš‚0їуЪїїёљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљіюљїэљїэїѕыћіэўљ№ћіэјєщќјэћѓьќѕь§іэњѕьљѓьљѓюњђђќєє§єёњєя§ї№јіыѕѕщљљэїјюѕіьњј№їєьєёщэътпмдРНȘ—“вгбОНПЩШЪыхъњѓјѓђєђјїьэызШЦюютњџћьњјыїћюєћєїќэіљхѕєьјњщѕїъіјюїњэєїъяђъюѓяђїьяѓъэёчьячьэхээхээфььсыыфщьушыпщщошшошшнхфхыъуххоцпмуоттшукчсбвйУЇжЗŠЗcE<(I> fV,u`,Œv5šƒ7ЃŒ<Ђ‹=ІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCІCЅAЊCЂŽ@md?џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЄDЇŒBІ‰?ŸC›;w7xm1МŒXУЃbПЂ_ИŸWБ™MЏ—CЏ”:ЎŽ/Љ‰&Ђ‚Љ…!Ї†Ђ‡ЇŒЃ‰ЃLћянјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьјіьієьїєьљїэњіыјђхќєчџїъўєъќіыќіыќіщњїщјіыјіьієьѕѓыћјщіђчњєяњђђљёёљђяѕѓщљјъѕђъњїяјіььъркзЯКЗВ‹абЯчххђђђїєії№ѓѓђєчэьомлЫЙКЁƒ‚ФВБмизьё№ёѓєѓѕіюєѓьљїщѕѕчѓѓчёёхяячюёщ№ѓщ№ѓшяђшюэчэьчэьъяюшэьхъщушчфщшуцъсцщрхшнтуоуфнтунтуйопхпфтпсопуилриногкекпойиситжевЮЬРКОВšЋЁy_š…HЇAЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅŒBЅAЊCЁ?md?џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ŸŒAІŒ@Њ‹@œ‰@”>‰t6‡o3гfИZИžXЕœRБ™GЏ”=Ў1Ћ‹(Ћˆ!Ј‡*Ї~!Њ~!Ў‰!Ћˆ!Ќ‰'ž‡$НЈjїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыїѕыћѕюієъѕѓшѕєцїѕъќјэўіяљёъѕє№єєюѓєыѓѕщєїшѕјщіљъїїщђђьјљ№їѕэєђшњѕь§ѕю§ѓь§ђюјіьієъ№юфхрзЯЬФЏЌЇ†…аЮЭїѕєђђђєђђђэялногйирлк{egpGLsNPnLMjHHnONuuЎЅЂЩЬЪофухыъыё№ыё№ъяющэючыьхщърэыпьъпщщршшучшфцчхфцхфцптцстцфучурттпстпспорсртзмнинмпроплкуолокемизолнбкзжлоежраЯимигжЩЏЃŠXЊˆFЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЄŒ@ЉŒBЁ?md?џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ ‹@ЇAЈŒ? „=‹};€n1Б…JЮЂcЖžVЖSД›KА”?Ќ4ЊŠ)Љ‡#Љ†ЁƒЈ~ВŒЊ€З‰1Б‰ЈŠ+Ѕ‘Cієъієъієъієъієъієъієъієъієъієъієъієъієъієъієъієъњєщњіыієщѕѕщіїэёђщ№эщїѓђђѓщѓєъііъієщљѓшћђшќёщ§ђъњђы§іэїёцћјъќљыѕђфієщєђшјіьёяхяъсхрзЧФМ ˜yvrЯЭЬёяюёђ№фффомммммеззЭССsTU€RX}UW{XUzWS{UQ€WUUV€VW~SV|UW‰jkЉ•”ЧРНжйзкхтоэщсцхушчучшрфхпуфпфхпфчнтхлууйопйнопортпспмомйлпмоймсжирейобжйдймгзмвзкейккжеилвдегнжйЪКЉœˆOЉ@Њ‡=ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ЄŒ@Ј‹A Œ>md?џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Є‹AЇ@Ё‡:Єƒ=…v7ƒm3дžbНšVДRБšLА–BЌ‘7ЌŒ-Љ‰&Ї…!Ѕ„Ї†Ѕ‰Ѓ‹Ї…!Г†$М  ƒ.пЯЅїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшїѓшњђхљѓшљїьіѕыюяхѕєъњјюіђчџіъїъкчкФйЮАгЦ бФ–аТ‘ЯСжХžлЫЇтжКѕъжіярёяфіњяяѕъєђчёяфъцлеаЧЗБЊ”‹mihШЦХцффоррмммпннтррронЈ•’Œdecb„c`Šd`c`‘b^Žc`ˆb^‡b^‹db‡`^‡`^‰ca‡da„a^ƒaa‡eeЉ”“Т­ЏлЫЬчннцстссслрпенмйпокрпионзнмекййонимнейкппглкжкккжииежкедожездзЮизгевдоевИЉˆš‡DЁŒ7 Œ5 ‘;ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@ІŒ@Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѓ‹?Ј‹A Œ>lc>џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?ЅŠ@Ѕ‹>Ђ‡7›;…r5œxBгЄgØNЏ™KЎ•E­‘<­Ž3Ћ‰+Ї‡$Ѕ‚  €›{"”}šƒ žƒ!ЎŠД+Ј’Pќіыіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчћѕшє№хѓёчєђшѕђф§їфљ№еуйЛЬР†ЪО„ЫП…гФŒмЬ—увŸхгЄфвЃфа увЁиЪ™ЧНЧП—кдЗячжјяцђ№хѓяффреЪЦЛ­Ї „€{SONГББфсусуфсуфхрсфрпрке—|xljpl›ql”ni‘njpkpj“qk–pk•mh™qlšrm™oj›njplŸomœlj”ni—rn’rm‹njŒsoŸŠˆНЌЉвУРтгбхйзрлкопнвзевзжжлкдйиоамлбнжжжвмаЯкабжйезиийЯзижмв⊘~™ˆEžŠ3ЁŠ<ž‹B˜;Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?Ѕ‹?ЂŠ>ЇŠ@Ÿ‹=lc>џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>І‰?Ђ‰9Їˆ9}6r9ИˆTПš\ДšNЎ™H­•CЌ9ЌŠ0Ї…'Ѕ‚! € €ПЅcЛVЏCЋ:˜“{#цжВяђуіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчіђчѓђфјіыёяхѕёцўїфхкМШКЫЙŠсШœфЭŸшдЄщиЇчиЇчйЈчлЋшоЎэнВьнЏюпБюоЏэнЎнЬ›ЮНŒшзІьъпышкйеЪОКЏ—okfVRQфттъцыуфшпстыцчхсрЭФР›}xВ{x }sЄwЅ}xЄ~zЄ{Ё{wЇ}xЈ|uІvЅ~vЃ~vЂ}uЂ~vЂ~vЂ~vЂ~xЄ~rЅsЅ~uІ}tЈ|uЈ|uЋ|xЋ|xЃ{}šxyЂŠŠЭРОойилйиийзеждЯиегйидебикЮкзгзанжвнеижзЦЩ™‰_™‚6І‡8Љ‡AЉˆBІ†=Ј‡BЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЄŠ>ЂŠ>ЇŠ@Ÿ‹=lc>џ§џ§џўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЃ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<ЄŠ>Ѕ†;˜ƒ8‹z7Šn2мЁiА˜PЏ—EВ•KЊ‰:Ў‘.ЊŠ+І|)Њ†”zУЇ~іђчѕ№чђ№цѓёцђђтѓёпњіфї№пѕёцѕёцѕёцѕёцѕёцѕёцѕёцѕёцњѓфѕёцђ№цѓёцєётіђрљѕуєђрњёуєючѓёчђюеаФ”ЦЕvнШ‹цаœугžхдЁхзЃчиЇщйЊъл­ьнЏэоАыоВэрДэрДэрДюсЕ№уЗънБйЬ ОЕнжНЬЪРЏЏЉ„…|a_Uœ–ѓщщющъщъюхщфшьчышуаЕ Ц„Ћˆ„Ж‰…Ж‰…Еˆ„Г‰„ВŠ…ВŠ…Џ‰„Џ‰„Г‰„Г‰„Г‰„БŠ‚БŠ‚БŠВ‹‚В‹‚Б‰„ВŠ…ВŠ…ВŠ…ВŠ…БŠ‚Г‰‚ДŠƒЌ„А†ГކЫИЕлйплсмучмхсэптъкрпмркийзнзмлдзркЯЬЪВ…s2Št:˜|?Ѓ‰<ЅŒ6Ђ‰9Ђ‡=Ё‰=Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѕˆ=Ѓ‹9Ђ‰9ja@џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЃ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ђˆ<Є…:›‚8‰x5šx=гœcЏ–N­•CЉŽ>Ћ:Ѕ‰$Є†!Њ$ЅƒŒx№пИѓэрјђчјђчі№хі№хѕяфѕюхѕэцєёуєёуєёуєёуєёуєёуєёуєёуѕятіѓхє№хђюуіѓхїђуёюпѕєцєяцјѓф№шЫМБ…ЫЙ„тЮ•цв›пЯšфдŸхдЁциЄшйЈщйЊъл­ьнЏюоГэрДюсЕятЖятЖэрДятЖёфИънБрЯžЕЇ}ИЏ”ЉЃ–}zvUSSкккя№юёющщыыучьхшэђцкђЯЇ§Я™јаŸяЯ”ыЩ“фТ”мЖ“дЌ“ЭЂ“Хš‘Т•‘У™С™Р—ŽР–Р–‘О–‘О•’О•’Н–ŽН–ŽН–ŽН–ŽМ•Н–ŽП•ŽП•ŽМ—У•ŽН–бОЛфпшкммчъсшхю№ьђјєѓ№ьчћѓѓ№фъђфшыриc\It`)ƒm3”|: †9Ѓˆ7Ї‹>ЄŠ>ЁŠ<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѓ‰<Ѕˆ=Ѓ‹9Ђ‰9ja@џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ё‡:Ђ…::…u2АˆMТ–WЏ’HЊ’@Ћ‘7ЉŽ4Ђ‰!Ѓ„ЉЁ}:ї№мјіої№сѕыфѕьтї№піђпђюуѓыьѕятѕятѕятѕятѕятѕятѕятѕятђясіѓхєюсѕяті№уѓяфєђчяэу№юфюцШМЌwжПфЬ’тܘтбžобфдŸцеЂчйЅщкЉъкЋымЎэоАюоГюрЖясЗ№тИѓхЛ№тИюрЖёуЙясЗэкЇдХ”ЌŸyŒƒo{tqrnsёѓѓьѓьіяьђюэь№ѕюяыєрНћв“џд‹џжње™ње™ње›ћеŸњеЁќжІњжЈњжЈьШЊщФЈфОІоЖЃжЏ аЇžЫЁšЦž™Ч —Ч —ШЁ˜ЩЂ™ЪЃšЪЃšЩЂ™ЩЂ™Э œЯ ˜ХŸ“йЦСфмцъцыющцђэюєхщєчхєшфїшціхщ§щюџюыШЛ­^J!l3Œy0œ„8Ѓ†;Ѓ†;Ђ†9Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ѕˆ=ЂŠ8Ђ‰9ja@џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ёˆ8Ÿ…9œ}8†s0՘[ЕLЏ‘DЉ;ЇŽ.Ё‡)Ё‡#Ђ‚ІzŸvТЏrёьыёђоёюпѕятѕ№сєюлјѕріђпѓэрєюсєюсєюсєюсєюсєюсєюсєюсёяфѕятєэмјётєюсюьсѕ№чѓяфящЬЗЈzеП~хЫ…чЯ“сЮ›мЭœфдŸхдЁчжЃчиЇщкЉылЌьнЏюоГяпДюпИярЙётЛѕцПѓфН№сК№сКьнЖмбЋнбЉЙЎˆˆ€cjdWЪЧУѕє№љљѓјѓєє№яюёѕ№эпјйІџзњд“је“ќгœќгœћдќдŸќж ўиЂќиЂ§йЃ§мЏ§лА§кВћиЖќиКњзНљдОјгНяЪМыЦИуОАмЖЊжАЄвЋЂаЉ аЉ ЯЇЂеЊЁвЏЁкЧРёхы№сщьлоёфтћцшљхфќщцћчц§щюљхъћщшџяш™…lhZ&ƒr)’y/ <І‡<Є‰9 †9Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Ђˆ;Є‡<ЂŠ8Ёˆ8ja@џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁ‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ÿˆ8 ƒ8™y7u3бЁaЋŽD­@ЈŒ8ЅŠ/Ѕ†+Ё"ž{Ї|ЁzЬЗsєэйѓэцёюряэлѓ№сђьсђьсђьйјіиѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюп№юуёьніямѕюнёюряэтѓьнѕьиХЙƒЯЛ‚рЧ‰хЬŽмЪсдœрЮ™ъеžцеЂчжЃшйЈъкЋылЌьнЏюоГ№рЕ№сКётЛётЛєхОєхОєхОєхОярЙтйИЯУЁСЕ“—qnmXѓїьїїїјєњьїѕёіѕјїћњщмјЬџб“ѕг—іи—ње™њдšњдžќеЁћдЇњеЉќеЎќеЏћиЌћйЎќйБћкГ§лЗќмЙњлКњлМ§йЩўкЪџмЮџнЯџна§йЯљеЫібЩыЫЦцУЙлОАбПДцжајпуњпуњфпћчцќшчљшхјцхљшыјъьћэюѕщчяоеi]5zl*Žw3›|7Ѕ†;Є‰9Ёˆ8Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ё‡:Ѓ†;Ё‰7Ёˆ8ja@џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7ž‰7Ё8“w6ž{;а ^ІŒ?ЈŽ:Ј‰4Ё„/І„+Ѓ€Ÿ~Ё~šx’{Ђ–NцлЛ§ямїьфёшф№ьсїђуєэоѕьпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпяыріяоєэкѕёпьынєёт§єйгУŸЩДpнЦˆоЧуߘмЮ”мЮ”щиŸфߘцеЂчжЃшйЈъкЋыл­ьнЏюоГ№рЕярЙѓфНѓфНєхОѓфНєхОєхО№сКшкАрЯЈЩЙ”Єœ~ЛНЉїџѕіљ§јђ§№њњёіѕњєщџхУўЯ—џд—љв›ње™њдћеŸњеЁћжЄњжЈљжЊњзЌћзЏќеЕќжЖ§зЗ§йЛќкНћлОќлСћнТ§мЩ§лЫўмЬўнЮџобџпдџпжџпжѕлеўпжџтйёнЬŸŒwџфнўпт§чтјцхјцх§юьішщіъъіььєъъњ№№ўђђИЎ–m^-‡q0™}64ž…5Ёˆ8Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ…: ˆ6 ‡7ja@џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7‰4Ѓ€7x6Ў‚EЧšVЃŠ:ЃŒ6Ј†2Ё….Є€"Є}ž~ž€Ј†šz •z‰s!ЮЗјуШ§ѓтэщжьыжєьпєчхёьнёьнёьнёьнёьнёьнёьнёьн№ънј№пѓьйђярыынєёмѓхСКЃqоФнШŠнЪ‘зЦŽуа—хв™тб™фдŸхдЁчжЅшйЈъкЋыл­ьнЏюоГяпДыпЕ№фКёхЛђцМёхЛ№фКяуЙьрЖэоАхеЇгРšДЈѕѓщ§ўњџўіџџѓџѕрђхЯёиАјв’њв‘§зќгœ§б›ћз›ќзћзЁќзЅћзЉќжЌћзЏќзБ§зЗўиК§иМќйПћйСњкУќлЧќнШќмЩ§мЬўнЭ§наўогќндќмжњнжћслўой§кзпЧГfT/ыаЛџшшічфїчшїчшєцчјъыїыщјяьќђђёщъящюџія‘‚b{h+–~2œƒ3Ÿ…8†6Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ…: ˆ6 ‡7i`?џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7™ˆ2Ѕ7Žx6КˆLО”MЃˆ7Ÿ‹4Ј„0œ‚$ЃЇ›yš|žxЋ~Љ|Јƒ”wAриЉіёмяырёыођьйёэлёэлёэлёэлёэлёэлёэлёэлђьпёщиї№ншшиюётэыгЮО“ЮВuлС…лЧжШрЭ”фЭ•хЮ–сбœмгЁхдЁчжЅчиЇщйЊыл­ьмБюоГяпДэсЗяуЙютИ№фКђцМёхЛёхЛютИцпДцй­иШЃлЭЛџ§§ђцфѓфЪъжЇўгђаšџд•џећжœяб ѕг˜џлšќвЃ§гЄ§еЅўеЈ§жЉџиЌўй­џкЎ§йГ§мЕўлЙќкМњйПљкСњлЦќмЩњмЩћнЬ§оЯќпбќогћоеќпиќпкљмзџомџмоЙž‰k[,™„eљфтэшхіцч§ьяљшыјъыћюьјэщїыыћ№ђёюїњяђюнШ‡t;{*›‚2†8œ‡6Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ђ‡7Ё„9 ˆ6 ‡7i`?џџџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁ†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6 „7›ƒ7“u.Ъ\Ћ‘=Ѕ…9Ёƒ0Ђ‚)ЅЂ~ ™v  {Ј~ Ј}Љ~›…Ќ‡š€аУэыйѓыкїюкьэйђыкђыкђыкђыкђыкђыкђыкђык№ънѕюеёчньъпюъзєфРИЅbиТ€йФ†лЦ‰оЩŒпЫ‘рЭ”тЮ—тб™фвхдЁчжЃчиЇщкЉылЌьнЏэоАюпБясЗясЗ№тИёуЙёуЙёуЙ№тИясЗцсАхкЎсЯЊсвВУȘÁyюа—џгўв—ќд“је‘љд–§е›ќгœљеŸіжЁ§жЂўзЃ§иІ§жЉќжЌ§жЏ§иВўиЕўиК§йЛџкОџлСџлУўлЧџмШџнЫјлЭљпгімељмеџркќкдќплђнлћмпќклўсвš…eqc!{h+еНБєцъџыућцю§юіѓыфїэцџыї§чљўьѓћыђћыџљюіФМ”Šz.Ѓ…8ž|6Ђ„=Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ё†6Ђ„5ž†2 …5j_?џўџџџўњ§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ …5 …5 …5 …5 …5 …5 …5 …5Ÿƒ6™5”v/а–bІŒ8Ђ‚6 ‚/Ё(Ѓ~Ђ}œz}œz }|œ|Є€ЎšyэлМёьнёшкѓъжьэйёыиёыиёыиёыиёыиёыиёыиёыияълєэдђщмэъмђюжоЬЇР­jиУиУ…кХˆнШ‹оЪпЬ“сЭ–тб™увšхдЁцеЂшзІшйЈъкЋымЎьнЏэоАэрДюсЕятЖ№уЗ№уЗятЖятЖюсЕысБымЎхгЊоЬЇЭРšЪИ‰єд™џв§Я•њб“ље•ўж›ўгš§б›§е ћжЂїгЃјдІјеЉњзЌњжАќиДћиЖќйИљкЛјлМњмПњлТњлФњкЧњмЫћнЬџоЯџлЯџмвџмвџоеџндџржџсжћпиџрзџтзƒkGyh%€g'–~Zћщо№щьёъяёщщњ№щњюшїюыєѕьщѕуіішэёьѓє№ћїп \˜5Ѓ‰5Ÿ†0 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5 …5Ђ„5ž†2 …5j_?џўџџџўњ§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4–1–x1жfŸ†0Ÿ€1ž,ž$Ÿšyž{zzšx šzЁ€Ћ„Ў~•uњшЫьчиѓънђъйыьи№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№щиѓьгђщлыщзєэвПЏЬЗsиУкУ…кХ‡нШ‹нЩпЫ’рЭ”уߘтб™фг хдЁчжЃчиЇщйЊылЌымЎьнЏьпГьпГэрДюсЕюсЕэрДэрДьпГясБэлЌьиЉтвЄмЭŸмЧ”ёб–џг“ўд™ћг™іа™ћд§дџдŸџиЄ§зЁћзЉќзЋћи­ќиАќзБќиД§иЖўйЗјкНњмПћнТћмХћлШќлЫќнЮ§наџнењкдљмијмлљлк§олњнијозћузџреівЪmV)ƒn*Œq.ƒj*ЮЗ—ўшэјыщѓэцљёёїъђљьєѕьяјѓ№єѓѕыђэ№іѕљђї№мЫ•}C›ƒ1Ÿ†0Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ÿ„4Ђ„5…1 …5j_?џўџџџўњ§џџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3 ‚3–1˜x/й iš+Ÿ~.›(~!–z™z zžt Ђx Ѕ} Ј€Ї| š}ž} ˜….іыЫяыияци№хзюъи№щж№щж№щж№щж№щж№щж№щж№щжяъеђывёъзьше№щШБŸjжРyзУ|йТ„йФ†мЧŠмЩŒпЫ‘рЭ”тЯ–фа™хгžцг цеЂшзІшйЈщйЊылЌьмЎьнЏэоАюпБюпБюпБюпБэоАэоАэнВъкЋьлЊчиЇхжЅсЮ›эߘѓЮ’ѕЭŒ§жŸібњдўжœџе џжЁќжœљжЊњзЋћи­ќиА§иВ§йЕџлЗџмКћиО§кРўйУ§кЦџлЫџлЭџлвџмгџлбџнг§оеўрлћмлўпоџолџпйѕмкџллыЩЙoZ&ƒm,Žr+’x+’yAђрйџђяїыщїээњэяџђєіэъїєьџшђџѕёєѓяњѕїљыпЕŸk ƒ2Ћ‡/Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ёƒ4…1Ÿ„4i^>џўџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3 ‚3—€2˜x/зžfš(ž~+š|#ž~—|˜wžw Є{›u–u”r“q—ƒ5НЋlдЭŽђьеычдюхзїъкяшдяшдяшдяшдяшдяшдяшдяшдяшд№ъгёщвющдяъеыпЛДŸbкС{еСzиТкУ…лЦˆоЩŒоЪпЭ’сЮ•уа—убœхгžчдЁчжЃшзІшйЈщйЊъкЋымЎьнЏьнЏэоАэоАэоАьнЏьнЏъкАьнЏшкЉфжЅфжІчжЅыеЁоУ‹ЭХюфЬътбчтЩщрХчкФцйУхнРѓйЕѓиЖѓиЖѓзИѓзИђиКѓйЛєйОњмУћмХћмЧњмЩћмЭћлЮќмб§нвћоаўсв§рбџуићокњлмўпоўойњлтџйржЗ–n["~l-w+™3x0ЖЊŽћящяьюэёы№єщѓэюў№ћќэѕєфнеЧЊНЌtЇGЂ‚7ž€1œ†85Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3Ÿ„3 ‚3œ„0Ÿ„4i^>џўџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ‚3˜3™y0ж›c˜~$œ|)˜{ œ|˜{wžv šy …mЎ›^ЬМятЎњыЪѕчдюьЭъукђыкюфгюхбяшЯяшдяшдяшдяшдяшдяшдяшдяшдёщв№цдьшающдтжЎНЅcйО{гОzзС€йУ‚кХ‡нШŠнЪпЫ‘рЭ”тЯ–фЯ›убœхгžчдЁчжЃшзІъйЈщйЊылЌылЌылЌьм­ьм­ьм­ьм­ылЌшиЎъл­циЇциЇфдЅфвЃшеЂкЦФН‹єщЮ№чйьшЯђьЯѓшвђчгѕэаѓшвђчбёцвяфаэтЮэсЯэсЯютаюрЩюрЩюрЪэоЫьмЫьмЫылЫылЫцЯЧуЪКюгОќоЫ§пдњмзџтнџожџпаџпвЪЈzxa)€n-“}/—{4–1–}=ѓлХџёњєяютоЫЩО БŸp˜ˆC”|4š7„4ž†.Ÿƒ.Ёƒ4žƒ3œ…/ ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ƒ2 ‚3œ„0žƒ3i^>џўџџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1 ‚3˜/œ}2е›`–|"˜y$—z™z—zŸužs “u)ђцТ№щкьъвђхеъсоъщдъсиячађчгьхбюъбэцвэцвэцвэцвэцвэцвэцвэцвёца№цеьшаэцвраІТЈbйЛzаНzжРиТлХ„лЦˆлШ‹оЪпЭ’сЮ•тЮ—фЯ›фвхвŸчдЁцеЄшзІщиЇшиЉщйЊщйЊщйЊщйЊщйЊщйЊщйЊъиЉчиЇхзЃъйЈчгЄтЮžубœоЮ“ЧР‰ѕщбэуйъхаюъЮёчжяфжэшЯычдычеычеычеычеэцеэцеючжючгючгючгэцвьхбьхбыфаыфаЪЕqЃŠ:ЊŒ-Љˆ'І„*І„0В‘;Е“9Л›YбЇlР”_€a*ƒo(’},ž6›4˜„,ЕœV˜\˜€8˜~*Ђ†1œ‚.›…-Ѓ‰/ ‚1~/Ÿ‚1Ђ…4š~1Ÿ4Є…6Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ2›ƒ/žƒ3h]=џ§џџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ2—~.Ÿ€5е›`“y•v!—{–w–yšoЂt˜zŒz!њыЫыожэцвючЬыхичъЪђшжяфФјьдыфгщхвэчаэчаэчаэчаэчаэчаэчаэча№хЯяфжьшаьхбоЬЃРЇ_зЙxаНzеП}зС€кФƒкХ‡кЧŠнЩоЬ‘рЭ”сЭ–уߘхаœфвцг хдЃчжЅчжЅчиЇчиЇчиЇшйЈшйЈшйЈшйЈшйЈьзЃыкЂшзŸхгžщвЂыдЂуа—йЪ‹ЦЛ‚єфЭюсйэцвэшЯюуеяузячаыхЮыхЮьцЯэчаьцЯьцЯюцЯюцЯьхвьхбьхбюхбюхбяцвячаячаеО€0В+ДŒ"Џˆ Ї‚ Љ…!Ѕ›€ЈЬ–aƒ\(Št&’|*€/ž4š‚0™€0œ‚5Ÿ2Є„1Іƒ-Єƒ- ‚/‚1ž€3Ÿ€5Ÿ„4—€*œ†.Ÿƒ.Ÿ,Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ‚1Ÿ2›ƒ/žƒ3h]=џ§џџџўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџž0ž0ž0ž0ž0ž0ž0ž0Ÿ0–‚+š/в™b“v!™u”w•u™q’s•tšs’|ьржушЩяубьъЬэтЬётвюхбяфЮђуа№чгтцЭюцЯюцЯюцЯюцЯюцЯюцЯюцЯюцЯщхЬіха№фЬъфйлЯ­НЅYлНvЫК{жО|иР~йУ‚лХ„лЦˆнШ‹нЪпЫ‘рЭ”сЮ•уߘфа™фвхгžфдŸхе цеЄчжЅчжЅшзІшзІшзІчжЅчжЅыдЇцг чзœхеšфвуЭхаиУŒФК‹ѕшШ№фвыувычЮьшЫьхЬёхгюцЯюцЯюцЯюцЯюцЯюцЯюцЯюцЯѓхгшргщчЯьчШяфжыужыцЧцмДТЃXЉˆ8Ј„,А‰'Џˆ ­†Є‚Ђ‚ЄЖ„$НY~d(Šs#—z0˜/ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0 ‚1ž‚-›€/g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџž0ž0ž0ž0ž0ž0ž0ž0Ё€0–‚+™~.еœe’s—s’u“s™t Žr™z›u‡t іщгчыШ№ташщЩэчЪючЬшцШяыЮяуЫырЪышгэхЮэхЮэхЮэхЮэхЮэхЮэхЮэхЮъцЭёуЭ№фЬшргузЕИЁVжЙoЯО{еОzзП}йСкФƒйФ†лЦ‰мЩŒнЩпЫ’пЬ“сЮ•уߘтб™убœфвхгžфг хдЁхдЁцеЂцеЂцеЂхдЁхдЁцвЃче фгšса—цбтЭšтЭ–зУ‰ЪП“ђчЧюуЯъуаыцЭычЪьхЬ№фвэхЮэхЮэхЮэхЮэхЮэхЮэхЮэхЮъыСшфЫѓыЮ№нЗоУžФЌxІ‘@‚'ЉŽ,ЈŒ'Џ)ЎŒ!Ћ‡Ћ‡ІЁ~ЂЖƒ%НŽX~d(‹t$—z/˜/ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0ž0Ÿ0ž‚-›€/g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-------- /—€*˜}-иŸho•qsp–t•w–ršp ‚h їсШяфШљмзюсбёсаяфацуЮчхЭёцаѓцаътЫьхЬьхЬьхЬьхЬьхЬьхЬьхЬьхЬшцЮятЬюфЬъувьтРЕžZбЖlЯЛtгМxеОzзП}иТкФƒйФ†мЧŠлШ‹нЩоЪ‘рЬ“сЮ•тЮ—са˜тб™увšфбžфбžхвŸхвŸхвŸхвŸхвŸфбžсатг›тб˜тЮ—тЭ™тЭ–сЭ“ЮМ}гЪŸёцЦэтЮьтаъхЬъцЪыфЫюуЯьхЬьхЬьхЬьхЬьхЬьхЬьхЬьхЬщуЬэцвЭР’Ј“B­4Б”2Й—3Р”5А“'В’'А%ЌŠЉ‡Ј„ЅЄЁ~Еƒ+КŒV~e'Œu%—{.™€0ž€/----------------------------------------Ÿ0ž‚-›€/g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-------- /—€*—|,кŸgŒn“opp •r Žl–o žt ‹n‹t(šŒ:РЃfгЛ—імЗѓоОюцЯтоЬщрЬэпШютЪэуЫэуЫэуЫэуЫэуЫэуЫэуЫэуЫхуЫюфЬьтЪъхаяхУЛІiЮЕkбКnдЛuеЛxжП{иР~иТиУ…кХ‡лЦ‰нЧнЩоЪрЬ’рЭ”сЮ•тЮ—уߘсЯšта›та›убœубœубœта›та›свšмЭ•рЯ—уߘоЩ’сЭ”пЬУБpоеА№цШьсЫытЮъуЪыфЩыфЫэтЬэуЫэуЫэуЫэуЫэуЫэуЫэуЫэуЫэтЮђфЮШЖЋ9СŸBЗ™:Ř6В5Ж-АŠ*Ї„#Ї„"Ї…!Ѕ‚Є€Є }Й…2Е‰N€g'u(™|+›€/.----------------------------------------ž€/,š.g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€, /—€*–{*ж›crmp Žo l ”qht›z‘ru™vŽu‹n ”}/цйЋьчЮщсЪюуШютЪьтЪьтЪьтЪьтЪьтЪьтЪьтЪьтЪцсЬьуШщпЧчсЪюхФЪЙˆПЉbдНoвЙsдЛuзНzзР|зСиТиУ…кХ‡мЧŠнШ‹пЪоЪпЫ‘рЬ’рЭ”сЮ•сЭ–тЮ—тЮ—уߘуߘуߘтЮ—тЮ—пб–нЬ“сЭ–тЭ–рЩ‘рЬ’зФ‡РЎqшпО№хЩьтЪьсЫщтЩъуШэфЩьтЪьтЪьтЪьтЪьтЪьтЪьтЪьтЪьтЪ№уЩэрРНЋlГ•<О—BД“=­”2Џ–0ЖŽ.Б‹+Ћˆ'Ј…#ЃЄІ‚Ё||П‰<Ў‚Ei'v)™})š€,œ~+œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,œ€,.œ€+š.g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ›+›+›+›+›+›+›+›+Ÿ~.—€*˜{*Ю“[™{$Žkn Žn ŽpŽn“p’lušpЁw  s ~Є —wжСьуШъуЪътХэсЩытЧытЧытЧытЧытЧытЧытЧытЧщсЪътХьтЪцпФюцЩпЯЊЏ›ZЮЗiвЙqвКrеМvеОzзП}жР~иТкФƒмХ‡нЦˆмЧ‰оЩŒпЪоЪпЫ‘пЫ‘рЬ“рЬ“сЭ”сЭ”тЮ•сЭ”сЭ”сЭ”нЮрЭ”пЫ’оШŽсЬмЩŒЩИЭНˆэтЦэхШытЧысЩысЩысЩытЧытЧытЧытЧытЧытЧытЧытЧытЧытЧъмЪѕшШЅ—KЖœ0ФŸ7М™7Г”-Б)А’)ЊŠ!Љ‰ЊˆЅƒЅЄ€Ё}œ{ ЦIЅz;„m)v*š(™+ž~+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+›+œ~-œ€+š.g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+ž~+—)™|+ХŠRЄ†/‹hŠk‹koŒmo“u’px—t›| žvІ{žxСЉsчмРштХэхЧыоШъсЦъсЦъсЦъсЦъсЦъсЦъсЦъсЦьпЩысУьтЪщрХъуЪщнСМ­oТЉ_ЯЖnбИpгКtеМvдНyдО|жРзС€йУ‚кУ…мХ‡лЦˆмЧŠнШ‹мЩŒнЩнЩоЪоЪпЫ‘пЫ‘пЫ‘оЪоЪнЩрЩ‘рЧмФˆоЪ‰гС„ТВ}угЈытЧъсЦъсЦъсЦърШърШъсЦштХъсЦъсЦъсЦъсЦъсЦъсЦъсЦъсЦьуШърТžPЋ5К•9Г‘7Б‘0Е’1Ќ1ЇŠ(Јˆ$Ј†Ј„І‚Ÿ{ž|›z Ю—Tœr1†p)v*›'˜)}*œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~-›*™~-g^=џџџџ§ўћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+ ~+—)š},П„L­Œ6‹f ˆi‰iŽiŒio”uЄ‚(Ќ‡+Ѕƒ%Ÿ„" Ѕ€ •u Є‘MьцНщцРщпСьоЬщрХщрХщрХщрХщрХщрХщрХщрХынЧьуТъоЦщсФулФятЬлЭ“ЛЂXЮЕkЯЖnбЙqгКtвЛwдМzдО|еП~зС€иТкУ…лФ†кХ‡лЦ‰мЧŠлШ‹лЧмШŽмШŽнЩнЩнЩмШŽмШŽпЩлТŠпЧнЦˆйЦƒЬК}РБ€єфПшоЦчоУщсФырХьрШщпЧшпФчсФщрХщрХщрХщрХщрХщрХщрХщрХщсФьпЩэмБШЎhАFИSУЉ]ЪЉdЪЉcЬЊ^Х K­…%Ѕ~Љƒž}œ}šy г›Z—m*ˆr*v*›‚&™}(}*œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+œ~+›},›*™~-f]<џџџџўџћўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџš~)š~)š~)š~)š~)š~)š~)š~)œ|)•'—~(Б„;ФP†d‡f ‰hˆk‹j›yЎ˜FЋ™LД›QИœEКšOТœTƘIЃ’Až•R№цОщмЦьоЫырХътФътФщсУшрТщоТщоТъпУырФчпСытЧщоШьоЫьоЧюуУьтКД­|ПЇ[аЖpЯГsаДtзНwвЙqжМvкО~жП{иС}иТ€иТ€зУ‚йХ„иЦ‡зХ†кЧŠйЦ‰йХ‹йЧŒйЧŠйШ‰зЪ†зЫ…дШ‚зХ„рХŒмП†мЦ…БЄ`фкЊърШщоУъпФырХщсФщсФщсФътФътФъуТшрУщнХьсЦьуТчрПъсЦчоЪхоЪыфЩёчЯјъитжКСГКЄbЪЊhХЉhСЊ\ФЈ[ǘCŸ~Ј‚Ђy zЉyЮЃ`‹i'‘u ˜{*”z.˜)€%š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)š~)~)™}(˜€(f[@џџќџќџћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™}(™}(™}(™}(™}(™}(™}(™}(œ|)”~&š+Ѕ{0Яš[ˆe`‡f‚bŠjЎŒ9ЖŸQЏ›MБ—JИŸIЗŸWЕžPЕ \ХДютРєщг№чгыфЫчсФхнРцоСшрУщсФщсФщсФъпУщоТъфСчпСшнТщнХънУырТ№фТлаЊВŸNТ­\ЯИhвЛmЮЕkеЛxбИxаКyзЛzйН|кО~йО~кОкСƒмТ†мТ†кФ‚лХƒмЦ…нЦˆмХ‡лФ†кФƒкФƒкХ‡йС…иПйУ|СЏnЭНŽятТцлПщоТъпУъпУъпУщоТцоСцоСцоСшрТчоУцлХшоЦшрУчсФыфЫьхвяыияыгыцб№щкьцгђьЩмЯ›ГЁdХЋhУЌ`ФЊ^ОžKЂ€І€ЁyŸz Ў~Т–VŠj(’v!˜|(•{.˜~*œ~%™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(™}(~)™}(—'f[@џџќџќџћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™|'™|'™|'™|'™|'™|'™|'™|'œ|)•}%›*v(вЁ]h_„e‡dˆgЏE­–KЕžPНŸPЖЁOЈ™[ЈŸ[наЂєцаїысшсвэыгяывящвѓыдячащтЩчнХфкТфлРцнТшпФчсОцнМысУъпУьрФщнСчлПэпТрЬ“Ћ˜UЧБcЮИfЭЖhвКrЫИoаРtеМtзОvиПwзОxиПyиТ{йТ~йТ~йУиТзР‚йПƒкП†кП‡кП‡йО…лМ…мРƒиТzЧИoОЏwянОъкУщоТшоРщпСщпСщоТщоТщоУчоУшпФшнСчнХырЬытЮыхЮюшбэшг№щияыгэшг№ыжчфеьшнѓьляцРВЉjХЌfХ­eТЉaСЃR €Ђ} Ÿy œy Л‰7А…Fn)“x!˜|%˜}-—})›}&™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'œ}(™}(—'f[@џџќџ§џћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™|'™|'™|'™|'™|'™|'™|'™|'™{(—|%˜}&žy)՘Oœq †aƒd‡b…eГ•NАšSЙŸRЛPЌ™PИЎыфНѓщбёшлщуж№эиъщЯ№щеяхл№цд№цдёшдёшдячаыфЫщпЧхмСщоТшнСщпСхлНчнПшнПхйНьпХ№мНЬЙŒДŸbЧЎdаЖiдКnЪВfгМpЮИpаКrвМtбОuвОwгПxбПxбПxбТyгСzдТ{дТ{жС}жС}жС}зТ~оЛƒлТzТВfГЅjшиГынРхйНщоУшоРшоРчнПчмРчмСцмФшоЦщпЧюфЬяфЮёшд№щж№ъз№ъзьцгэце№щађъгђъгючгђщпьовшиГЗЋeФЎgУЌhСЈbТЄS| | Ÿz šv Щ•Ožu6Žp)•z#˜}#—})–{*š{&™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'›|'˜|'—'eZ?џџќџ§џћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™|'™|'™|'™|'™|'™|'™|'™|'™{(˜|%—{$œ|)А‰;Ж‰@„\‚dŠg„fЌEЕŸXЕœRЙšUД _№чТёцияциючжюъвъчЫьчЮѓщзѓхйячжячжючдючдёшдёщвёщв№щаютаюуЭщпЧцоСцоРщпСшнСцлПцнМэрКЫК‰Ќ–UХЋ_гЕfиИoгБoаЖtбЗuвИvгЙwдКxгКzдЛ{еМ|вМ{дО}жО|еН{гМxгМxзНzйРzжЛxС­fСВtхз­цкОцоРчрПцмОцлПчмРчоУщрХысЩюуЭёцаѓшвѕъжёшд№щжючжэцеючж№щж№щеючдіькьуЯёъжёхйјчкбН”НЌcУАgСЋjУЉfНŸL›zŸ{ žy tЯœ^“n*s&–{$›~#˜|'—z)›|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'™|'š{&—{&–~&eZ?џџќџ§џћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™}&™}&™}&™}&™}&™}&™}&™}&™})š{&™~$—{&Ђ€-Эš[…Zc†d…gЁƒ6ИЂ[ЖŸ[М `­˜[нЭЈђцк№щжьцЯ№ывєэйѓщз№хбєщгяшз№шз№щж№щж№щжяшдяшд№чгђшзђшзюхбђывэцЫъфЧъфЧфоСтпРриК№уНкЩ–Љ–RЛЅWЮДgвБkвЗmвЗmвЗmгИnдЙoеКpжЛqиНsзИyжИwжЙvзМyйПyиОxгЙsЮГpНЎiФГ€чзГшоРчсФумУпиНыфУяхЭёчЯ№щаёщвёщвёшдёшдђщеёчжяшеющдюшеыфгячжѕэж№шЫэчдючгђьеёыдђшжєцЯНЊ}ЧБpХВiХЌnШ­jØ>›{ {v Љ{#Ц”Xo$Žv$˜{&›~#—{&–y(š|%™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&™}&š{&—{&–~&eZ?џџќџ§џћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|(š{&›}$”|$›|'Ы–]—lc„b‹jœ{,ЙЃ\БŸ^ЛЃgИЂ`ФЏ|№цдёщвђэдьхб№шзячжђыиющаящжящжящжюшеяшеяшеяшеяше№ще№щжэцгђыиючгяшд№ъгящвючдђщеюфЬэуСчнЎУЗ}ЗЇeЛЈdШВjЩГkЬДlЯЗoЯЗoЯЗoЯИmаЙnбКnаМoаМoЮМoЫЛoЦДmОЎiЙЈeеЪžъпС№хЯъуЪъхЬэцвёъжёъбючгяшд№щеёъж№ще№щеяшдющдђчйђыияъеюъзэцеђщеёцЪиЬЈеЧЃбХовЊкбЌукЕлбЂНЌsЫВtЩГkЧ­qЩЏiЅ‰+|Ё{s О?Б‚Dsy#—y&›}$–z%–y(™{"˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%˜|%™z%–z%–~&eZ?џџќџ§џћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ—{$—{$—{$—{$—{$—{$—{$—{$”z&œz&˜z!–~$˜z#П†RБ„-cƒa…akКЄ]БЂcВŸbСЋcЗ bтйХюшбђьеяыгящж№щиэце№щиющдяъеяъеящжящжяше№щж№шзющаяыгющд№щиьхжёъляшзяшзёчжёъжэшгёыиђъйѓцащкЙиЫбРгТйЧ’нЫ–оЬ—мЪ•кШ“йЧ’мЪ•пЬ™нЬ™еХ–аР–еХЁцжЙіхЫѓшкђще№щеяшзящжюъвёъзяфм№шз№шз№шзюшеюшеюшеящж№ыжяци№ъзъшаэъе№щжєщгьпПСГ‰ЩВzЭИzХВuФБ~МЎyОВpХГlЮВqЪДmШ­tШЏg™~›z  zžq вœUžr2u‘|!—y&›}$–z%—z)™|!—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$—{$™z%–z%•}%eZ?џџќџ§џћџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#—y ™~$“w"–z&šz' {)ЭЃP‡X{b†e…eЖœZДЂeЙІbПЃmМІdЫН“ютРхкКйбЉвЪ•ЫС‹ТЕ‰эрРюъзющк№щкячжђызящвяъеьшжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжёцЪуйЛгШЈЬРœЮТšвФšеХšдХ—ЫФ™ЬФœаШЃлгЕчрХяшдёъйяшйящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжюъб№ъгђыи№чйёчжѕшЮеУšЯЗƒбН„ЪЙzЫЛyЫЙxЯЙЪБyЫГwЩЕtЬВpСВmЛžSЄz›v˜t ЇzЭ”\r“u"–y$—z%—{$—{$–{!•z ˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#—{$˜z#˜z#d\?§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z!•y"—{$–y$•u"žy'ӘI—i`‚ba †:ЛЄlЛЈkМЇiСЊlЕЁhОЌwЕЄqЙЇrМЉlФЏrСЋwгПяъбяшдюце№щиящжющдёыиючжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжёчеѓщзіызєщгѓшЭ№фШюуХ№тХєщЭєщЮѓъЯђывѓыдёъжящжючжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжёьзяшдючдячжёъжцнМФД…гП…ЯЛ‚бНƒЯН€ЫИ{ЭИ{ЪЕwЪЖuШЖuЫДvЦГoІˆ/Ÿw šu™rХ“@А€@‘s “v!–y$–y$–z#–z#–{!•z ˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#˜z#–z#˜z#˜z#d\?§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ—y"—y"—y"—y"—y"—y"—y"—y"˜z#’v˜}#•z •w x&Г‰<И‹B\‚b|c‹qСІmЛЉtИЋgНЉoЧАlФЎlРЌkЦВqЩАrЭБtЪАtФЎtсиЗєыаёъзѓьнэщз№ъз№ъзячжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжюцйячк№щк№щи№шзяше№щжёъз№хз№чйёщиёщи№шзяше№щж№ъзящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжящжьхдєьльхвєэк№ъгйбЌФЙ…ЯРбН„ЯКƒЭИЯЛ‚ЬК{ЪИwЧЕtШЖwЩГyЩАh™{›t { ™nд Z”n&’u ”w"–y$–z#•y"–z#–{!•z —y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"–z#˜z#—y"c[>§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ—y"—y"—y"—y"—y"—y"—y"—y"—x#–x!–{!•z™{$›v$Ёy.ЫŸX‹^ b~edЖ™VМЈxКБnОЌqСЌoСАqТВpТАsЧАxЧАxЩЕ{ФЕvСДŽђчЩёшдэшйъчияыйюцеєъйящжящжящжящжящжящжящжящж№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъзёыиящжюшеюшеэщжюъзюъзэщжюшл№шл№шл№щкяшз№шз№щж№щж№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъзёълячж№шз№щжяшдющЪгЪžФЖдТ…аМƒаИ„аЛ„ЩЗzЭМ}ЬК}ЪЖ}ЭД|В•@šxšvšsД‚(СMq"•v!—x#˜z#—y"—y"—y"—y —y —y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"—y"•y"—y"—y"c[>§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ—y —y —y —y —y —y —y —y –w"˜z#–x–y—y –t!—p%Й‘IВ€8~`~c|_™|+НЈqПГyМЎsТ­zУВzРВwОЎsШГ|ШГ|ФЖ{ПЖvУЖѓшЪђщеэшйъчияыйячжѕык№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъзяшдёъжѓьиѓьиђэи№ъзюъзюъзюъзэщжэщжящжёъйёъйђъйёщи№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъзьшжѕюлэцгёщиёълєэйяфШЬОšШЛ}бП„дМ†аМƒЪЙ€ЭМƒЭЙ‚ЭВЮВr˜xœwšv”kЯQžu,u!–x!—y"—y"–x!–x!—y"—y –x—y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y —y ”x!–x!—y"c[>§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ–x–x–x–x–x–x–x–x–x!–x!•w—z–všx$˜v#y+ЮW…b€_€`ƒg З[ХА}НВvФЎzТЎwХВyЦГvЫЖyЪЕxУГxРЕ{хмЛјядђыиѓьнэщз№ъзёыиёщи№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъзѓщиѓщиѓщиёщи№чй№чйёшкѓъмэьвюьдяэеёьз№ъз№щи№щиёъл№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъз№ъзьше№ыжѕюлђъйячкђънюфвьоШЩОŠЮН…вМ‚ЯЛ‚ЯНˆЧЗ‚ЬЗ€зКГ’B˜ušu’oБ„)У’Nou•w –x!–x!•w •w –x!–x!•w –x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x“w –x!–x!c[>§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ–x–x–x–x–x–x–x–x•w”v•w™y —w™{"˜z#’tНFЇz1ƒ]b~a}1ФЊtРД~ЧД{УБ|ЦДШДzЩДvШДzЧЕ†мЬЈђэдёъж№шзёъй№ъз№ыжѓэк№щиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёълёълёшкёшкђщлђщлёшк№чй№ыжёьзёыи№ъз№ъзящж№ъзёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыияыиђэиючгёъзёьнэшйђъйѕъдтжВЫЛŒЯЛаМƒЭМ‰ШЗ„гОЬБg—t œu ”r–p аœPЁw2‘x"˜y•w–x–x•w•w–x!–x!•w –x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x–x“w •w –x!c[>§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ•w•w•w•w•w•w•w•w–y•w–u–u˜w!”v’u”zЁy'гŸcŠa }b}`}YНŸfОАСЕ{ТЕТД„ФДЧЖ}ЧЖƒШЙ™єхеяыиющкёъл№шзєэйёыдёьзюъиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиюъзяыи№эиђэиёьзёьзѓьиѓьиѓънђщлђщлёщиёыиђьйђэиђэиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыиёыияыйяъеѓэжђызюъзяыиёэеѕюгщмЦЧЖжТ‰дР‡ЫК‰ЯО‹дП{„.žxšo“uЇЩ‘P“n$Šv˜w”v•w•w•w•w–x!•w ”v•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w•w’v•w –x!c[>§џќџ§џќўџ§џўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v’vЛ‹IДC~Yz]f‹pЬД~СДˆШИ‰ЫД‡ЬЗ„ШК€СДŽютаёыдяъеѕюкђыз№щжђыиђъйђъйѓъмёщиёыи№якяьзёщиіъоёчнѓыођьйђьйђьйђьйђьйђьйђьйђьйђьйђьйђьйђьйђьйђьйђьйђьйёъйёъйёъйёъйёъйёъйёъйёъйђьйђьйђьйђьйђьйђьйђьйђьйящжђьйѓэкѓьл№шлѓъмђызёэбьсЦѓьбяыгюымьърыцнєэоэцваР•ЭПŠеОŒмТŒаЛ‡бР‡ЛЁU–r“w”o˜k д ^Ѓw7•y’u˜t ”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v–v™x”xcYAћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”vš{•nдЅafƒd{`|a ЄŒDЩЖ‰ЪИ‰ЭМ‹ЭМ‹ЩЙŠЧЛ‹щрОіэрѓэрющкѓьлѕямѕ№лєюз№ывєяжїьоёъйяыиђюлѓьйѕыкєьлёыиђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкёэляыиђьйёъйѓъмћёпђыаеЮ­ЭП›ЮФЂхнПєэдёъзћёпєъввШЊЮТŒиУ–вС‰гТ—вТЭДv”ušr’t–oКˆ<ЙŠ@—r s˜|™u!”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v–v™x”xcYAћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v•v•vБŠ<У–L[~az_eНЇmЭЙŠЦКŠЧКŒЭЛ’ЩЛŠХМьпЯђытящоѓьнѓьияыЯлжЗЮШЅцрЛїъкіюн№ькёэкѓюйђызїёкђюжђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкђыкѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлђыкђыкђыкђыкђыкђыкђыкђык№ымёэляыи№ъзї№нысЩнгБЬТšиШšе֘бУ™ЮТžцйЙєчЧнЯЋЭП•бЦлШ•дТ™ЧОŒЯО‹›#˜qšm“mŸpиЅf”o“xt•x™v ”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v”v–v˜w“wcYAћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v—v‘x•sС“F­~-{X€a`‡oбЛ‡ЩЙ”ЦКаР–ЩИЮС•ЩТ›эхдѓьйѕэжсйМЮХЃЫРšШП”ЭТ–теЛячађюляыиѓэкѓьиѕюкєякѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьл№ымђюмёэкѓэкїюкзЬАЬТšиЬœмЫšлЪ™лЭгӘбТ›еФаР•кЫšеЩ™аС“иШžзЦ•Њ—<’qšo˜n™l ТIЕŠA•t’y’z‘q–x“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v“v•u˜w“wbX@ћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u“t”x!oЈ{*д ]Œe}\†bza˜6гР•ЮМЮН–бС—ЬО”ЭЦвЧЇхлЙлЯЋЬП™аСšеХšж֘зЧ™ЬС›йбГёьзяэлђюлѕюлђыкёыоєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмєэмѓьлѓьлѓьлѓьлѓьлѓьлѓьлѓьлєэмєэмєэмєэмєэмєэмєэмєэмєэо№ымѓянѕюняшдлаДжЪ мЯ›оЮŸеЧ—иЪšлЮ зЩŸиШžиЩ›дЦ•гЧŸгЧŸиФ”Л›RŽo™w’m”lД€3ПGm“uu’x‘s—z’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u’u”t—v’vbX@ћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u“vr”tv!В‚@Ф›R‚_ƒ[}`~fЊ‘QдЛ™бПšЯԘбԘвФ“ЯУ™аҘЬП“зЧœзЦ›дС–лШкФšаЦ—аЧЅ№ыжѓ№сёэлѓьлѕюпђытђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђюмђэођэођэођэођэођэођэођэођюмђюмђюмђюмђюмђюмђюмђюмѕюпєэмђюмёьнєэкщоУжЪЂлЭœйЫЁобЅзЪœжЩкЫЄжЧ жЩиЬœзШšйЩ›М _“qЁt“qjЂxв ^ |$•wu•w”s”w’v”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”t–u’vbX@ћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u‘v“t—v‘q™t$ЙBБ‰7[ }`~_|]НЄfиЪšЪӘЯУ›зФŸбУ™иЪ гХ›дФšзЧзЧкШŸлЩ лЮ мбБєэмђюуёьнѓэкї№пѓэтѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓянѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓянѓянѓянѓянѓянѓянѓянѓянѕэмї№пёьняьоіёт№шбвЦЄмЯЃжЩЃмЮЄкЭЁкЬЂйЪЃиШЃйЫЁеШšсб–ОЄbr ’m“n’j ˜pЮMАˆ=q‹p’u”r–r•xr”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u”u“s–u‘uaW?ћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“ts–w˜v‘s“w—mР“J™v&{^„\ˆb{dЗ­qЭЧЂгЦІйСЅдЧЁбФžдЧЁеШЂгЧŸиЩЂйЫЁзЩŸиШžщмТїятющрѓ№сєякїђнёьнѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпѓюпіямєэмёюпђюуђьсћёпмбГкЮІпЯЊлЬЅнЭЂоЮЄмЫЄнЬЅнЭЃкЫНЈjo —q•r‡hŽg ТFНŒ>qr“zq™v™vpv“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“s–u‘uaW?ћџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t‘s‘tŽtŽr“t•pЅ|-дІY’m{Z€`„aeЦВ{бЧЅаШЃйХЂжШЄгЬЅЯШЁгЧŸкЫЄжЩЃдЫІвХЋіыеѓэкђярёяфђьсљ№уїьоѕ№лъхаєэйњ№оїяољёфющрёюцєярєярѕёпє№оѓюпѕятѓэтєэфєъуї№чёыоєёт№юмѕёпёэлї№сёюпїёфѕьоїьжцмОкбАпгЛљьмїюхіэпѕюлёянюётюяпчрЧиЧІпЫВлЮЂлаœкбЅзЮ­еЩЅфвЧЋn“n”o’m•ngЖ‹<ЖŒA•s“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t“t•s“u”s\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s‘qptt“t’p—oЎƒ4еža•m|^}az\€f ЦГvиЩЈвЫЊвЧЇйЪЉиЪІиаЈеЭЅзЪЄлШЅгШ­љёкіђр№юу№ях№ьсѓэрљ№тскПдЭВиЯДрзМщсЪї№нѕ№сяэтєярєярѓюпѓюпѕ№сєюсєюсіюсїятєьпѕят№эођярѕ№сђэоѓюпѕєр№щикбНйЮГйЯ­лв­йЯБрдМђьпѕяті№хёьуѕёцєэмхкОпвЌжЮІтаБувЋзЬІгЭЈреЉХЌnn“n—qjiЏ7НH˜t“q’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s•s“u”s\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s–tq“t“u“u“t’p•pЗ€7д™aˆby`x]€^„j РІwбЬ­еЬЇзЪЄлЯЋеЪЌбЦЊнбЏпЯЅоиЛєюзѕђу№юфэыуієщє№отнШйбЌйаЋкбЌкаЎлбГцпЦђюлђярѓ№сѕятєюуі№х§ѕшѕюнїђнѕёйњѓпёъзќѕцєюсѕёцѕятѕ№сѕ№сєёмёьзнгЛмгВмдЌпи­мг­йаЏйиОяюкѕёцєюуяхгтжКовЎйбЉмдЌйЯЇнЫДмЭ­уеЅЗЄaŠn ”m•p‹hiЌ~0НŽJ›t&“p‘r’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s’s”r’t”s\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r•s‘o”s‘sr“u’s‘r™qЖ…;Э”`‹fy^c{W |bА›dтдЃлд­аЪ­йЭЕйЬВзЪЊлв­жЯЎскПящжѕђфђюуіётъцЮдаДнвЌреЏсе­ог­мбБумСљѓрѕђуѕђфєёуѕюхіяцїятскЧрмРмйКнзКлдЛэчдєюсјёшѓюхі№уіётї№п№щекбЖржДуйБсзЏпзЏоеАкеЎроПььдхрЧмбБрдЌквЊлиВнбЇржИзЯЊуаЊА‘LokŽkŽg‘jЋ}/ЯŸ]Є|)•up’t‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r“q’t”s\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r’p’p”s’r’r‘srsqŽpЎˆ6вœ_“i~Zx\}b€`ЇJоЮЄзЯВивЕзаЏкаВлаДкв­иЯЎеЮЕхлЩєэкёщвлгЕйаЎсеГхзГтдАсеБпдЖскСљђсёэтєёуѓяфіяцћђшєыннеОмзИнзДнжЕожЙумШљђуїёцѓюхє№хі№уњђхёщикаИтзЗфиЖузГтйДукЕтдАоеДебДозЖтзБтжЎтйИвЮЕсеБфиАкЧšЁ‰5Šg˜k‘kŒihЎ5ЛFЈ€-“qŽq‘tŒm‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r“q‘s“r\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r’s”s“r“r”s‘sqs‘r†ryБ†/лœjšly_ya^}]v.зЧ’кдЏзгЖмдЗрдВодВреЕогЗмвКнгЛпдИлаАуйЗовЖреЗтеЕтзЗогЗнеОљёфіёшѓёцє№хїёцњѓфыфблдЙнжЕсйДуиИуйЛмеМђыкѕятіђчіђчіђчѓьу№щисзПфкМсжИсжИсжИпжЕъзМсвИтзМпеЗсжЖуиИпвИфзСциЎЪВ|qŽj’mjddГˆ7ЛŽEžw(ps‘r”u’u‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r‘r’pr“r\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’qŽrpo’p’p’qqq”r‹r‡p ”pЌ|.йЃbs&z[|]_z]|aУАwужАоеДоиЕпдИреЙриЛпжЛквЕхкОфкМнгЕпиПриЛсиЗтйИриЛпзРњѓфєяцѕѓщіђчјѓфїёофмХсйМукЙхлЙуиКуиМрзМьхбљѕуњїщіёшєяцїђщ№ъзпиНуйЛузЛшлСфйНтиКтеЛцйПузЛреКоеКфйЙьлДхбЂЋ’L‡i ‘i‘in‚dŽh ОˆAИŽA“p”rm•xp‘o’t’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q‘or“r\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q‹rq’q”q‘n“p•sp‘m–p—t‹o“tЄw-ХŽKДƒ7x]|`yZƒbz\›„@вЧЁздХожПпзРнжНрйОпйМпиНпжЛфлРмзОпиНулНтмЙриКниПљѕуіђчѓ№шіђчїђуєякнжЛфмПцмОхкМъмРцкОукПойРѓ№лїєхіёшїёъђюущцбмйКфнМфйНчмСтзЛумЛупМтйЗшнНхкОркНулГУГx‹t(l’jfkfq ӘIН‰C“qon‘s‹m‘tr ”o’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q’q‘or’q\X?џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q“s’r‘p“rŽl—uД’9ХQf|\~a~^]bПЄZдзОнкЛфйЙшкОцкТрйОсйЛфлКфйУтиРцлНцлЛфкМскПунЪцсвъфзячкєэмщтЮозОумСшрТтлКъйОымТциСщмЦытЮъуЯщфЯрнШфжУцкТцлРцлПчкРфиРтиРфнТциХуйСснСцпОЯТ–ž…?Šcœm…h‰kgdЄs%ЮWБŠ<Žn‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘pr’p]Y=џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘qpppŽm‘p‘oŽl“qЏˆ:ЯŸ_Ѓr,~Y{]{ay\_‹mТ­zфнФнкХлеОылЪълЫфкЩркУфлЧфкШуйШфкЩумШснФпмРуоНфнМцоРшнТщнХщкЧщзЦюлЬфрУснСхсХсмУумУчрХтлРхпТррТупУчлУцнТцрУтпУрлЦриЧснФщпЧиЦЎ•KŽpŠh‹h†d‰j‡aŽaЛŠ@Т”FЉ€+“oo‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘q‘pr’p\X<џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџppppppppppppppppppppppppoo’roo“r‘oŒj“nŸw$Т‘KС”Pjw[}[^ƒ^ƒaˆjСЈ|ылЪолЭонШсоТъмЪщоЪчмШчмЦщпЧшпФщоТюуХфпЪхрЫфнЩумШцрЩшрЩхнЦчпШфмХътЫхнЦцоЧцпЦчрХъчШурСьоШфнЪроЬпоЪупУцсТцуФууХлЪЃЅHŒi“fcˆh„n{g‰`Іx*ЮŸ[Е‡@’k”smnpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp‘pŽq’p\X<џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpppppppppppppppppppppppp‘qo‘q‘qŽmŽm‘p’q’l”rŒo Ў‹5Юž\Д…;„_Z ~^€^‚b|a„nЏŸ\лвЇфрФшнЧътЫцрЩупЧчуЫчрЬчмШщлШснЪтоЫцтЯхтЭфпЪчуЫчуЫтоЦшфЫтмХцпЫърЮърЯънЭчкЪюпЯчфШщуЦщрХчнЫьрдъкУЩД€ž†:gŠg„d†fg‰_†`pЧ’OСFЃ{(‘n’rm“smppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppoŽq‘o\X<џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpppppppppppppppppppppppp‘qoŽnp‘qŽmŽmo”q‘t Šm ‘p™rМ‹EЭœ^ z(zay^z\u\{bv]z]œ}.ДБ…вЯЉцуЧфуЯтпафпачсЮъфЭытЮщрЬцпЫшсЭхоЪфнЩшсЭъуЯщсЪшрЩьхбчрЬхрЫщчЯуфЪстШхмШътбщоШгТ—Џ”J’qˆeˆd†j„fˆf‡fcmЛ‡;уhД;•ip r Žsnoo ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppnp‘o[W;џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџoooooooooooooooooooooooom’roo‘q‘qpp‰o l–qm Žmn™sМŒDд™hЅ{.}ew^~\\€`{aƒ]†d’t%Ћ–XЭР’пкЛутЭтфбчоЪ№цдщтЯчпЮьхдыфечрбчтгщсаьфгщрвъпбьпбюсбымЬкЬКНЏ~š‡D„f…dŠh…e‚bˆe„cƒc€_•lОŠDв˜]Д‡=r”n”q’r‹mpŠkŽn •uoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonŒo n[W;џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџoooooooooooooooooooooooom’rpmmŒl Žnm‹mŒm ’m‘lŒo s ‘q”k˜uК…BмœbН‡@‹izatZ^€^}\_ƒc€`}_m!Є„;Ѓ˜\Й­sПГ}ЦИˆзЩŸоЮЊкЫЋиШЋгаЄЙГ„ЙЏyДЅfЊ•Jš+e‚dƒ`„d‡eˆc‰`†`€c{h„aЂs!ЪŽRб•_Б9r‡qˆqŽqn kmŽm‘q”tŠiooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooŽmŒo n[W;џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnpoŒl ooŽnpml ‘r‰n ‹n ’phŽn‹r Žlo‘o­€7Э—XߘUЎ€2†a u]x]}^]^_€a}a‚]ƒa_`€b}_}b~cŠb†^ˆbˆb‚_ƒ`‚bƒdˆa…bbzay`‚`žoО†9иeЦ“MЄ~&q Žp oŽll‹oŠnŒmoŽlŽlŽlnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽmŒo n[W;џџџџўџџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŒmŒmŽnmj˜sГŠ;ЫЁVб–XМ…@Ёp"‹` €\~]|_|^^^€_€_`‚a``ƒ`‚_‚^ƒ_„_„_ƒ^‚]†^‰`’fЄv)РKа^Ц“UБ}AŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnmŒo Žl[W;џџџџ§џџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŒnŠm n p n Œj h‘iœt­‚3У•NЮ_Ц—ZЗŠGЇ}2žv$‡jd z]wZx[z]z]y\z^{_{^|_€cŠmš}"Ѕˆ-НŽJШ™UЬŸVО’EЈ*™r’n ‘nŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnŽnmŒo Žl[W;џџџџ§џџџўќўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm ‹l ‹mo p p ‘mkŒmŠk‹k mšuЉ~-З‡?ОŒJв–ZкžbрЄhнЁeг—[ЬTЬTЯ“Wб”Vж™[оЁcсЄfмŸ_г–VШ‹KС„DЄ~&›ujhj’o’o ‘o mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm‹n Žl[W;џџџџ§џџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџm m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m mŽn n Œn ŒlŒl Žn n ‰o ‹o ‹pŽq p ‘o ’m ‘l nŒkŠi Žm–uœ{œ{šyšx•snŒkmŽnm ‹k Žn m Žm n n l l Žm m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m Žl‹n k [W;џџџџ§џџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŒl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl ŒkŒkŒl l Žm n Žm Œk ‹k Œl kŒiŠhŠj ŒoŽr‘k ’l“m“m’l‘k ‘k ‘k ’j’j’j‘j‘j‘k ’l’l ŽmŒl Šj Šj Œm n Œm ‹l Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Žl‹n k [W;џџџџ§џџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŒl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl jkŒj ‹i ‹i Œj l l ŽiŽi Œk Žm oŽnŠkˆgŒm Œm ‹l ‹l ‹l Œm Œm ‹l ‹k Œl mŒl ‹k ‹k ‹k Œl Šj Œl m Œl Œl Œl ŒkŒjŒl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl Œl k Šm k [W;џџџџ§џџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k Œj k mmk ‹k Œl m ŒmnŽn m ‹k‹j Œj k ‰l Šm ‹n ‹n ‹n Šm ‰l ‰l ‰l ‰l ˆk‰l ‹n Œo ‹n ‰l Šh‹j mŒl ‹l ‹l Œl Žn ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k k Šm k ZV:џџџџ§џџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k m ‹kŠjŒk l ‹l ŠkŠk‰l ‹k ‹k Œj Žk Žk k k Žj k k Žj Žj Žj Žj Žj ŒlŒlŒl Œl Œk ‹j ‹i ‹i Žl‹j ŠjŒlŒl‹k‹i Œj ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k ‹k Œj Šm Œj ZV:џџџџ§џџџў§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmysql-connector-c++-1.1.7/win/Bitmaps/exclamic.ico000644 015771 000012 00000001376 12645244437 022450 0ustar00pb2userwheel000000 000000  ш( @€РРР€€€€€џџ33133233333333333333$DDDDDDDDDDD@12DDDDDDDDDDDDD2DDDDDD@DDDDDDC2DDDDDD34DDDDDC2DDDDD@30DDDDD3$DDDDD34DDDDD13$DDDDD@DDDDD@1332DDDDDDDDDDDC332DDDDDCDDDDD333$DDDDDDDD1333$DDDD#$DDD@133332DDDD34DDDC33332DDD@30DDD33333$DDB32DDD133333$DDC33DD@13333332DDC33DDC3333332DDC33DD3333333$DC33DD13333333$DC33D@1333333332D@30DC333333332DDDDD333333333$DDDD1333333333$DDD@133333333332DDDC33333333332DDD33333333333$DD133333333333$D@13333333333332D3333333333333"#33333333333333333333333јрР€€€€РРрр№№јјќќ?ў?ўџџџџ€џџ€џџРџџРџџрџџрџџ№џџ№џџјџџќџџџџџmysql-connector-c++-1.1.7/win/Bitmaps/info.ico000644 015771 000012 00000002066 12645244437 021613 0ustar00pb2userwheel000000 000000  ш&(( @€€€€€€€€€€€€€РРРџџџџџџџџџџџџpwpppџpџpwwџwwwpџwwwџџџ€wwpџџџџџјwwџџџџџџџјwpџџџџџџџџџ№wwџџџџџџџџџџџwpџџџќЬЬЬЬџџџ№wpџџџџќЬЬџџџџјwџџџџџќЬЬџџџџџwxџџџџџќЬЬџџџџџ€wџџџџџќЬЬџџџџџ№wџџџџџќЬЬџџџџџ№wџџџџџќЬЬџџџџџ№wџџџџџќЬЬџџџџџ№wџџџџќЬЬЬџџџџџ№pxџџџџџџџџџџџџџ€pџџџџџџџџџџџџџџџџџŒЬШџџџџјџџџџЬЬЬџџџџ№џџџџЬЬЬџџџџџџџŒЬШџџџ№џџџџџџџјpwџџџџџјwwxџџџ‡wwwwpџџчџџџЧџџџ‡џџџџџўџџјџџРџџ?ўќј№рР€€€€Рр№?јќџџџџрџ( Р€€€€€€€€€€€€РРРџџџџџџџџџџџџџџpџџwxџџџјpџџџџџ№pџџЬЬџ№wџџќЯџџџџќЯџџџџЬЯџџџџџџџџџџќЯџ№џјџ№wџџїpwwwpџўј№рР€€€€Р№mysql-connector-c++-1.1.7/win/CMakeLists.txt000644 015771 000012 00000013662 12645244437 021331 0ustar00pb2userwheel000000 000000 # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # # The MySQL Connector/C++ is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FLOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # PROJECT(MSI) CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) # This is Windows only, so just set one of two possible SET(CONNECTOR_PLATFORM "Intel") SET(CONNECTOR_PLATFORM_SUFFIX "win32") SET(CONNECTOR_DEFAULT_DEST "ProgramFilesFolder") IF(CMAKE_SIZEOF_VOID_P MATCHES 8) SET(CONNECTOR_PLATFORM "x64") SET(CONNECTOR_PLATFORM_SUFFIX "winx64") SET(CONNECTOR_DEFAULT_DEST "ProgramFiles64Folder") ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8) INCLUDE(${CMAKE_BINARY_DIR}/config.cmake) SET(CONNECTOR_PRODUCT_DEST "MySQL Connector C++ ${CONNECTOR_PRODUCT_VERSION}") # Generate GUID EXECUTE_PROCESS(COMMAND uuidgen OUTPUT_VARIABLE CONNECTOR_PKG_ID1) STRING(STRIP ${CONNECTOR_PKG_ID1} CONNECTOR_PKG_ID1) EXECUTE_PROCESS(COMMAND uuidgen OUTPUT_VARIABLE CONNECTOR_PKG_ID2) STRING(STRIP ${CONNECTOR_PKG_ID2} CONNECTOR_PKG_ID2) # check if wix is in current path # FIND_PATH(CONNECTOR_WIX_DIR candle.exe $ENV{CONNECTOR_WIX_DIR} $ENV{WIX_DIR} $ENV{WIX_DIR}/bin $ENV{ProgramFiles}/wix/bin $ENV{ProgramFiles}/Windows Installer */bin) IF(NOT CONNECTOR_WIX_DIR) MESSAGE(ERROR "Wix not found. Please change your environment variable PATH or specify WIX_DIR") ENDIF(NOT CONNECTOR_WIX_DIR) IF (CONNECTOR_SIGNED) FIND_PROGRAM(HAVE_MD5SUM NAMES md5sum PATH ENV PATH) IF(NOT HAVE_MD5SUM) MESSAGE(ERROR "Can't find md5sum") ENDIF(NOT HAVE_MD5SUM) FIND_PROGRAM(HAVE_SIGNTOOL NAMES signtool PATH ENV PATH) IF(NOT HAVE_SIGNTOOL) MESSAGE(ERROR "Can't find signtool") ENDIF(NOT HAVE_SIGNTOOL) ENDIF (CONNECTOR_SIGNED) IF(NOT EXTRA_NAME_SUFFIX) SET(EXTRA_NAME_SUFFIX "") ENDIF(NOT EXTRA_NAME_SUFFIX) SET(WIXOUT "mysql-connector-c++${EXTRA_NAME_SUFFIX}-${CONNECTOR_PRODUCT_VERSION}${CONNECTOR_PRODUCT_LEVEL}-${CONNECTOR_PLATFORM_SUFFIX}") SET(ProductURN "MSQZP-100-ZZZZ") #----------------------------------------------------- IF(EXISTS "${CMAKE_SOURCE_DIR}/../LICENSE.mysql") SET(LIC_SHORT_NAME "LICENSE.txt") SET(LIC_NAME "LICENSE.mysql.txt") SET(LICENSE_FILE "${CMAKE_SOURCE_DIR}/../LICENSE.mysql") SET(LICENSE_RTF "${CMAKE_BINARY_DIR}/License.rtf") ELSE() SET(LIC_SHORT_NAME "COPYING.txt") SET(LIC_NAME "COPYING.txt") SET(LICENSE_FILE "${CMAKE_SOURCE_DIR}/../COPYING") SET(LICENSE_RTF "${CMAKE_BINARY_DIR}/License.rtf") ENDIF() FILE(READ ${LICENSE_FILE} CONTENTS) STRING(REGEX REPLACE "\n" "\\\\par\n" CONTENTS "${CONTENTS}") STRING(REGEX REPLACE "\t" "\\\\tab" CONTENTS "${CONTENTS}") FILE(WRITE "${LICENSE_RTF}" "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\\viewkind4\\uc1\\pard\\lang1031\\f0\\fs15") FILE(APPEND "${LICENSE_RTF}" "${CONTENTS}") FILE(APPEND "${LICENSE_RTF}" "\n}\n") #----------------------------------------------------- CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/mysql-conncpp-msi-template.xml.in ${CMAKE_BINARY_DIR}/mysql-conncpp-msi-template.${CONNECTOR_PLATFORM}.xml @ONLY) MESSAGE(STATUS "${WIXOUT}") SET(XML1 mysql-conncpp-msi-ui.xml) SET(WIXOBJ1 ${CMAKE_BINARY_DIR}/mysql-conncpp-msi-ui.wixobj) SET(XML2 ${CMAKE_BINARY_DIR}/mysql-conncpp-msi-template.${CONNECTOR_PLATFORM}.xml) SET(WIXOBJ2 ${CMAKE_BINARY_DIR}/mysql-conncpp-msi-template.${CONNECTOR_PLATFORM}.wixobj) ADD_CUSTOM_COMMAND(OUTPUT "${WIXOBJ1}" COMMAND "${CONNECTOR_WIX_DIR}/candle" "-dBuildDir=${CMAKE_BINARY_DIR}" "-I${CMAKE_SOURCE_DIR}" -o "${WIXOBJ1}" "${XML1}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") ADD_CUSTOM_COMMAND(OUTPUT "${WIXOBJ2}" COMMAND "${CONNECTOR_WIX_DIR}/candle" "-dBuildDir=${CMAKE_BINARY_DIR}" "-I${CMAKE_SOURCE_DIR}" -o "${WIXOBJ2}" "${XML2}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") ADD_CUSTOM_COMMAND(OUTPUT "${CMAKE_BINARY_DIR}/${WIXOUT}.msi" COMMAND "${CONNECTOR_WIX_DIR}/light" -o "${CMAKE_BINARY_DIR}/${WIXOUT}.msi" "${WIXOBJ1}" "${WIXOBJ2}" "${CONNECTOR_WIX_DIR}/WixUI.wixlib" "${CONNECTOR_WIX_DIR}/wixca.wixlib" -loc "${CONNECTOR_WIX_DIR}/WixUI_en-us.wxl" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" DEPENDS "${WIXOBJ1}" "${WIXOBJ2}") ADD_CUSTOM_TARGET(MSI ALL DEPENDS "${CMAKE_BINARY_DIR}/${WIXOUT}.msi") IF(CONNECTOR_SIGNED) ADD_CUSTOM_COMMAND(OUTPUT "${WIXOUT}.msi.md5" COMMAND signtool sign -a -d "MySQL Connector C++ ${CONECTOR_PRODUCT_VERSION}" -du "http://www.mysql.com" -t "http://timestamp.verisign.com/scripts/timestamp.dll" ${WIXOUT}.msi COMMAND md5sum ${WIXOUT}.msi > ${WIXOUT}.msi.md5) ADD_CUSTOM_TARGET(MSI_SIGNED ALL DEPENDS "${WIXOUT}.msi.md5") ENDIF(CONNECTOR_SIGNED) mysql-connector-c++-1.1.7/win/mysql-conncpp-msi-arpprops.xml000644 015771 000012 00000004326 12645244437 024545 0ustar00pb2userwheel000000 000000 mysql-connector-c++-1.1.7/win/mysql-conncpp-msi-template.xml.in000644 015771 000012 00000022077 12645244437 025122 0ustar00pb2userwheel000000 000000 NEWERPRODUCTFOUND mysql-connector-c++-1.1.7/win/mysql-conncpp-msi-ui.xml000644 015771 000012 00000016342 12645244437 023315 0ustar00pb2userwheel000000 000000 1 1 NOT Installed 1